2013-02-12 2 views
36

я в настоящее время пытаюсь свести к минимуму задержки звука для простого приложения:с низкой задержкой воспроизведение звука на Android

У меня есть видео на ПК, и я передающее аудио видео-ролика через RTP для мобильного клиента , С очень похожим алгоритмом буферизации я могу достичь 90 мс латентности на iOS, но ужасно ± 180 мс на Android.

Я угадываю разницу между well-known латентностью issues на Android.

Однако после прочтения вокруг немного, I came upon this article, в котором говорится, что:

  1. с низкой задержкой аудио доступна с Android 4.1/4.2 в некоторых устройствах.

  2. Звук с низкой задержкой может быть достигнут с использованием libpd, which is Pure Data library for Android.

я 2 вопроса, непосредственно связанные с этими 2 заявления:

  1. Где я могу найти более подробную информацию о новой малой задержкой звука в Jellybean? This is all I can find but it's sorely lacking in specific information. Должны ли изменения быть прозрачными для меня или есть какие-то новые вызовы класса/API, которые я должен реализовать для меня, чтобы заметить какие-либо изменения в моем приложении? Я использую API AudioTrack, и я даже не уверен, что ему следует извлечь пользу из этого улучшения или если я буду изучать какой-то другой механизм воспроизведения звука.

  2. Должен ли я изучать использование libpd? Мне кажется, что это единственный шанс добиться меньших латентностей, но поскольку я всегда думал о PD как утилите для синтеза звука, действительно ли это подходит для проекта, который просто захватывает кадры из сетевого потока и воспроизводит их обратно ? Я вообще не синтезирую. Я следую за неправильным тропом?

В качестве дополнительной записке, прежде, чем кто-то упоминает OpenSL ES, this article makes it quite clear that no improvements in latency should be expected from using it:

«Как OpenSL ES является родным C API, не-Dalvik применения нити, которые OpenSL вызова ES не имеют Dalvik связанные с отходами, такие как сбор мусора . Однако нет дополнительного преимущества в производительности для использования OpenSL ES, кроме этого. В частности, использование OpenSL ES не приводит к снижению задержки звука, более высоким приоритетам планирования, и т.д., чем то, что в целом обеспечивает платформа «

+10

Я член команды Android, и я работать в тесном сотрудничестве с авторами статьи вы процитировать. Прохождение, которое вы цитируете, больше не является верным. Когда статья была написана, самые маленькие буферы, доступные OpenSL, все еще были довольно большими. Теперь, когда размер буфера был уменьшен в Jellybean, латентность упала до такой степени, что «связанные с Dalvik накладные расходы, такие как паузы в сборке мусора» является очень важным соображением. Единственный способ надежного использования меньших буферов Jellybean - использовать OpenSL. –

ответ

60

Для низкой латентностью на Android, начиная с версии 4.2.2, вы должны сделать следующее, упорядоченный от наименее до наиболее очевидным:

  1. Выберите устройство, которое поддерживает FEATURE_AUDIO_PRO, если это возможно, или FEATURE_AUDIO_LOW_LATENCY, если нет. («Низкая латентность» - 50 мс в одну сторону, про - < 20 м. В оба конца.)

  2. Использование OpenSL. Далвик GC имеет низкую амортизированную стоимость, но при его запуске требуется больше времени, чем может обеспечить звук с низкой задержкой.

  3. Обработать аудио в обратном вызове очереди буфера. Система выполняет обратные вызовы очереди буфера в потоке, который имеет более благоприятное планирование, чем обычные потоки пользовательского режима.

  4. Сделайте свой размер буфера кратным AudioManager.getProperty (PROPERTY_OUTPUT_FRAMES_PER_BUFFER). В противном случае ваш обратный вызов будет иногда получать два вызова за один раз, а не один. Если ваше использование ЦП действительно не светло, это, вероятно, закончится срывом. (В Android M очень важно использовать ТОЧНО размер системного буфера из-за ошибки в коде обработки буфера.)

  5. Используйте частоту дискретизации, предоставленную AudioManager.getProperty (PROPERTY_OUTPUT_SAMPLE_RATE). В противном случае ваши буферы будут перемещаться через системный ресамплер.

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

  7. Используйте векторные инструкции, такие как NEON, SSE или что-то еще, что эквивалентный набор инструкций находится на вашем целевом процессоре.

  8. Протестируйте и измерьте код. Отслеживайте, сколько времени требуется для запуска, и помните, что вам нужно знать производительность наихудшего случая, а не среднее, потому что худший случай - это то, что вызывает глюки. И быть консервативным. Вы уже знаете, что если для воспроизведения вашего аудио требуется больше времени, чем для его воспроизведения, вы никогда не получите низкой латентности. Но на Android это еще более важно, потому что частота процессора колеблется так сильно.Вы можете использовать, возможно, 60-70% процессора для аудио, но имейте в виду, что это изменится по мере того, как устройство станет более горячим или более холодным, или когда начнутся и прекратятся радиоприемники Wi-Fi или LTE и т. Д. не

с низкой задержкой звука больше не является новой функцией для Android, но она по-прежнему требует изменений конкретного устройства в аппаратных средствах, драйверы ядра и рамки стащить. Это означает, что существует много вариаций в латентности, которые вы можете ожидать от разных устройств, и учитывая, сколько разных телефонов с ценами Android продается, вероятно, всегда будут различия. Найдите FEATURE_AUDIO_PRO или FEATURE_AUDIO_LOW_LATENCY, чтобы идентифицировать устройства, соответствующие критериям латентности, которые требуется вашему приложению.

+0

Пункт 5. Если исходный аудиосигнал записан с номером 44100, а PROPERTY_OUTPUT_SAMPLE_RATE - 48000, тогда звук будет воспроизводиться слишком быстро. Каков наилучший способ обойти это? – Ian1971

+0

Ian, я считаю, что PROPERTY_OUTPUT_SAMPLE_RATE (POSR) относится к исходной частоте дискретизации звукового процессора вашего устройства. Это означает, что если вы подаете аудиосигнал на частоте 48 кГц, а POSR вашего устройства составляет 48 кГц, тогда системе не придется выполнять какую-либо «дополнительную работу», и поэтому ее можно воспроизводить без дополнительной задержки. – rmigneco

+0

Давая звук, отснятый с частотой 44,1 кГц, не означает, что он будет воспроизводиться с разной скоростью, но вам нужно, чтобы ОС/устройство выполнило дополнительный шаг повторной выборки для обработки звука на частоте 48 кГц, что добавляет задержки. – rmigneco

3

Из ссылки в вашем пункте 1:

». С низкой задержкой аудио

Android 4.2 улучшает поддержку низкой латентностью аудио воспроизведения, начиная с из улучшений, сделанных в версии Android 4.1 для аудиовыхода задержка с использованием API OpenSL ES, Soundpool и тонального генератора.Эти улучшений зависят от аппаратной поддержки - устройства, которые предлагают эти с малой задержкой функции аудио может рекламировать свою поддержку приложений через постоянную функции аппаратной «

Ваша цитата в полной форме:

. «Производительность

Поскольку OpenSL ES является родным C API, приложениями, не связанными с Dalvik, которые называют OpenSL ES, не имеют связанных с Dalvik служебных данных, таких как мусор coll ection паузы. Однако нет дополнительного преимущества в производительности для использования OpenSL ES, кроме этого. В частности, использование OpenSL ES не приводит к более низкой задержке звука, более высокому приоритету планирования, и т. Д., Чем обычно предоставляет платформа. С другой стороны, как реализации Android платформы и конкретные устройства продолжают Evolve, приложение OpenSL ES может рассчитывать на выгоду от любого будущих улучшения производительности системы.»

Итак, апите общается с водителями а затем hw - OpenSl (таким же образом Opengl делает с графикой). Ранние версии Android имеют плохой дизайн в драйверах и/или hw. Эти проблемы были устранены и исправлены с версиями 4.1 и 4.2, поэтому, если hd у вас есть сила, вы получаете низкую задержку с помощью OpenSL.

Опять же, из этой заметки на веб-сайте библиотеки puredata очевидно, что lib окон- чательно использует сам OpenSL для достижения низкой латентности:

Низкой поддержки задержки для устройств, совместимых с последней версией Pd для Android (от 12/28/2012) поддерживает с низким уровнем задержки звука для совместимых Android устройств. При обновлении своей копии обязательно потяните последнюю версию версии как pd-for-android, так и подмодуля libpd от GitHub.

На момент написания настоящего документа Galaxy Nexus, Nexus 4 и Nexus 10 обеспечили низкочастотную дорожку для аудиовыхода. Чтобы попасть в дорожку с низкой задержкой , приложение должно использовать OpenSL, и оно должно работать с правильной частотой выборки и размером буфера . Эти параметры зависят от устройства (Galaxy Nexus и Nexus 10 работают на частоте 44100 Гц, а Nexus 4 работает с на частоте 48000 Гц, размер буфера различается для каждого устройства).

Как его привычка, Pd для Android работ над всеми этими сложностями как , насколько это возможно, предоставляя доступ к новым возможностям низкой латентности при наличии оставаясь при этом обратно совместимым с более ранними версиями Android. Под капотом звуковые компоненты Pd для Android будут использовать OpenSL на Android 2.3 и более поздних версиях, а назад - на старый AudioTrack/AudioRecord API в Java на Android 2.2 и раньше.

5

При использовании OpenSL ES вы должны выполнить следующие требования, чтобы получить низкую производительность задержки на Jellybean и более поздних версиях Android:

  • аудио должно быть моно или стерео линейный PCM.

  • аудио частота дискретизации должна быть такой же же частота дискретизации, как родная скорость выходной (это не может быть фактически требуется на некоторых устройствах, потому что FastMixerявляется способен передискретизацией, если поставщик настраивает это сделать так. Но в моих тестах я получил очень заметные артефакты при повышении частоты дискретизации от 44,1 до 48 кГц в FastMixer).

  • Ваш BufferQueue должен иметь не менее 2 буферов. (Это требование с тех пор было расслабленным. См. this commit от Glenn Kasten. Я не уверен, в какой версии Android это впервые появилось, но догадка будет 4.4).

  • Вы не можете использовать определенные эффекты (например, реверберацию, усиление НЧ, выравнивание, виртуализацию, ...).

SoundPool класс также будет пытаться использовать быстрые AudioTrack с внутренне, когда это возможно (одни и те же критерии, что и выше применяются для BufferQueue части).

2

Те из вас, кто больше в 10-миллисекундной проблеме Android, т. е. звук с низкой задержкой на Android. Мы в Superpowered создали объяснение задержки аудиодорожки Android. Пожалуйста, смотрите здесь:

http://superpowered.com/androidaudiopathlatency/#axzz3fDHsEe56

+1

Это хорошее объяснение, но не на 100% до настоящего времени. Буферизация AudioFlinger была уменьшена в L, удалив в общей сложности два буфера из пути. В настоящее время существует один эффективный буфер задержки между приложением и HAL (он выглядит больше, но часть кода является синхронной - больше memcpys не всегда означает большую задержку.) Кроме того, не уверен, где 6 мс «задержка шины», рисунок идет от. Это кажется слишком высоким. –

+0

Привет, Иан, Надеюсь, вы в порядке. У нас есть недавно обновленная версия: http://superpowered.com/android-marshmallow-latency –

+1

Это выглядит примерно правильно. Единственное, чего не хватает, это Nexus 9 DSP - он называется AHUB в теге Tegra K1. Я бы предположил, что в FIFO учтены дополнительные задержки после программного обеспечения, чем у шины. Я думаю, вы также можете игнорировать тот факт, что вызов записи HAL блокируется. Вызов не возвращается, пока не произойдет следующее прерывание, поэтому весь движок запланирован на основе прерывания звука, а не на монотонном планировщике скорости. Есть некоторые серьезные проблемы с этим, многие из которых уникальны для Linux-ориентированных ОС, но я не думаю, что одним из них является модель «push». –