我现在所做的事情:
我有一个带回调的音频设备,用于播放iPod Lib的音频。
在回调中,我得到了inNumberFrames
static OSStatus playbackMP3Callback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
BeepTrackController *remoteIOplayer = (__bridge BeepTrackController *)inRefCon;
for (int i = 0 ; i < ioData->mNumberBuffers; i++){
AudioBuffer buffer = ioData->mBuffers[i];
if (remoteIOplayer->_isMP3Running == YES) {
SInt16 peak = [remoteIOplayer getMP3Samples:buffer.mData nrOfAudioFrames:inNumberFrames];
}else
memset(buffer.mData,0,ioData->mBuffers[i].mDataByteSize);
}
return noErr;
}
对于iPod Lib读取我使用带有CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer的AssetReader,它提供了许多样本,这些样本与来自音频回调缓冲区的所需数量的样本不同。她只是重要的代码行:
-(SInt16) getMP3Samples:(SInt16*)address nrOfAudioFrames:(NSInteger)nrOfFrames
... Loop ....
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(
_mp3Control.nextbuffer,
NULL,
&audioBufferList,
sizeof(audioBufferList),
NULL,
NULL,
kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment,
&_mp3Control.blockBuffer
);
... SNIP ....
for (int bufferCount=currentBuffer; bufferCount < audioBufferList.mNumberBuffers; bufferCount++) {
SInt16* samples = (SInt16 *)audioBufferList.mBuffers[bufferCount].mData;
for (int i=currentSampleCount; i < audioBufferList.mBuffers[bufferCount].mDataByteSize/2 ; i++) {
currentSample = samples[i];
address [_mp3Control.currentSampleBufferCount++] = currentSample;
// End of Buffer reached?
if (_mp3Control.currentSampleBufferCount >nrOfFrames*2) {
_mp3Control.currentSampleBufferCount = 0;
currentBuffer = bufferCount;
currentSampleCount = i;
return currentSample;
}
}
}
所以我想要的是CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer准确地返回AUnit回调中我的回调缓冲区所需的样本量。由于结构相同,我怀疑这里必须是一种同步它的方法。 我已经获得了音频播放,但是使用了不同大小的缓冲区的丑陋静态指针,我希望它更优雅,因此更健壮。
现在我正在阅读CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer函数的doco,我们都知道除了头文件之外没有很多文档。
任何提示?我的尝试在噪音或崩溃中都失败了......我知道它一定是可能的; - )
谢谢, 安德烈亚斯
答案 0 :(得分:0)
无法保证操作系统会返回您请求或需要的音频缓冲区大小。它甚至可能在运行时改变大小。因此,应该只使应用程序的中间缓冲代码清洁和健壮。无锁循环FIFO是一种常见的解决方案。