Pie*_* P. 4 core-audio audiobufferlist swift
我在C中有以下代码,它们分配具有适当长度的AudioBufferList。
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);
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,时间mChannelsPerFrame是2,因此上面的代码创建了两个缓冲区,每个通道一个。每个缓冲区都有一个值得保留的内存bufferSizeBytes。
如何在Swift中复制相同的行为?
不幸的是,在Swift中,C数组被视为一个元组,因此AudioBufferList.mBuffers被导入具有单个AudioBuffer的元组。C允许您通过使用指针数学(在这种情况下为数组下标)来访问相邻内存,以创建可变长度的结构,Swift则不行。
普通的AudioBufferList不能很好地转换为Swift。苹果通过一些辅助函数和类型缓解了此问题。他们创建了一个静态分配函数,该函数返回一个UnsafeMutableAudioBufferListPointer,这是一种特殊类型,其中下标返回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)
Run Code Online (Sandbox Code Playgroud)
您可以使用 Core Audio API 创建一个包含 2 个缓冲区的 AudioBufferList,用于 2 个交错流:
import AudioUnit
import AVFoundation
var myBufferList = AudioBufferList(
mNumberBuffers: 2,
mBuffers: AudioBuffer(
mNumberChannels: UInt32(2),
mDataByteSize: myBufferSizeBytes,
mData: nil) )
Run Code Online (Sandbox Code Playgroud)