В выпуске Android 4.1 были внесены изменения внутренней структуры для более низкой задержки вывода звука. Были внесены минимальные изменения в общедоступный клиентский API или HAL API. В этом документе описывается первоначальный проект, который со временем продолжал развиваться. Хорошее понимание этого дизайна должно помочь OEM-производителям устройств и поставщикам SoC правильно реализовать дизайн на своих конкретных устройствах и наборах микросхем. Эта статья не предназначена для разработчиков приложений.
Создание трека
Клиент может дополнительно установить бит AUDIO_OUTPUT_FLAG_FAST
в параметре audio_output_flags_t
конструктора AudioTrack C++ или AudioTrack::set()
. В настоящее время единственными клиентами, которые делают это, являются:
- Собственный звук Android на основе OpenSL ES или AAudio
- android.media.SoundPool
- android.media.ToneGenerator
Реализация AudioTrack C++ проверяет запрос AUDIO_OUTPUT_FLAG_FAST
и может при необходимости отклонить запрос на уровне клиента. Если он решает передать запрос, он делает это, используя бит TRACK_FAST
параметра track_flags_t
фабричного метода IAudioTrack
IAudioFlinger::createTrack()
.
Аудиосервер AudioFlinger просматривает запрос TRACK_FAST
и может дополнительно отклонить запрос на уровне сервера. Он информирует клиента о том, был ли запрос принят, через бит CBLK_FAST
блока управления общей памятью.
К факторам, влияющим на решение, относятся:
- Наличие потока быстрого микшера для этого выхода (см. ниже)
- Отслеживание частоты дискретизации
- Наличие клиентского потока для выполнения обработчиков обратного вызова для этой дорожки
- Размер буфера отслеживания
- Доступные слоты быстрого доступа (см. ниже)
Если запрос клиента был принят, это называется «ускоренный путь». В противном случае это называется "обычный трек".
Смесительные потоки
Когда AudioFlinger создает обычный поток микшера, он решает, создавать ли также быстрый поток микшера. И обычный микшер, и быстрый микшер связаны не с конкретной дорожкой, а скорее с набором дорожек. Всегда есть нормальная резьба смесителя. Поток быстрого микшера, если он существует, подчиняется обычному потоку микшера и действует под его контролем.
Быстрый миксер
Функции
Поток быстрого микшера предоставляет следующие возможности:
- Микширование субмикса обычного микшера и до 7 клиентских быстрых дорожек
- Затухание на дорожке
Пропущенные функции:
- Преобразование частоты дискретизации для каждой дорожки
- Эффекты для каждой дорожки
- Эффекты микса
Период
Быстрый микшер запускается периодически с рекомендуемым периодом от двух до трех миллисекунд (мс) или немного большим периодом в пять мс, если это необходимо для стабильности расписания. Это число было выбрано таким образом, чтобы с учетом всего буферного конвейера общая задержка составляла порядка 10 мс. Возможны меньшие значения, но это может привести к увеличению энергопотребления и вероятности сбоев в зависимости от предсказуемости планирования ЦП. Возможны и большие значения, вплоть до 20 мс, но это приводит к ухудшению общей задержки, поэтому их следует избегать.
Планирование
Быстрый микшер работает с повышенным приоритетом SCHED_FIFO
. Ему требуется очень мало процессорного времени, но он должен выполняться часто и с низким дрожанием планирования. Джиттер выражает изменение времени цикла: это разница между фактическим временем цикла и ожидаемым временем цикла. Запуск слишком поздно приведет к сбоям из-за опустошения. Слишком ранний запуск приведет к сбоям из-за извлечения из ускоренной дорожки до того, как дорожка предоставит данные.
Блокировка
В идеале поток быстрого микшера никогда не блокируется, кроме HAL write()
. Другие случаи блокировки в быстром микшере считаются ошибками. В частности, избегаются мьютексы. Вместо этого используются неблокирующие алгоритмы (также известные как алгоритмы без блокировки). Дополнительную информацию по этой теме см. в разделе Избегание инверсии приоритетов .
Связь с другими компонентами
Быстрый миксер мало взаимодействует с клиентами напрямую. В частности, он не видит операций на уровне компоновщика, но имеет доступ к блоку управления общей памятью клиента.
Быстрый микшер получает команды от обычного микшера через очередь состояний.
Помимо извлечения данных дорожки, взаимодействие с клиентами осуществляется через обычный микшер.
Основным приемником быстрого микшера является аудио HAL.
Обычный микшер
Функции
Все функции включены:
- До 32 дорожек
- Затухание на дорожке
- Преобразование частоты дискретизации для каждой дорожки
- Обработка эффектов
Период
Период вычисляется как первое целое кратное периода быстрого смесителя, который составляет >= 20 мс.
Планирование
Обычный микшер работает с повышенным приоритетом SCHED_OTHER
.
Блокировка
Обычному микшеру разрешено блокировать, и он часто делает это в различных мьютексах, а также в блокирующем канале для записи своего субмикса.
Связь с другими компонентами
Обычный микшер интенсивно взаимодействует с внешним миром, включая потоки связывания, диспетчер политики аудио, поток быстрого микшера и клиентские дорожки.
Приемник обычного микшера — это блокирующая труба, ведущая к дорожке 0 быстрого микшера.
Флаги
AUDIO_OUTPUT_FLAG_FAST
— это подсказка. Нет никакой гарантии, что запрос будет выполнен.
AUDIO_OUTPUT_FLAG_FAST
— это концепция уровня клиента. Он не появляется на сервере.
TRACK_FAST
— это концепция клиент -> сервер.