Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocate an AudioBufferList with two buffers for stereo audio stream

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?

like image 481
Pierre P. Avatar asked Mar 03 '18 18:03

Pierre P.


1 Answers

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)
like image 148
dave234 Avatar answered Sep 30 '22 18:09

dave234