我有3个audioQueueBufferRef来填充我的音频队列,当数据足够快时,每个人的工作都很好。但有时,当没有更多数据时,outputCallback会要求填充缓冲区。在这种情况下,我不会将某些内容排入队列,并且不再调用回调。 (正常?)
在此之后,我运行2个缓冲区,然后(在另一个延迟之后)运行1个缓冲区,最后没有更多的缓冲区有回调,导致没有声音。
我尝试将空的audioQueueBufferRef存储在一个数组中,并在我要填充数据时调用它们。但由于数据速度不够快,缓冲区只会“吃掉”剩余的少量数据,而且声音也很滞后。
运行低数据填充时,最好的方法是什么?
我所拥有的最好的方法就是让缓冲区在没有回调的情况下死掉,让剩下的缓冲区完成工作,直到每个缓冲区都为空。在此之后我停止audioQueue,存储一些数据并再次播放。请注意,我必须调用AudioqueueStop(),因为当每个缓冲区都为空并且我重新填充它们时,没有声音出来。这是正常的吗?
一般来说,我这样做是好方法还是有更好的方法? 是否有回调检测到我的所有audioqueueBufferRef都已死(没有回调运行)? 2.
答案 0 :(得分:0)
我在playroutine中尝试过为你测试一个解决方案:
cnt++;
if (cnt > 5) {
inBuffer->mAudioDataByteSize = 4;
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
cnt = 0;
return;
}
它模拟每隔5次AudioQueue要求缓冲区的数据到达太晚。请注意,我将mAudioDataByteSize设置为4,这是2通道16位波形文件的SMALLEST样本大小。如果将大小设置为零,则队列将死亡并返回错误消息“kAudioQueueErr_BufferEmpty”,因此您需要提供数据,尽管您没有任何要提供的数据。如果你考虑一下,这是有道理的。
也许您甚至可以调整代码来估计需要等待多长时间来获取数据,让我们说您将在大约2ms内获得更多。然后你可以将缓冲区大小设置为小于该时间的样本数。如果您正在播放2声道16位44100 Hz波形歌曲,则2ms将达到44100 Hz的缓冲区大小* 0.002秒= 88,88 * 2声道*(16位/ 8)= 353字节。
答案 1 :(得分:0)
我认为回调是在您设置的频率中调用的,如果您无法及时填充数据,则声音异常。您的数据来自网络吗? 我遇到了与你相同的条件,我的解决方案是录制一个静音的数据包数据,当我没有音频数据填写时,我使用静音数据。