Дизайн для уменьшения задержки

Поставщики могут реализовать две ключевые функции для уменьшения задержки звука:

  • FAST Mixer в AudioFlinger: эта функция, представленная в Android 4.1, поддерживает приложения, использующие Java AudioTrack и AAudio. FAST Mixer требует минимальных изменений в API публичного клиента или HAL API.
  • AAudio MMAP: эта функция, представленная в Android 8.1, позволяет нативным приложениям добиться ещё меньшей задержки благодаря AAudio. Подробнее см. в разделе AAudio и MMAP .

На этой странице описывается первоначальная схема задержки звука, которая со временем продолжала развиваться. Чёткое понимание этой схемы крайне важно для производителей оригинального оборудования (OEM) и поставщиков систем на кристалле (SoC) для обеспечения корректной реализации на своих устройствах и чипсетах. Эта страница не предназначена для разработчиков приложений.

Создание трека

Клиент может опционально установить бит AUDIO_OUTPUT_FLAG_FAST в параметре audio_output_flags_t конструктора AudioTrack C++ или AudioTrack::set() . В настоящее время это делают только следующие клиенты:

Реализация AudioTrack на C++ проверяет запрос AUDIO_OUTPUT_FLAG_FAST и может при необходимости отклонить его на уровне клиента. Если она решает передать запрос дальше, это делается с использованием бита TRACK_FAST параметра track_flags_t фабричного метода IAudioTrack IAudioFlinger::createTrack() .

Аудиосервер AudioFlinger проверяет запрос TRACK_FAST и может при необходимости отклонить его на уровне сервера. Он сообщает клиенту, был ли запрос принят, посредством бита CBLK_FAST блока управления общей памятью.

Факторы, влияющие на решение, включают в себя:

  • Наличие потока быстрого микшера для этого выхода (см. ниже)
  • Частота дискретизации трека
  • Наличие клиентского потока для выполнения обработчиков обратных вызовов для этого трека
  • Размер буфера трека
  • Доступные слоты для ускоренного прохождения (см. ниже)

Если запрос клиента был принят, это называется ускоренным рассмотрением . В противном случае это называется обычным рассмотрением .

Смесительные нити

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

Быстрый миксер

Функции

Быстрый поток микшера обеспечивает следующие возможности:

  • Сведение субмикса обычного микшера и до семи клиентских быстрых треков
  • Затухание на дорожку

Пропущенные особенности:

  • Преобразование частоты дискретизации для каждой дорожки
  • Эффекты для каждого трека
  • Эффекты для каждого микса

Период

Быстрый микшер запускается периодически с рекомендуемым периодом 2–3 миллисекунды или чуть более длительным периодом 5 мс, если это необходимо для стабильности планирования. Это значение было выбрано таким образом, чтобы с учётом всего буферного конвейера общая задержка составляла порядка 10 мс. Возможны и меньшие значения, но они могут привести к повышенному энергопотреблению и вероятности сбоев в зависимости от предсказуемости планирования ЦП. Возможны и большие значения, до 20 мс, но они приводят к ухудшению общей задержки, поэтому их следует избегать.

Планирование

Быстрый микшер работает с повышенным приоритетом SCHED_FIFO . Он потребляет очень мало процессорного времени, но должен запускаться часто и с низким джиттером планирования. Джиттер выражает изменение времени цикла: это разница между фактическим и ожидаемым временем цикла. Слишком поздний запуск приводит к сбоям из-за недогрузки. Слишком ранний запуск приводит к сбоям из-за загрузки данных с быстрого трека до того, как трек предоставит данные.

Блокирование

В идеале поток быстрого микшера никогда не блокируется, за исключением HAL write() . Другие случаи блокировки в быстром микшере считаются ошибками. В частности, избегаются мьютексы. Вместо этого используются неблокирующие алгоритмы (также известные как алгоритмы без блокировок). Подробнее об этом см. в разделе «Избегание инверсии приоритетов» .

Связь с другими компонентами

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

Быстрый микшер получает команды от обычного микшера через очередь состояний.

За исключением сбора данных о треках, взаимодействие с клиентами осуществляется через обычный микшер.

Основным приемникем быстрого микшера является аудио HAL.

Обычный миксер

Функции

Все функции включены:

  • До 32 треков
  • Затухание на дорожку
  • Преобразование частоты дискретизации для каждой дорожки
  • Обработка эффектов

Период

Период вычисляется как первое целое кратное периода быстрого миксера, который >= 20 мс.

Планирование

Обычный микшер работает с повышенным приоритетом SCHED_OTHER .

Блокирование

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

Связь с другими компонентами

Обычный микшер активно взаимодействует с внешним миром, включая потоки связующего устройства, менеджер аудиополитик, поток быстрого микшера и клиентские треки.

Раковина обычного миксера является блокирующей трубой для трека 0 быстрого миксера.

Флаги

Бит AUDIO_OUTPUT_FLAG_FAST — это подсказка. Нет гарантии, что запрос будет выполнен.

AUDIO_OUTPUT_FLAG_FAST — это концепция клиентского уровня. Она не отображается на сервере.

TRACK_FAST — это концепция клиент -> сервер.