Подтвердить что ты не робот

Android: звук API (детерминированный, низкая латентность)

Я просматриваю все виды API звука для Android, и я хотел бы знать, какой из них я должен использовать. Моя цель - получить звук с низкой задержкой или, по крайней мере, детерминированное поведение в отношении задержки воспроизведения.

У нас было много проблем, и кажется, что Android-звук API - это дерьмо, поэтому я изучаю возможности.

Проблема заключается в том, что между sound_out.write(sound_samples); и фактическим звуком, воспроизводимым из динамиков, существует значительная задержка. Обычно это около 300 мс. Проблема в том, что на всех устройствах он отличается; некоторые из них не имеют этой проблемы, но большинство из них искалечено (однако вызов CS имеет нулевую задержку). Самая большая проблема с этой нелепой задержкой заключается в том, что на некоторых устройствах эта задержка представляется некоторым случайным значением (т.е. Не всегда 300 мс).

Я читаю о OpenSL ES, и я хотел бы знать, есть ли у кого-нибудь опыт с ним, или это же дерьмо, но упаковано в другой пакет?

Я предпочитаю иметь собственный доступ, но я не имею в виду перенаправление уровня Java, пока я могу получить детерминированное поведение: либо задержка должна быть постоянной (для данного устройства), либо я хотел бы получить доступ в текущую позицию воспроизведения, а не гадать с диапазоном ошибок ± 300 мс...

EDIT:
Спустя 1,5 года я попробовал несколько телефонов Android, чтобы узнать, как я могу получить наилучшую латентность для голосовой связи в реальном времени. Используя специализированные инструменты, я измерил задержку пути всплеска. Лучшие результаты были более 100 мс, большинство телефонов находились в диапазоне 180 мс. У кого-нибудь есть идеи?

4b9b3361

Ответ 1

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

Почему OpenSL? AudioTrack и OpenSL имеют аналогичные задержки, с одним важным отличием: обратные вызовы буфера AudioTrack обслуживаются в Dalvik, а обратные вызовы OpenSL обслуживаются в собственных потоках. Текущая реализация Dalvik не способна обслуживать обратные вызовы при крайне низких задержках, потому что нет способа приостановить сбор мусора во время обратных вызовов звука. Это означает, что минимальный размер буферов AudioTrack должен быть больше минимального размера для буферов OpenSL, чтобы поддерживать безупречное воспроизведение.

В большинстве релизов Android эта разница между AudioTrack и OpenSL никак не изменилась. Но с Jellybean у Android теперь есть аудиоканал с низкой задержкой. Фактическая задержка по-прежнему зависит от устройства, но она может быть значительно ниже, чем раньше. Например, http://code.google.com/p/music-synthesizer-for-android/ использует 384-фреймовые буферы на Galaxy Nexus для общей выходной задержки менее 30 мс. Это требует, чтобы звуковой поток обслуживал буферы примерно раз в 8 мсек, что было невозможно в предыдущих выпусках Android. Это еще не возможно в ниве Dalvik.

Это объяснение предполагает две вещи: во-первых, вы запрашиваете наименьшие возможные буферы из OpenSL и выполняете свою обработку в обратном вызове буфера, а не в очереди буфера. Во-вторых, ваше устройство поддерживает путь с низкой задержкой. На большинстве современных устройств вы не увидите большой разницы между AudioTrack и OpenSL ES. Но на устройствах, поддерживающих звук Jellybean + и low-latency, OpenSL ES предоставит вам путь с низкой задержкой.

Ответ 2

IIRC, OpenSL проходит через тот же интерфейс, что и AudioTrack, поэтому в лучшем случае он будет соответствовать AudioTrack. (FWIW, я в настоящее время использую OpenSL для вывода с низкой задержкой)

Печальная истина в том, что на Android нет такой вещи, как звук с низкой задержкой. Не существует даже подходящего способа для флага и/или фильтрации устройств на основе задержки звука.

Какой интерфейс вы хотите использовать для минимизации задержки, зависит от того, что вы пытаетесь сделать. Если вы хотите иметь аудиопоток, вы будете искать либо OpenSL, либо AudioTrack.

Если вы хотите запускать некоторые статические снимки, вы можете использовать SoundPool. Для статических снимков SoundPool будет иметь низкую задержку, поскольку образцы предварительно загружаются на аппаратное обеспечение. Я думаю, что можно предварительно загружать снимки с помощью OpenSL, но я не пробовал.

Ответ 3

Самая низкая латентность, которую вы можете получить, - от SoundPool. Там есть ограничение на то, насколько большой звук вы можете играть таким образом, но если вы находитесь под лимитом (1Mb, IIRC), это довольно низкая латентность. Даже это, вероятно, не 40 мс.

Но это быстрее, чем то, что вы можете получить по потоковой передаче, по крайней мере, в моем опыте.

Предостережение: вы можете наблюдать случайные сбои в SoundPool на устройствах Samsung. У меня есть теория, что это происходит только при доступе к SoundPool из нескольких потоков, но я не проверял это.

EDIT: OpenSL ES, по-видимому, имеет чрезвычайно высокую задержку в Kindle Fire, в то время как SoundPool намного лучше, но обратное может быть правдой на других платформах.