CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer返回buff大小可调?

时间:2013-04-26 12:13:59

标签: iphone ios core-audio

我现在所做的事情:

我有一个带回调的音频设备,用于播放iPod Lib的音频。 在回调中,我得到了inNumberFrames

的playxback缓冲区所需的样本数
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,我们都知道除了头文件之外没有很多文档。

任何提示?我的尝试在噪音或崩溃中都失败了......我知道它一定是可能的; - )

谢谢, 安德烈亚斯

1 个答案:

答案 0 :(得分:0)

无法保证操作系统会返回您请求或需要的音频缓冲区大小。它甚至可能在运行时改变大小。因此,应该只使应用程序的中间缓冲代码清洁和健壮。无锁循环FIFO是一种常见的解决方案。