0

我现在做什么:

我有一个音频单元运行一个回调来播放来自 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 函数的文档,我们都知道除了头文件之外,这里没有很多文档。

有什么提示吗?我的尝试在噪音或崩溃中都失败了……我知道这一定是可能的 ;-)

谢谢, 安德烈亚斯

4

1 回答 1

0

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

于 2013-04-28T20:29:05.240 回答