AudioQueueBufferRef пустой из-за задержки потока
У меня есть 3 audioQueueBufferRef, чтобы заполнить мою очередь аудио, и все работает хорошо, когда данные поступают достаточно быстро. Но иногда outputCallback просит заполнить буфер, когда данных больше нет. В этом случае я ничего не ставлю в очередь, и обратный вызов больше не вызывается. (нормальный?)
После этого я запускаю с 2 буферами и позже (после другого лага) 1 буфер, и в самом последнем случае буферы больше не имеют обратных вызовов, что приводит к отсутствию звука.
Я пытаюсь сохранить пустой audioQueueBufferRef в массиве и вызывать их, когда у меня есть данные для заполнения. Но так как данные поступают недостаточно быстро, буфер просто "съедает" оставшееся у меня небольшое количество данных, и звук остается медленным.
Каков наилучший способ пойти, когда заканчивается данных для заполнения?
Лучшее, что я нашел, - это позволить буферу просто умереть без обратного вызова и позволить оставшемуся буферу выполнять работу, пока каждый буфер не будет пуст. После этого я останавливаю audioQueue, сохраняю некоторые данные и играю снова. Обратите внимание, что мне нужно вызвать AudioqueueStop(), потому что, когда все буферы пусты и я снова их заполняю, звук не выходит. Это нормально?
В целом я делаю это хорошо или есть лучший подход? И есть ли обратный вызов, который обнаруживает, что все мои audioqueueBufferRef мертвы (без выполнения обратного вызова)? 2.
2 ответа
Я попробовал это в playroutine, чтобы проверить решение для вас:
cnt++;
if (cnt > 5) {
inBuffer->mAudioDataByteSize = 4;
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
cnt = 0;
return;
}
Он имитирует, что данные поступают слишком поздно каждый раз, когда AudioQueue запрашивает буфер. Обратите внимание, что я поместил mAudioDataByteSize в размер 4, который является МАЛЕНЬКИМ размером выборки для двухканального 16-битного волнового файла. Если вы установите размер равным нулю, очередь умрет и вернет сообщение об ошибке "kAudioQueueErr_BufferEmpty", так что вам нужно подавать данные, хотя их не нужно подавать. Если вы думаете об этом, это имеет смысл.
Возможно, вы могли бы даже адаптировать код, чтобы оценить, сколько времени вам нужно ждать, чтобы получить данные, скажем, вы получите больше примерно за 2 мс. Тогда вы можете просто установить размер буфера равным количеству семплов чуть меньше, чем за это время. Если вы воспроизводите 2-канальную 16-битную звуковую песню 44100 Гц, 2 мс будут равны размеру буфера 44100 Гц * 0,002 секунды = 88, 88 * 2 канала * (16 бит / 8) = 353 байта.
Я думаю, что обратный вызов вызывается с установленной вами частотой. Если вы не можете заполнить данные вовремя, звук ненормальный. Ваши данные из сети? Я выполнил то же условие, что и вы, и мое решение состоит в том, чтобы записать один пакет данных, который является тишиной, и когда у меня нет аудиоданных для заполнения, я вместо этого использую данные молчания.