0

我有 3 个 audioQueueBufferRef 来填充我的音频队列,当数据足够快时,一切都很好。但有时 outputCallback 要求在没有更多数据时填充缓冲区。在这种情况下,我不会将某些东西排入队列,并且不再调用回调。(普通的 ?)

在此之后,我使用 2 个缓冲区和后来(在另一个滞后之后)1 个缓冲区运行,最后没有更多的缓冲区有回调导致没有声音。

我尝试将空的 audioQueueBufferRef 存储在一个数组中,并在我有数据要填充时调用它们。但由于数据来得不够快,缓冲区只会“吃掉”我剩下的少量数据,而且声音很迟钝。

当要填充的数据不足时,最好的方法是什么?

我发现的最好的方法是让缓冲区在没有回调的情况下死掉,让剩余的缓冲区完成这项工作,直到每个缓冲区都为空。在此之后我停止音频队列,存储一些数据并再次播放。请注意,我必须调用 AudioqueueStop() 因为当每个缓冲区都是空的并且我重新填充它们时,没有声音出来。这是正常的吗?

一般来说,我是用好方法还是有更好的方法?是否有一个回调检测到我所有的 audioqueueBufferRef 都死了(没有回调运行)?2.

4

2 回答 2

0

我觉得回调是按照你设定的频率调用的,如果不能及时填充数据,声音就异常了。您的数据是否来自网络?我遇到了和你一样的情况,我的解决方案是记录一个无声的数据包数据,当我没有要填写的音频数据时,我改用无声数据。

于 2013-12-01T14:20:55.007 回答
0

我在 playroutine 中尝试了这个来为你测试一个解决方案:

cnt++;
if (cnt > 5) {
    inBuffer->mAudioDataByteSize = 4;

    AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
    cnt = 0;
    return;
}

它模拟每 5 次 AudioQueue 请求缓冲区时数据到达太晚。请注意,我将 mAudioDataByteSize 设置为 4,这是 2 通道 16 位波形文件的最小样本大小。如果将大小设置为零,则队列将终止并返回错误消息“kAudioQueueErr_BufferEmpty”,因此您确实需要提供数据,尽管您没有任何要提供的数据。如果你仔细想想,这是有道理的。

也许您甚至可以调整代码来估计您需要等待多长时间才能获取数据,假设您将在大约 2 毫秒内获得更多数据。然后,您可以将缓冲区大小设置为比该时间少一点的样本数。如果您正在播放 2 通道 16 位 44100 Hz 波形歌曲,2 毫秒将相当于 44100 Hz * 0.002 秒 = 88、88 * 2 通道 *(16 位 / 8)= 353 字节的缓冲区大小。

于 2013-12-01T12:55:44.750 回答