В выпуске 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
— это концепция клиент -> сервер.