O Android Automotive OS (AAOS) é baseado na pilha de áudio principal do Android para oferecer suporte aos casos de uso para operar como o sistema de infoentretenimento em um veículo. O AAOS é responsável pelos sons de infoentretenimento (mídia, navegação e comunicações), mas não é diretamente responsável por alertas e avisos que têm restrições rígidas de disponibilidade e tempo. Embora o AAOS forneça sinais e mecanismos para ajudar o veículo a gerenciar o áudio, no final, cabe ao veículo fazer a chamada sobre quais sons devem ser reproduzidos para o motorista e os passageiros, garantindo que os sons críticos de segurança e os sons regulamentares sejam ouvidos corretamente sem interrupção.
Como o Android gerencia a experiência de mídia do veículo, as fontes de mídia externas, como o sintonizador de rádio, precisam ser representadas por apps, que podem processar eventos de foco de áudio e teclas de mídia para a fonte.
O Android 11 inclui as seguintes mudanças no suporte a áudio relacionado a veículos:
- Seleção automática da zona de áudio com base no ID do usuário associado
- Novos usos do sistema para oferecer suporte a sons específicos de automóveis
- Suporte ao foco de áudio do HAL
- Foco de áudio atrasado para streams não temporários
- Configuração do usuário para controlar a interação entre navegação e chamadas
Sons e streams do Android
Os sistemas de áudio automotivo processam os seguintes sons e streams:
Figura 1. Diagrama da arquitetura com foco em fluxos
O Android gerencia os sons que vêm de apps Android, controlando esses apps e roteando os sons para dispositivos de saída no HAL com base no tipo de som:
- Os streams lógicos, conhecidos como origens na nomenclatura básica de áudio, são marcados com Atributos de áudio.
- Os fluxos físicos, conhecidos como dispositivos na nomenclatura de áudio principal, não têm informações de contexto após a mixagem.
Para confiabilidade, os sons externos (vindos de fontes independentes, como alertas de cinto de segurança) são gerenciados fora do Android, abaixo do HAL ou até mesmo em hardware separado. Os implementadores do sistema precisam fornecer um mixer que aceite um ou mais streams de entrada de som do Android e os combine de maneira adequada com as fontes de som externas exigidas pelo veículo.
A implementação do HAL e o mixer externo são responsáveis por garantir que os sons externos críticos à segurança sejam ouvidos e por misturar os fluxos fornecidos pelo Android e direcioná-los para alto-falantes adequados.
Sons do Android
Os apps podem ter um ou mais players que interagem com as APIs padrão do Android (por exemplo, AudioManager para controle de foco ou MediaPlayer para streaming) para emitir um ou mais fluxos lógicos de dados de áudio. Esses dados podem ser mono de canal único ou surround 7.1, mas são roteados e tratados como uma única fonte. O stream do app está associado a AudioAttributes, que dão dicas ao sistema sobre como o áudio deve ser expresso.
Os streams lógicos são enviados pelo AudioService e roteados para um (e apenas um) dos streams de saída física disponíveis, sendo que cada um deles é a saída de um mixer no AudioFlinger. Depois que os atributos de áudio são mixados em um stream físico, eles não estão mais disponíveis.
Cada stream físico é entregue à HAL de áudio para renderização no hardware. Em apps automotivos, o hardware de renderização pode ser codecs locais (semelhantes aos dispositivos móveis) ou um processador remoto na rede física do veículo. De qualquer forma, é função da implementação do HAL de áudio fornecer os dados de amostra reais e torná-los audíveis.
Fluxos externos
Os streams de som que não podem ser roteados pelo Android (por motivos de certificação ou de tempo) podem ser enviados diretamente para o mixer externo. A partir do Android 11, o HAL agora pode solicitar o foco para esses sons externos para informar o Android e permitir que ele tome as ações adequadas, como pausar a mídia ou impedir que outros ganhem o foco.
Se os streams externos forem fontes de mídia que precisam interagir com o ambiente de som que o Android está gerando (por exemplo, interromper a reprodução de MP3 quando um sintonizador externo estiver ativado), esses streams externos precisam ser representados por um app Android. Esse app solicitaria o foco de áudio em nome da fonte de mídia em vez do HAL e responderia às notificações de foco inicializando/interrompendo a fonte externa conforme necessário para se encaixar na política de foco do Android. O app também é responsável por processar eventos de tecla de mídia, como reprodução/pausa. Um mecanismo sugerido para controlar esses dispositivos externos é o HwAudioSource.
Dispositivo de saída
No nível da HAL de áudio, o tipo de dispositivo AUDIO_DEVICE_OUT_BUS
fornece um dispositivo de saída genérico para uso em sistemas de áudio de veículos. O dispositivo de barramento
oferece suporte a portas endereçáveis (em que cada porta é o ponto final de um
fluxo físico) e deve ser o único tipo de dispositivo de saída compatível em
um veículo.
Uma implementação do sistema pode usar uma porta de barramento para todos os sons do Android.
Nesse caso, o Android mistura tudo e entrega como um fluxo.
Como alternativa, a HAL pode fornecer uma porta de barramento para cada CarAudioContext
para permitir
a entrega simultânea de qualquer tipo de som. Isso permite que a implementação do HAL
misture e abaixe os diferentes sons conforme desejado.
A atribuição de contextos de áudio a dispositivos de saída é feita por
car_audio_configuration.xml
.
Entrada de microfone
Ao capturar áudio, o HAL de áudio recebe uma chamada openInputStream
que inclui um argumento AudioSource
indicando como a
entrada do microfone deve ser processada.
A fonte VOICE_RECOGNITION
(especificamente o Google Assistente) espera um stream de microfone estéreo que tenha
um efeito de cancelamento de eco (se disponível), mas nenhum outro processamento aplicado a ele.
O beamforming precisa ser feito pelo Google Assistente.
Entrada de microfone multicanal
Para capturar áudio de um dispositivo com mais de dois canais (estéreo), use uma
máscara de índice de canal em vez de uma máscara de índice posicional (como
CHANNEL_IN_LEFT
). Exemplo:
final AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setSampleRate(44100) .setChannelIndexMask(0xf /* 4 channels, 0..3 */) .build(); final AudioRecord audioRecord = new AudioRecord.Builder() .setAudioFormat(audioFormat) .build(); audioRecord.setPreferredDevice(someAudioDeviceInfo);
Quando setChannelMask
e setChannelIndexMask
são definidos, AudioRecord
usa apenas o valor definido por
setChannelMask
(máximo de dois canais).
Captura simultânea
A partir do Android 10, o framework do Android oferece suporte à captura simultânea
de entradas, mas com restrições para proteger a privacidade do usuário. Como parte
dessas restrições, fontes virtuais, como
AUDIO_SOURCE_FM_TUNER
, são ignoradas e podem ser
capturadas simultaneamente com uma entrada normal (como o microfone).
HwAudioSources
também não são considerados parte das restrições de captura
simultânea.
Os apps projetados para funcionar com dispositivos AUDIO_DEVICE_IN_BUS
ou
AUDIO_DEVICE_IN_FM_TUNER
secundários precisam identificar
explicitamente esses dispositivos e usar AudioRecord.setPreferredDevice()
para ignorar a lógica de seleção de fonte padrão do Android.
Usos de áudio
O AAOS usa principalmente
AudioAttributes.AttributeUsages
para roteamento, ajustes de volume e gerenciamento de foco. Os usos são uma
representação do "porquê" a transmissão está sendo reproduzida. Portanto, todos os streams
e solicitações de foco de áudio precisam especificar um uso para a reprodução de áudio. Quando
não for definido especificamente ao criar um objeto AudioAttributes, o uso será
padrão para USAGE_UNKNOWN
. Embora esse comportamento seja tratado da mesma forma
que USAGE_MEDIA
, não é recomendável confiar nele para a reprodução
de mídia.
Usos do sistema
No Android 11, os usos do sistema foram introduzidos. Esses usos se comportam
de maneira semelhante aos usos estabelecidos anteriormente, exceto que eles exigem APIs do sistema
para uso, além de android.permission.MODIFY_AUDIO_ROUTING
. Os novos
usos do sistema são:
USAGE_EMERGENCY
USAGE_SAFETY
USAGE_VEHICLE_STATUS
USAGE_ANNOUNCEMENT
Para criar uma AudioAttributes
com um uso do sistema, use
AudioAttributes.Builder#setSystemUsage
em vez de setUsage
. Chamar esse método com um uso que não seja do sistema
resultará na geração de uma IllegalArgumentException
. Além disso, se
o uso do sistema e o uso forem definidos em um builder, ele vai gerar uma
IllegalArgumentException
durante a criação.
Para verificar qual uso está associado a uma instância
AudioAttributes
, chame AudioAttributes#getSystemUsage
.
Isso retorna o uso ou o uso do sistema associado.
Contextos de áudio
Para simplificar a configuração do áudio do AAOS, usos semelhantes foram agrupados
em CarAudioContext
. Esses contextos de áudio são usados em
CarAudioService
para definir roteamento, grupos de volume e gerenciamento de foco
de áudio.
Os contextos de áudio no Android 11 são:
CarAudioContext | Usos de atributos associados |
---|---|
MUSIC |
UNKNOWN, GAME, MEDIA |
NAVIGATION |
ASSISTANCE_NAVIGATION_GUIDANCE |
VOICE_COMMAND |
ASSISTANT, ASSISTANCE_ACCESSIBILITY |
CALL_RING |
NOTIFICATION_RINGTONE |
CALL |
VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING |
ALARM |
ALARM |
NOTIFICATION |
NOTIFICATION, NOTIFICATION_* |
SYSTEM_SOUND |
ASSISTANCE_SONIFICATION |
EMERGENCY |
EMERGENCY |
SAFETY |
SAFETY |
VEHICLE_STATUS |
VEHICLE_STATUS |
ANNOUNCEMENT |
ANNOUNCEMENT |
Mapeamento entre contextos e usos de áudio. As linhas destacadas são para novos usos do sistema.
Áudio multizona
Com o setor automotivo, há um novo conjunto de casos de uso relacionados a usuários simultâneos que interagem com a plataforma e procuram consumir mídias separadas. Por exemplo, um motorista pode tocar música no carro enquanto os passageiros no banco de trás assistem um vídeo do YouTube na tela traseira. O áudio de várias zonas permite que diferentes fontes de áudio sejam reproduzidas simultaneamente em diferentes áreas do veículo.
O áudio de várias zonas, a partir do Android 10, permite que os OEMs configurem o áudio em zonas separadas. Cada zona é uma coleção de dispositivos no veículo com grupos de volume, configuração de roteamento para contextos e gerenciamento de foco. Dessa forma, a cabine principal pode ser configurada como uma zona de áudio, enquanto as entradas de fone de ouvido da tela traseira são configuradas como uma segunda zona.
As zonas são definidas como parte de car_audio_configuration.xml
.
O CarAudioService
lê a configuração e ajuda o AudioService
a rotear streams de áudio com base na zona associada. Cada zona ainda define
regras para roteamento com base em contextos e no uid dos aplicativos. Quando um player é
criado, CarAudioService
determina a qual zona o player está
associado e, com base no uso, para qual dispositivo o AudioFlinger
precisa encaminhar o áudio.
O foco também é mantido de forma independente para cada zona de áudio. Isso permite que
aplicativos em diferentes zonas produzam áudio de forma independente sem
interferirem uns nos outros, enquanto os aplicativos ainda respeitam as mudanças no
foco dentro da zona. O CarZonesAudioFocus
em
CarAudioService
é responsável por gerenciar o foco de cada
zona.
Figura 2. Configurar áudio de várias zonas
HAL de áudio
As implementações de áudio automotivo dependem do HAL de áudio padrão do Android, que inclui o seguinte:
IDevice.hal
: cria streams de entrada e saída, gerencia o volume principal e o silenciamento e usa:createAudioPatch
: para criar patches externos entre dispositivos.IDevice.setAudioPortConfig()
para fornecer volume para cada stream físico.
IStream.hal
. Junto com as variantes de entrada e saída, gerencia o streaming de amostras de áudio para e do hardware.
Tipos de dispositivos automotivos
Os tipos de dispositivo a seguir são relevantes para plataformas automotivas.
Tipo de dispositivo | Descrição |
---|---|
AUDIO_DEVICE_OUT_BUS |
Saída principal do Android (é assim que todo o áudio do Android é enviado para o veículo). Usado como o endereço para desambiguação de fluxos para cada contexto. |
AUDIO_DEVICE_OUT_TELEPHONY_TX |
Usado para áudio roteado para a rede celular para transmissão. |
AUDIO_DEVICE_IN_BUS |
Usado para entradas não classificadas de outra forma. |
AUDIO_DEVICE_IN_FM_TUNER |
Usado apenas para entrada de rádio de transmissão. |
AUDIO_DEVICE_IN_TV_TUNER |
Usado para um dispositivo de TV, se presente. |
AUDIO_DEVICE_IN_LINE |
Usado para a entrada auxiliar. |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
Música recebida por Bluetooth. |
AUDIO_DEVICE_IN_TELEPHONY_RX |
Usado para áudio recebido do rádio celular associado a uma chamada telefônica. |
Como configurar dispositivos de áudio
Os dispositivos de áudio visíveis para o Android precisam ser definidos em
/audio_policy_configuration.xml
, que inclui os seguintes componentes:
- nome do módulo. Oferece suporte a "primary" (usado para casos de uso automotivos),
"A2DP", "remote_submix" e "USB". O nome do módulo e o driver de áudio
correspondente precisam ser compilados para
audio.primary.$(variant).so
. - devicePorts. Contém uma lista de descritores de dispositivo para todos os dispositivos de entrada e saída (incluindo dispositivos permanentemente conectados e removíveis) que podem ser acessados neste módulo.
- Para cada dispositivo de saída, é possível definir o controle de ganho que consiste em valores mínimo/máximo/padrão/de etapa em millibel (1 millibel = 1/100 dB = 1/1000 bel).
- O atributo de endereço em uma instância de devicePort pode ser usado para encontrar o
dispositivo, mesmo que haja vários dispositivos com o mesmo tipo de dispositivo que
AUDIO_DEVICE_OUT_BUS
. - mixPorts. Contém uma lista de todos os streams de entrada e saída expostos pelo HAL de áudio. Cada instância de mixPort pode ser considerada como um stream físico para o Android AudioService.
- rotas. Define uma lista de possíveis conexões entre dispositivos de entrada e saída ou entre o stream e o dispositivo.
O exemplo a seguir define um bus0_phone_out de dispositivo de saída em que todos
os streams de áudio do Android são mixados por mixer_bus0_phone_out. A rota leva o
fluxo de saída de mixer_bus0_phone_out
para o dispositivo
bus0_phone_out
.
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>bus0_phone_out</item> <defaultOutputDevice>bus0_phone_out</defaultOutputDevice> <mixPorts> <mixPort name="mixport_bus0_phone_out" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="bus0_phone_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="BUS00_PHONE"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-8400" maxValueMB="4000" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort> </devicePorts> <routes> <route type="mix" sink="bus0_phone_out" sources="mixport_bus0_phone_out"/> </routes> </module> </modules> </audioPolicyConfiguration>