Reputation: 939
I have my own sound engine written in C++ and it has some custom abilities. I have the decoded + processed PCM values in my engine but I need to somehow play this through a library on IOS. It works based on a callback system. A 3rd party requests callbacks with given parameters such as numberOfFrames, pointerToFillData etc.
I am very new to IOS Audio and I do not know what gets this job done. On Android Oboe is the lib that does this.
I have found some custom libraries written like novocaine that is very similiar to what I need but its not exactly it. I looked at Core Audio but it seems to me that Core Audio SDK is deprecated. However, Audio Unit that was packed with Core Audio seems like the thing I need.
There are multiple ways to do this. This is why I could really use an example + suggestions on why your way is the preferable way...
Can anyone guide me in the right direction with examples?
I saw @hotpaw2 s answer but I need an example with a reason why his answer is better than other available options.
Upvotes: 4
Views: 382
Reputation: 87804
You definitely need an 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
}
}
}
you can create an AVAudioPCMBuffer
like this:
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)
}
Replace floatChannelData
to int16ChannelData
or int32ChannelData
if you need
Upvotes: 3
Reputation: 70693
The iOS Audio Queue API is (currently) non-deprecated and callback based.
See: https://developer.apple.com/documentation/audiotoolbox/audio_queue_services
Upvotes: 4