Аудио буферизация в Android

Я пытаюсь реализовать эффективный аудио буфер для потоковой передачи. Изначально я пытался сделать буферизацию следующим образом Программный поток

Так что изначально у меня есть мой InputStream который взят из HttpUrlConnection, Данные считываются из входного потока циклическим буфером, который заполняет буферы. В этом случае у меня есть 3 буфера, но количество и размер буферов можно легко изменить. Поэтому после того, как все буферы заполнены, я начинаю записывать данные из моего первого буфера в OutputStream который связан с InputStreamтак что всякий раз, когда я пишу что-то OutputStream это можно затем прочитать из InputStream, MediaCodec отвечает за чтение данных из InputStream и декодирование данных, которые затем передаются AudioTrack,

Проблема с этой настройкой заключается в том, что через некоторое время OutputStream в конце концов достигает конца циклического буфера, поэтому между ними больше нет "дополнительного буфера" "OutputStream.giveMeNextBufferWithData" а также "CircularBuffer.readDataFromInputStreamAndCreateBuffer" (псевдокод).

Я пытался увеличить количество и размер каждого буфера, но это не помогло. Это просто задерживает количество времени, прежде чем OutputStream становится "голодным" для получения дополнительных данных.

Есть одна очень хорошая библиотека https://code.google.com/p/aacdecoder-android/ которая очень хорошо работает, когда дело доходит до буферизации аудио, но, к сожалению, я не мог понять, как там делается буферизация, и она не не работает так хорошо при некоторых обстоятельствах.

Так есть ли "идеальный" алгоритм для такой задачи? Я думал о двойной / тройной буферизации, но я не слишком уверен в этом и, учитывая, что я искал в сети и безуспешно внедрял различные решения в течение последних нескольких дней, я в конце концов решил спросить ее.

Надеюсь, я все хорошо объяснил.

Спасибо всем заранее!

1 ответ

Буферизация сама по себе в конечном счете недостаточна для потоковых источников с фиксированной скоростью передачи (по запросу), где вы не можете гарантировать, что частота дискретизации источника и устройства абсолютно одинакова.

Для коротких программ вы можете буферизовать секунду или две аудио, и если ваша скорость воспроизведения будет высокой, вы начнете погружаться в этот резерв, но, надеюсь, не превысите его. Точно так же вам нужна избыточная емкость буфера, если вы воспроизводите данные медленнее, чем они генерируются. Но они в конечном итоге потерпят неудачу, когда разница в частоте дискретизации накапливается больше, чем размер резервного буфера.

Вместо этого, чтобы потоковая передача работала "вечно", вам нужен способ выровнять нормы производства и потребления.

"Ленивый" способ сделать это состоит в том, чтобы иметь логику, которая добавляет или отбрасывает одну выборку за более длительную единицу времени, в зависимости от направления, в котором произошла ошибка. Но это технически вносит искажения.

"Причудливый" способ сделать это состоит в том, чтобы иметь преобразователь с переменной частотой дискретизации, соотношение которого может быть скорректировано с течением времени, чтобы противодействовать ошибке между уровнем потребления аудио и скоростью производства.

Другие вопросы по тегам