我有我自己的用C++编写的声音引擎,它有一些自定义功能。我的引擎中有解码+处理的PCM值,但我需要以某种方式通过IOS上的库播放它。它基于回调系统工作。第三方使用给定的参数请求回调,如numberOfFrames、pointerToFillData等。
我是IOS Audio的新手,我不知道是什么让我完成了这项工作。在Android上,Oboe是做这件事的lib。
我发现了一些像novocaine这样的定制库,它们与我需要的非常相似,但并不完全是这样。我查看了Core Audio,但在我看来Core Audio SDK已被弃用。然而,与核心音频打包的音频单元似乎是我需要的东西。
有多种方法可以做到这一点。这就是为什么我真的可以用一个例子+建议来说明为什么你的方式是更好的方式……
有没有人能用例子把我引向正确的方向?
我看到了@hotpaw2的答案,但我需要一个例子来说明为什么他的答案比其他可用选项更好。
发布于 2021-03-28 04:06:36
iOS音频队列接口(目前)不推荐使用,并且基于回调。
请参阅:https://developer.apple.com/documentation/audiotoolbox/audio_queue_services
发布于 2021-03-30 15:07:14
你绝对需要一个AVAudioEngine。
let engine = AVAudioEngine()
let player = AVAudioPlayerNode()
var scheduledFrames: AVAudioFrameCount = 0
init() throws {
engine.attach(player)
engine.prepare()
try engine.start()
}
func addBuffer(buffer: AVAudioPCMBuffer) {
// this will add the buffer to the end of the queue, read more in the docs
scheduledFrames += buffer.frameLength
player.scheduleBuffer(buffer, at: nil) {
// buffer was played here
scheduledFrames -= buffer.frameLength
if scheduledFrames < 44100 { // I used around a second here, calculate depending your format
// request new buffer
}
}
}您可以像这样创建一个AVAudioPCMBuffer:
var data: UnsafeMutablePointer<UnsafeMutablePointer<Float>>!
// fill your data
let count = 100
guard
let format = AVAudioFormat(
standardFormatWithSampleRate: 44100,
channels: 1
),
let buffer = AVAudioPCMBuffer(
pcmFormat: format,
frameCapacity: AVAudioChannelCount(count)
)
else {
// throw
return
}
for channel in 0..<Int(format.channelCount) {
memcpy(buffer.floatChannelData![channel],
data[channel],
count * MemoryLayout<Float>.size)
}如果需要,请将floatChannelData替换为int16ChannelData或int32ChannelData
https://stackoverflow.com/questions/66834610
复制相似问题