我使用音频队列服务在 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 帧吗?
最佳答案
音频队列在音频单元之上运行。操作系统很可能将音频单元缓冲区的大小配置为 2 的幂,并且返回的音频队列缓冲区将从较大的音频单元缓冲区中剔除。
204 * 240 + 192 = 12 个音频单元缓冲区,共 4096 个。
如果您想要不是 2 的幂的固定长度缓冲区,最好的选择是让应用程序将传入缓冲区重新缓冲(保存直到有足够的数据)到您想要的长度。无锁循环 fifo/缓冲区可能适合此目的。
关于macos - 为什么我的音频队列输入回调中的数据包编号不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26168429/