为啥我的 iOS 录音回调中的音频缓冲区未满?

Posted

技术标签:

【中文标题】为啥我的 iOS 录音回调中的音频缓冲区未满?【英文标题】:Why is the audiobuffer not full in my iOS audio recording callback?为什么我的 iOS 录音回调中的音频缓冲区未满? 【发布时间】:2016-03-23 10:32:08 【问题描述】:

录音正常工作:我可以录制和播放录音。唯一奇怪的是,有时调用回调函数时使用未完全填充的缓冲区。 我在 StreamCallback 函数中记录了 inNumPackets 变量的值,序列可能如下所示:

2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 1568, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2010、2048、2048、

处理缓冲区的代码目前依赖于固定大小,这意味着每次缓冲区未填充时我都会得到工件。

我可以做一些事情来始终获得完整的缓冲区吗? - 还是预期的行为?

我的代码中的一些摘录:

DataFormat.mFormatID := kAudioFormatLinearPCM;
DataFormat.mSampleRate := 44100;
DataFormat.mChannelsPerFrame := 1;
DataFormat.mBitsPerChannel := 16;
DataFormat.mBytesPerPacket := 2;
DataFormat.mBytesPerFrame := 2;
DataFormat.mFramesPerPacket := 1;
DataFormat.mFormatFlags := kLinearPCMFormatFlagIsSignedInteger OR kLinearPCMFormatFlagIsPacked;

lStatus := AudioQueueNewInput(@DataFormat,@StreamCallback,nil,nil,kCFRunLoopCommonModes,0,fAqDataQueue);
...
//allocate 3 buffers with a buffer size of 2048 packets with 2 bytes per packet
AudioQueueAllocateBuffer(fAqDataQueue,2*2048,fAqDataBuffers[li]);

【问题讨论】:

【参考方案1】:

您不能使用依赖于固定大小的 ios Core Audio 缓冲区的处理。这是因为由于您的应用程序无法控制的原因(例如设备上运行的其他音频进程所需的采样率重新采样或设备的硬件功能或各种省电),iOS 可以随意更改音频单元缓冲区大小模式等)

如果您需要处理固定大小的缓冲区,请对传入的音频单元样本使用无锁循环 FIFO/缓冲区,并轮询该 FIFO 以查看它是否包含足够的样本以供您的处理步骤使用。详情请见this answer。

【讨论】:

以上是关于为啥我的 iOS 录音回调中的音频缓冲区未满?的主要内容,如果未能解决你的问题,请参考以下文章

为啥缓冲区未满时字节缓冲区会出现缓冲区溢出异常

IOS中重复音频的损坏录音

为啥 SDL2 为音频样本提供的缓冲区不够大?

iOS,音频队列:缓冲区大小不是恒定的

音频单元录制噪音

如何正确使用 iOS AudioUnit 渲染回调