我现在做什么:
我有一个音频单元运行一个回调来播放来自 iPod Lib 的音频。在回调中,我得到了 playxback 缓冲区所需的样本数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 函数的文档,我们都知道除了头文件之外,这里没有很多文档。
有什么提示吗?我的尝试在噪音或崩溃中都失败了……我知道这一定是可能的 ;-)
谢谢, 安德烈亚斯