macos - 为什么我的音频队列输入回调中的数据包编号不同?

标签 macos audio core-audio audio-recording audioqueueservices

我使用音频队列服务在 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/

相关文章:

ios - ExtAudioFile - 如何设置元数据

c++ - 通过 M-Audio ProFire 610 输出声音

macos - 如何在 mac os 中跳过或禁用浏览器的 SSL 检查?

c++ - 全屏模式下未触发 KeyRelease 事件

objective-c - SceneKit 避免在特定节点上照明

ios - macOS Catalyst 应用程序未显示在 iTunes/App Store Connect 构建选项中

android - 停止失败,带有 TarsosDSP 的 Android 应用程序

java - 如何刷新 AudioRecord 对象中的缓冲区?

android - 是否可以使用标准音乐应用程序来选择音频文件?

audio - 使用PortAudio生成正弦波以播放中间C