Projetar para reduzir a latência

Os fornecedores podem implementar dois recursos principais para reduzir a latência de áudio:

  • Mixer FAST no AudioFlinger:introduzido no Android 4.1, esse recurso é compatível com apps que usam Java AudioTrack e AAudio. O FAST Mixer envolve mudanças mínimas na API pública do cliente ou na API HAL.
  • MMAP do AAudio:introduzido no Android 8.1, esse recurso permite que apps nativos alcancem uma latência ainda menor com o AAudio. Consulte AAudio e MMAP para mais informações.

Nesta página, descrevemos o design inicial da latência de áudio, que evoluiu ao longo do tempo. É fundamental que os OEMs de dispositivos e os fornecedores de SoC entendam bem esse design para garantir a implementação correta nos dispositivos e chipsets específicos. Esta página não é destinada a desenvolvedores de apps.

Criação de faixa

O cliente pode definir opcionalmente o bit AUDIO_OUTPUT_FLAG_FAST no parâmetro audio_output_flags_t do construtor AudioTrack C++ ou AudioTrack::set(). No momento, os únicos clientes que fazem isso são:

A implementação em C++ do AudioTrack analisa a solicitação AUDIO_OUTPUT_FLAG_FAST e pode negar o pedido no nível do cliente. Se ele decidir encaminhar a solicitação, fará isso 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 analisa a solicitação TRACK_FAST e pode negar a solicitação no nível do servidor. Ele informa ao cliente se a solicitação foi aceita ou não, usando o bit CBLK_FAST do bloco de controle de memória compartilhada.

Os fatores que afetam a decisão incluem:

  • Presença de uma thread de mixer rápido para essa saída (veja abaixo)
  • Taxa de amostragem de rastreamento
  • Presença de uma linha de execução do cliente para executar gerenciadores de callback para essa faixa.
  • Tamanho do buffer de rastreamento
  • Vagas disponíveis para o programa de aceleração (confira abaixo)

Se o pedido do cliente for aceito, ele será chamado de fast track. Caso contrário, ela é chamada de faixa normal.

Linhas de execução do Mixer

Quando o AudioFlinger cria uma linha de execução de mixer normal, ele decide se também vai criar uma linha de execução de mixer rápida. O mixer normal e o rápido não estão associados a uma faixa específica, mas a um conjunto delas. Sempre há uma encadeamento normal do mixer. A thread do mixer rápido, se existir, é subordinada à thread do mixer normal e age sob o controle dela.

Mixer rápido

Recursos

A linha de execução do mixer rápido oferece estes recursos:

  • Mixagem da submixagem do mixer normal e até sete faixas rápidas do cliente
  • Atenuação por faixa

Recursos omitidos:

  • Conversão da taxa de amostragem por faixa
  • Efeitos por faixa
  • Por efeitos de mixagem

Período

O mixer rápido é executado periodicamente, com um período recomendado de dois a três milissegundos ou um período um pouco maior de 5 ms, se necessário para estabilidade de programação. Esse número foi escolhido para que, considerando o pipeline de buffer completo, 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.

Programação

O mixer rápido é executado com prioridade SCHED_FIFO elevada. Ele precisa de muito pouco tempo de CPU, mas precisa ser executado com frequência e com baixo jitter de programação. Jitter expressa a variação no tempo de ciclo: é a diferença entre o tempo de ciclo real e o tempo de ciclo esperado. Executar muito tarde resulta em falhas devido a subexecução. Executar muito cedo resulta em falhas devido à extração de uma faixa rápida antes que ela forneça dados.

Bloqueia o conteúdo

O ideal é que a linha de execução do mixer rápido nunca bloqueie, 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 Evitar inversão de prioridade para mais informações sobre esse tema.

Relação com outros componentes

O mixer rápido tem pouca interação direta com os clientes. Em particular, ele não vê 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 uma fila de estado.

Além de extrair dados de faixa, a interação com os clientes é feita pelo mixer normal.

O coletor principal do mixer rápido é a HAL de áudio.

Mixer normal

Recursos

Todos os recursos estão ativados:

  • Até 32 faixas
  • Atenuação por faixa
  • Conversão da taxa de amostragem por faixa
  • Processamento de efeitos

Período

O período é calculado como o primeiro múltiplo inteiro do período de mistura rápida que é >= 20 ms.

Programação

O mixer normal é executado com prioridade SCHED_OTHER elevada.

Bloqueia o conteúdo

O mixer normal pode bloquear e geralmente faz isso em vários mutexes, bem como em um pipe de bloqueio para gravar a submixagem.

Relação com outros componentes

O mixer normal interage muito com o mundo externo, incluindo encadeamentos de vinculação, gerenciador de políticas de áudio, encadeamento de mixer rápido e faixas de cliente.

O coletor do mixer normal é um pipe de bloqueio para a faixa 0 do mixer rápido.

Flags

AUDIO_OUTPUT_FLAG_FAST bit é uma dica. Não há garantia de que o pedido será atendido.

AUDIO_OUTPUT_FLAG_FAST é um conceito no nível do cliente. Ele não aparece no servidor.

TRACK_FAST é um conceito de cliente -> servidor.