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

Posted

技术标签:

【中文标题】iOS,音频队列:缓冲区大小不是恒定的【英文标题】:iOS, Audio Queue: Buffer size is not contant 【发布时间】:2011-06-11 20:24:40 【问题描述】:

我在我的应用程序中使用音频队列服务。在分配缓冲区时,我将缓冲区大小设置为 30000 个样本:

AudioQueueAllocateBuffer(mQueue, 30000, &mBuffers[i]);

但是回调的后续调用是使用以下inNumberPacketDescriptions进行的:

30000
30000
30000
26928
30000
30000

它们并不总是等于 30000。为什么?

记录格式配置(使用CAStreamBasicDescription):

mRecordFormat.mSampleRate = kSampleRate;    
mRecordFormat.mChannelsPerFrame = 1;
mRecordFormat.mFormatID = kAudioFormatLinearPCM;
mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
mRecordFormat.mBitsPerChannel = 16;
mRecordFormat.mBytesPerPacket = mRecordFormat.mBytesPerFrame = (mRecordFormat.mBitsPerChannel / 8) * mRecordFormat.mChannelsPerFrame;
mRecordFormat.mFramesPerPacket = 1;

3 个缓冲区被使用。

【问题讨论】:

这是在单个录制会话中吗?通常最后一个块会少于 30000,因为没有那么多样本。您是否在数据包计数小于 30000 的点暂停和恢复记录?还有你是怎么配置AudiostreamBasicDescription中的数据格式的? 没有停顿或停止。附记录格式配置。 【参考方案1】:

编辑:我看到 iOS 在出现非二次方音频缓冲区时会发疯并自发更改缓冲区大小。 (Another SO question 引用了这个)无论如何,

30000 是

(a) 巨大的缓冲区大小,以及

(b) 用于缓冲区的奇怪数字。通常它们是 2 的幂,即 *=2 来自 64,即 64、128、256、512、1024、2048、4096。我从未见过高于 4096 的,而且我做了很多音频工作。

如果您有特殊原因使用异常大的缓冲区,您可以使用 nextPowerOfTwo 便利函数或自己硬编码数学。

【讨论】:

可能,但这不是问题原因的答案。如果缓冲区大小是 2 的幂,它会一直保持不变吗? @buildsucceeded - 谢谢。为你点赞。试图解决为什么我编写的一些代码在 ipad mini 和模拟器上的 IOs7 上运行良好,但在 iphone 4s 上却忽略了所有音频数据。降低缓冲区大小,嘿presto。干活干活。 谢谢!仔细想想是有道理的,设备中用于这些缓冲区的内存量是有限的,出于性能原因,必须静态分配。 您好,只是一个后续问题。缓冲区大小受什么影响?当我将其设置为 1024 而不是 4096 或如何计算时有什么区别?这会影响录制音频的质量吗?我将采样率设置为 16k,那么我怎么知道应该设置的缓冲区的大小?谢谢! @finalstatic 质量不受影响除非缓冲区太小,无法在下一批音频进入之前处理音频,在这种情况下,您将得到故障。更大的缓冲区大小意味着更多的延迟,但如果您没有进行实时监控(并且没有受到很大的内存限制),那么相当大的缓冲区大小(512 或 1024)将为您提供很好的服务。

以上是关于iOS,音频队列:缓冲区大小不是恒定的的主要内容,如果未能解决你的问题,请参考以下文章

iOS 通过Audio Queue播放音频数据

音频队列播放完成的准确时间

Java 音频字节缓冲区需要不同的时间来填充

谷歌协议缓冲区是不是支持序列化前的大小计算?

播放流后音频队列无法录制音频

如何从音频队列缓冲区中提取整数样本并将修改后的样本写回?