Как создавать приложения с низкой задержкой

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

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

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

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

Клиент может установить бит 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 блока управления общей памятью.

На решение влияют следующие факторы:

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

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

Цепочки Mixer

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

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

Функции

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

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

Недоступные функции:

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

Период

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

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

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

Блокировка

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

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

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

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

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

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

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

Функции

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

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

Период

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

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

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

Блокировка

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

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

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

Обычный микшер блокирует канал 0 быстрого микшера.

Флаги

AUDIO_OUTPUT_FLAG_FAST – подсказка. Мы не гарантируем, что запрос будет выполнен.

AUDIO_OUTPUT_FLAG_FAST – это концепция на уровне клиента. Она не появляется на сервере.

TRACK_FAST – это концепция "клиент – сервер".