I have the following code in C that allocate an AudioBufferList with the appropriate length.
UInt32 bufferSizeBytes = bufferSizeFrames * sizeof(Float32);
propertySize = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * mRecordSBD.mChannelsPerFrame);
mBufferList = (AudioBufferList *) malloc(propertySize);
mBufferList->mNumberBuffers = mRecordSBD.mChannelsPerFrame;
for(UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i)
{
mBufferList->mBuffers[i].mNumberChannels = 1;
mBufferList->mBuffers[i].mDataByteSize = bufferSizeBytes;
mBufferList->mBuffers[i].mData = malloc(bufferSizeBytes);
}
Most of the time, mChannelsPerFrame
is 2, so the above code creates two buffers, one for each channel. Each buffer has a reserved memory worths bufferSizeBytes
.
How can I replicate the same behaviour in Swift?
Unfortunately in Swift, a C array is treated as a tuple, so AudioBufferList.mBuffers is imported a tuple with a single AudioBuffer. C lets you just access the neighboring memory by using pointer math (or array subscript in this case) in order to create a variable length struct, Swift does not.
AudioBufferList just plain doesn't translate to Swift very well. Apple have mitigated this issue with a few helper functions and types. They created a static allocate function that returns an UnsafeMutableAudioBufferListPointer which is a special type where subscript returns the audioBuffers.
let bufferSizeBytes = MemoryLayout<Float>.size * 1234
var bufferlist = AudioBufferList.allocate(maximumBuffers: 2)
bufferlist[0] = AudioBuffer(mNumberChannels: 1,
mDataByteSize: UInt32(bufferSizeBytes),
mData: malloc(bufferSizeBytes))
bufferlist[1] = AudioBuffer(mNumberChannels: 1,
mDataByteSize: UInt32(bufferSizeBytes),
mData: malloc(bufferSizeBytes))
// Free your buffers and the pointer when you're done.
for buffer in bufferlist {
free(buffer.mData)
}
free(&bufferlist)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With