iPhone:AudioBufferList init和release

用3个AudioBuffers初始化(分配内存)和释放(释放)AudioBufferList的正确方法是什么? (我知道可能有不止一种方式来做这件事。)

我想使用这3个缓冲区来读取audio文件的连续部分,并使用audio单元进行播放。

下面是我如何做到这一点:

AudioBufferList * AllocateABL(UInt32 channelsPerFrame, UInt32 bytesPerFrame, bool interleaved, UInt32 capacityFrames) { AudioBufferList *bufferList = NULL; UInt32 numBuffers = interleaved ? 1 : channelsPerFrame; UInt32 channelsPerBuffer = interleaved ? channelsPerFrame : 1; bufferList = static_cast<AudioBufferList *>(calloc(1, offsetof(AudioBufferList, mBuffers) + (sizeof(AudioBuffer) * numBuffers))); bufferList->mNumberBuffers = numBuffers; for(UInt32 bufferIndex = 0; bufferIndex < bufferList->mNumberBuffers; ++bufferIndex) { bufferList->mBuffers[bufferIndex].mData = static_cast<void *>(calloc(capacityFrames, bytesPerFrame)); bufferList->mBuffers[bufferIndex].mDataByteSize = capacityFrames * bytesPerFrame; bufferList->mBuffers[bufferIndex].mNumberChannels = channelsPerBuffer; } return bufferList; } 

首先,我认为你实际上需要3个AudioBufferLists,而不是一个AudioBufferList和3个AudioBuffer成员。 一个AudioBuffer代表一个数据通道,所以如果你有3个立体声audio文件,你应该把它们放在3个AudioBufferLists中,每个列表有2个AudioBuffers,左边一个缓冲区,右边一个。 然后你的代码将分别处理每个列表(及其各自的通道数据),并且可以将列表存储在NSArray或类似的东西中。

从技术上讲,没有理由不能有一个单一的缓冲区列表与3交错audio通道(这意味着左右声道都存储在一个单一的数据缓冲区),但这违背了传统的API使用,将有点混乱。

无论如何,CoreAudio API的这一部分比Objective-C-ish更多的C-ISH,所以你可以使用malloc / free而不是alloc / release。 代码看起来像这样:

 #define kNumChannels 2 AudioBufferList *bufferList = (AudioBufferList*)malloc(sizeof(AudioBufferList) * kNumChannels); bufferList->mNumberBuffers = kNumChannels; // 2 for stereo, 1 for mono for(int i = 0; i < 2; i++) { int numSamples = 123456; // Number of sample frames in the buffer bufferList->mBuffers[i].mNumberChannels = 1; bufferList->mBuffers[i].mDataByteSize = numSamples * sizeof(Float32); bufferList->mBuffers[i].mData = (Float32*)malloc(sizeof(Float32) * numSamples); } // Do stuff... for(int i = 0; i < 2; i++) { free(bufferList->mBuffers[i].mData); } free(bufferList); 

上面的代码假设你正在读取浮点数据。 如果你没有对这些文件做任何特殊的处理,那么将它们作为SInt16(原始的PCM数据)读取,效率会更高,因为iPhone没有FPU。

另外,如果你没有使用单个方法以外的列表,那么通过将它们声明为常规对象而不是指针,将它们分配到堆栈而不是堆上更有意义。 你仍然需要malloc()实际的AudioBuffer的mData成员,但至less你不需要担心free()实际的AudioBufferList本身。