我正在努力理解Core Audio,或者更确切地说:Extended Audio File Services
在这里,我想使用ExtAudioFileRead()
从文件中读取一些音频数据
只要我使用一个巨大的缓冲区来存储我的音频数据(即一个AudioBuffer
),这就可以正常工作。只要我使用多个AudioBuffer
,ExtAudioFileRead()
就会返回错误代码-50
(“参数列表中的错误”)。据我所知,这意味着ExtAudioFileRead()
的一个论点是错误的。可能是audioBufferList
。
我不能使用一个巨大的缓冲区,因为dataByteSize
会溢出其UInt32
- 整数范围的大文件。
以下是创建audioBufferList
的代码:
AudioBufferList *audioBufferList;
audioBufferList = malloc(sizeof(AudioBufferList) + (numBuffers-1)*sizeof(AudioBuffer));
audioBufferList->mNumberBuffers = numBuffers;
for (int bufferIdx = 0; bufferIdx<numBuffers; bufferIdx++ ) {
audioBufferList->mBuffers[bufferIdx].mNumberChannels = numChannels;
audioBufferList->mBuffers[bufferIdx].mDataByteSize = dataByteSize;
audioBufferList->mBuffers[bufferIdx].mData = malloc(dataByteSize);
}
这是工作但溢出的代码:
UInt32 dataByteSize = fileLengthInFrames * bytesPerFrame; // this will overflow
AudioBufferList *audioBufferList = malloc(sizeof(audioBufferList));
audioBufferList->mNumberBuffers = 1;
audioBufferList->mBuffers[0].mNumberChannels = numChannels;
audioBufferList->mBuffers[0].mDataByteSize = dataByteSize;
audioBufferList->mBuffers[0].mData = malloc(dataByteSize);
最后,ExtAudioFileRead()
的调用(适用于两个版本):
UInt32 numFrames = fileLengthInFrames;
error = ExtAudioFileRead(extAudioFileRef,
&numFrames,
audioBufferList);
你知道我在这里做错了吗?
答案 0 :(得分:5)
我认为你误解了mNumberBuffers字段的用途。单声道和交错立体声数据通常为1
。您将其设置为其他内容的唯一原因是多轨数据,其中每个通道都位于单独的数据缓冲区中。
如果你想读取文件的一部分,你可以将缓冲区的dataByteSize设置为合理的大小,当你读取文件时,告诉API只给你那么多字节,然后循环它。 / p>
答案 1 :(得分:1)
我也遇到了与mNumberBuffers相同的问题&gt; 1 ,, ... 我的工作涉及创建自己的内部缓冲区:
类似的东西:
char buffer1 [byteSize]; char buffer2 [byteSize]; ......
你也可以使用指针来简化事情,比如:
缓冲液[指数] [byteSize];
然后你必须手动迭代它们并将它们填满主线程以避免音频故障。
ExtAudioFileRead只会填充AudioBufferList中的buffer [0],然后你可以在音频播放时指向不同的手动分配的缓冲区。
希望这会有所帮助。
答案 2 :(得分:0)
mNumberBuffers == 2。它是未交错时的音频通道数。
答案 3 :(得分:-3)
Cocoa似乎根本不接受mNumberBuffers&gt;这是一种耻辱,因为它使整个结构无用。 (我希望这是正确的......)