关于 iphone:AudioQueue 吃了我的缓冲区(前 15 毫秒)
AudioQueue ate my buffer (first 15 milliseconds of it)
我正在以编程方式生成音频。我听到缓冲区之间的沉默间隙。当我将手机连接到示波器时,我发现每个缓冲区的前几个样本都丢失了,取而代之的是静默。这种静默的长度从几乎没有变化到长达 20 毫秒。
我的第一个想法是我原来的回调函数花费了太多时间。我用最短的可能替换它——它一遍又一遍地重新排列相同的缓冲区。我观察到同样的行为。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
AudioQueueRef aq;
AudioQueueBufferRef aq_buffer; AudioStreamBasicDescription asbd; void aq_callback (void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { void aq_init(void) { asbd.mSampleRate = AUDIO_SAMPLES_PER_S;
int PPM_PACKETS_PER_SECOND = 50; s = AudioQueueNewOutput(&asbd, aq_callback, NULL, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &aq); // put samples in the buffer s = AudioQueueStart(aq, NULL); |
我不熟悉 iPhone 音频 API,但它似乎与其他通常您会排队多个缓冲区的 API 相似,这样当系统完成处理第一个缓冲区时,它可以立即启动在执行第一个缓冲区的完成回调时处理下一个缓冲区(因为它已经排队)。
类似:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
AudioQueueRef aq;
AudioQueueBufferRef aq_buffer[2]; AudioStreamBasicDescription asbd; void aq_callback (void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) { void aq_init(void) { asbd.mSampleRate = AUDIO_SAMPLES_PER_S;
int PPM_PACKETS_PER_SECOND = 50; s = AudioQueueNewOutput(&asbd, aq_callback, NULL, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &aq); // put samples in the buffer - fill both buffers s = AudioQueueStart(aq, NULL); |
相关讨论
- 感谢您指出我可以在 init() 中将多个缓冲区加入队列——这个重要的事实让我无法理解。实施此建议以及对回调的更改改善了我的情况,但并没有解决它。我仍然想念一些缓冲区的前几毫秒。现在这种情况仅每 7 或 8 个数据包发生一次,我错过的样本更少,但仍然很明显。
- 在这个简单的例子中,这似乎并不重要,但以防万一:拥有超过 2 个缓冲区是否有帮助(以防万一你还没有尝试过)?另外,您确定 buffer_data() 正在用整整 1/50 秒的数据包填充缓冲区吗? AUDIO_SAMPLES_PER_S 的值是多少?
- 感谢您一直以来的支持。如果我使用 3 个缓冲区而不是 2 个缓冲区,我就不会丢失样本。这看起来很神奇……这种魔法让我感到不舒服,因为我无法解释它。我想知道是否有某种双缓冲正在进行。我以前尝试过使用缓冲区的大小,使它们长达 1 秒 (PPM_PACKETS_PER_SECOND = 1)。使用 2 个长缓冲区,我仍然会丢失样本。使用 3 个短缓冲区,我可以取回我放入的所有内容。
- 为了完整起见,您的其他问题的答案:我用定义明确的值填充缓冲区的末端,直到它们的长度(buffer_data 检查 AudioQueueBuffer.mAudioDataBytesCapacity)并且 AUDIO_SAMPLES_PER_S 是 #define 到 44100。