A versão Android 4.1 introduziu alterações internas na estrutura para um caminho de saída de áudio de menor latência . Houve alterações mínimas na API do cliente público ou na API HAL. Este documento descreve o projeto inicial, que continuou a evoluir ao longo do tempo. Ter uma boa compreensão desse design deve ajudar os fornecedores de OEM e SoC de dispositivos a implementar o design corretamente em seus dispositivos e chipsets específicos. Este artigo não se destina a desenvolvedores de aplicativos.
Criação de faixas
O cliente pode opcionalmente definir o bit AUDIO_OUTPUT_FLAG_FAST
no parâmetro audio_output_flags_t
do construtor AudioTrack C++ ou AudioTrack::set()
. Atualmente, os únicos clientes que fazem isso são:
- Áudio nativo do Android baseado em OpenSL ES ou AAudio
- android.media.SoundPool
- android.media.ToneGenerator
A implementação AudioTrack C++ revisa a solicitação AUDIO_OUTPUT_FLAG_FAST
e pode, opcionalmente, negar a solicitação no nível do cliente. Se decidir passar a solicitação, ele o faz usando o bit TRACK_FAST
do parâmetro track_flags_t
do método de fábrica IAudioTrack
IAudioFlinger::createTrack()
.
O servidor de áudio AudioFlinger revisa a solicitação TRACK_FAST
e pode, opcionalmente, negar a solicitação no nível do servidor. Informa ao cliente se a requisição foi ou não aceita, via bit CBLK_FAST
do bloco de controle de memória compartilhada.
Os fatores que afetam a decisão incluem:
- Presença de um thread de mixer rápido para esta saída (veja abaixo)
- Rastrear taxa de amostragem
- Presença de um segmento de cliente para executar manipuladores de retorno de chamada para esta faixa
- Rastrear tamanho do buffer
- Slots de acesso rápido disponíveis (veja abaixo)
Se a solicitação do cliente foi aceita, ela é chamada de "via rápida". Caso contrário, é chamado de "pista normal".
Roscas do misturador
No momento em que o AudioFlinger cria um thread de mixer normal, ele decide se deseja ou não criar também um thread de mixer rápido. Tanto o mixer normal quanto o mixer rápido não estão associados a uma faixa específica, mas sim a um conjunto de faixas. Há sempre um thread de misturador normal. O encadeamento rápido do mixer, se existir, é subserviente ao encadeamento do mixer normal e atua sob seu controle.
Misturador rápido
Características
A rosca do misturador rápido fornece esses recursos:
- Mixagem do submix do mixer normal e até 7 faixas rápidas do cliente
- Atenuação por faixa
Recursos omitidos:
- Conversão de taxa de amostragem por faixa
- Efeitos por faixa
- Por efeitos de mixagem
Período
O misturador rápido é executado periodicamente, com um período recomendado de dois a três milissegundos (ms), ou um período ligeiramente superior de cinco ms, se necessário para estabilidade de agendamento. Esse número foi escolhido para que, contabilizando o pipeline completo do buffer, a latência total seja da ordem de 10 ms. Valores menores são possíveis, mas podem resultar em maior consumo de energia e chance de falhas, dependendo da previsibilidade do agendamento da CPU. Valores maiores são possíveis, até 20 ms, mas resultam em latência total degradada e, portanto, devem ser evitados.
Agendamento
O mixer rápido é executado com prioridade SCHED_FIFO
elevada. Ele precisa de muito pouco tempo de CPU, mas deve ser executado com frequência e com baixo jitter de agendamento. Jitter expressa a variação no tempo de ciclo: é a diferença entre o tempo de ciclo real versus o tempo de ciclo esperado. Correr muito tarde resultará em falhas devido ao underrun. Correr muito cedo resultará em falhas devido à retirada de uma pista rápida antes que a pista forneça dados.
Bloqueio
Idealmente, o encadeamento rápido do mixer nunca bloqueia, exceto em HAL write()
. Outras ocorrências de bloqueio no mixer rápido são consideradas bugs. Em particular, os mutexes são evitados. Em vez disso, são usados algoritmos sem bloqueio (também conhecidos como algoritmos sem bloqueio). Consulte Evitando a inversão de prioridade para obter mais informações sobre este tópico.
Relação com outros componentes
O mixer rápido tem pouca interação direta com os clientes. Em particular, ele não vê as operações no nível do binder, mas acessa o bloco de controle de memória compartilhada do cliente.
O mixer rápido recebe comandos do mixer normal por meio de uma fila de estado.
Além de puxar os dados da faixa, a interação com os clientes é feita através do mixer normal.
O coletor principal do mixer rápido é o HAL de áudio.
Misturador normal
Características
Todos os recursos estão ativados:
- Até 32 faixas
- Atenuação por faixa
- Conversão de taxa de amostragem por faixa
- Processamento de efeitos
Período
O período é calculado para ser o primeiro múltiplo integral do período do misturador rápido que é >= 20 ms.
Agendamento
O mixer normal é executado com prioridade SCHED_OTHER
elevada.
Bloqueio
O mixer normal tem permissão para bloquear, e geralmente o faz em vários mutexes, bem como em um canal de bloqueio para gravar sua submixagem.
Relação com outros componentes
O mixer normal interage amplamente com o mundo externo, incluindo threads de binder, gerenciador de política de áudio, thread de mixer rápido e faixas de cliente.
A pia do mixer normal é um tubo de bloqueio para a faixa 0 do mixer rápido.
Bandeiras
O bit AUDIO_OUTPUT_FLAG_FAST
é uma dica. Não há garantia de que o pedido será atendido.
AUDIO_OUTPUT_FLAG_FAST
é um conceito de nível de cliente. Não aparece no servidor.
TRACK_FAST
é um conceito de cliente -> servidor.