Чтобы уменьшить задержку аудио, поставщики могут реализовать две ключевые функции:
- 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(). В настоящее время это делают только следующие клиенты:
- Встроенный аудиопроигрыватель Android на основе OpenSL ES или AAudio
android.media.SoundPoolandroid.media.ToneGenerator
Реализация 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 – это концепция "клиент – сервер".