为啥我的音频队列输入回调中的数据包编号会有所不同?

Posted

技术标签:

【中文标题】为啥我的音频队列输入回调中的数据包编号会有所不同?【英文标题】:Why does the packet number in my audio queue input callback vary?为什么我的音频队列输入回调中的数据包编号会有所不同? 【发布时间】:2014-10-02 19:45:03 【问题描述】:

我在 Mac OS X 上使用音频队列服务记录 PCM 音频数据。它可以工作,但我在回调中获得的帧数会有所不同。

static void MyAQInputCallback(void *inUserData, AudioQueueRef inQueue, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudiostreamPacketDescription *inPacketDesc)

在我的音频输入队列的每次调用中,我都希望获得 5 毫秒(240 帧/inNumPackets,48 kHz)的音频数据。

这是我使用的音频格式:

AudioStreamBasicDescription recordFormat = 0;
memset(&recordFormat, 0, sizeof(recordFormat));
recordFormat.mFormatID = kAudioFormatLinearPCM;
recordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
recordFormat.mBytesPerPacket = 4;
recordFormat.mFramesPerPacket = 1;
recordFormat.mBytesPerFrame = 4;
recordFormat.mChannelsPerFrame = 2;
recordFormat.mBitsPerChannel = 16;

我有两个 960 字节的缓冲区排队:

for (int i = 0; i < 2; ++i) 
    AudioQueueBufferRef buffer;
    AudioQueueAllocateBuffer(queue, 960, &buffer);
    AudioQueueEnqueueBuffer(queue, buffer, 0, NULL);

我的问题:每 240 帧 (inNumPackets) 的 204 次调用一次回调,只有 192 帧。

为什么会发生这种情况,我可以做些什么来不断获得 240 帧吗?

【问题讨论】:

【参考方案1】:

音频队列在音频单元之上运行。音频单元缓冲区很可能由操作系统配置为 2 的幂,并且您返回的音频队列缓冲区被从较大的音频单元缓冲区中截取。

204 * 240 + 192 = 12 个 4096 的音频单元缓冲区。

如果您想要不是 2 次幂的固定长度缓冲区,最好的办法是让应用程序将传入的缓冲区重新缓冲(保存到您有足够的数据)到您想要的长度。无锁的循环 fifo/缓冲区可能适合此目的。

【讨论】:

以上是关于为啥我的音频队列输入回调中的数据包编号会有所不同?的主要内容,如果未能解决你的问题,请参考以下文章

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

我的应用程序“查找麦克风的音频输入频率”总是崩溃。但为啥?

iOS 通过Audio Queue播放音频数据

简单的 AudioQueue 正弦波——为啥会失真?

iPhone音频流 - 保存状态?

音频输出单元的输入回调中允许哪些操作