O Android Automotive OS (AAOS) baseia-se na pilha de áudio principal do Android para oferecer suporte aos casos de uso para operar como sistema de infoentretenimento em um veículo. AAOS é responsável pelos sons de infoentretenimento (ou seja, mídia, navegação e comunicações), mas não é diretamente responsável por sinos e avisos que tenham requisitos rígidos 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 tomar a decisão sobre quais sons devem ser reproduzidos para o motorista e passageiros, garantindo que sons críticos de segurança e sons regulatórios sejam ouvidos adequadamente sem interrupção.
À medida que o Android gerencia a experiência de mídia do veículo, as fontes de mídia externas, como o sintonizador de rádio, devem ser representadas por aplicativos, que podem lidar com o foco de áudio e os principais eventos de mídia da fonte.
O Android 11 inclui as seguintes alterações no suporte de áudio automotivo:
- Seleção automática de zona de áudio com base no ID de usuário associado
- Novos usos do sistema para suportar sons específicos do setor automotivo
- Suporte para foco de áudio HAL
- Foco de áudio atrasado para streams não transitó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 automotivos lidam com os seguintes sons e fluxos:
Figura 1. Diagrama de arquitetura centrada em fluxo
O Android gerencia os sons provenientes de aplicativos Android, controlando esses aplicativos e roteando seus sons para dispositivos de saída no HAL com base no tipo de som:
- Os fluxos lógicos , conhecidos como fontes na nomenclatura principal de áudio, são marcados com atributos de áudio .
- Fluxos físicos , conhecidos como dispositivos na nomenclatura central de áudio, não possuem informações de contexto após a mixagem.
Para maior confiabilidade, sons externos (provenientes de fontes independentes, como avisos sonoros de cintos de segurança) são gerenciados fora do Android, abaixo do HAL ou até mesmo em hardware separado. Os implementadores do sistema devem fornecer um mixer que aceite um ou mais fluxos de entrada de som do Android e, em seguida, combine esses fluxos de maneira adequada com as fontes de som externas exigidas pelo veículo.
A implementação HAL e o mixer externo são responsáveis por garantir que os sons externos críticos para a segurança sejam ouvidos e por mixar os fluxos fornecidos pelo Android e encaminhá-los para alto-falantes adequados.
Sons do Android
Os aplicativos podem ter um ou mais players que interagem por meio de 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 fonte única. O fluxo do aplicativo está associado a AudioAttributes que fornecem dicas ao sistema sobre como o áudio deve ser expresso.
Os fluxos lógicos são enviados através do AudioService e roteados para um (e apenas um) dos fluxos de saída físicos disponíveis, cada um dos quais é a saída de um mixer dentro do AudioFlinger. Depois que os atributos de áudio forem mixados em um fluxo físico, eles não estarão mais disponíveis.
Cada fluxo físico é então entregue ao HAL de áudio para renderização no hardware. Em aplicativos 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 Audio HAL fornecer os dados de amostra reais e torná-los audíveis.
Fluxos externos
Os fluxos de som que não devem ser roteados pelo Android (por motivos de certificação ou tempo) podem ser enviados diretamente para o mixer externo. A partir do Android 11, o HAL agora é capaz de solicitar foco para esses sons externos para informar o Android de forma que ele possa tomar as ações apropriadas, como pausar a mídia ou impedir que outras pessoas obtenham foco.
Se os fluxos externos forem fontes de mídia que devem interagir com o ambiente sonoro que o Android está gerando (por exemplo, interromper a reprodução de MP3 quando um sintonizador externo estiver ligado), esses fluxos externos deverão ser representados por um aplicativo Android. Esse aplicativo solicitaria o foco de áudio em nome da fonte de mídia em vez do HAL e responderia às notificações de foco iniciando/interrompendo a fonte externa conforme necessário para se adequar à política de foco do Android. O aplicativo também é responsável por lidar com eventos importantes de mídia, como reproduzir/pausar. Um mecanismo sugerido para controlar tais dispositivos externos é HwAudioSource .
Dispositivos de saída
No nível de áudio HAL, 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 suporta portas endereçáveis (onde cada porta é o ponto final de um fluxo físico) e espera-se que seja o único tipo de dispositivo de saída suportado em um veículo.
Uma implementação de sistema pode usar uma porta de barramento para todos os sons do Android; nesse caso, o Android mistura tudo e entrega como um único fluxo. Alternativamente, o HAL pode fornecer uma porta de barramento para cada CarAudioContext
para permitir a entrega simultânea de qualquer tipo de som. Isto torna possível que a implementação HAL misture e reduza os diferentes sons conforme desejado.
A atribuição de contextos de áudio aos dispositivos de saída é feita através de car_audio_configuration.xml
.
Entrada de microfone
Ao capturar áudio, o Audio HAL 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 Assistant) espera um fluxo de microfone estéreo que tenha um efeito de cancelamento de eco (se disponível), mas nenhum outro processamento aplicado a ele. Espera-se que o Beamforming seja feito pelo 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, a estrutura do Android suporta a 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, como tal, podem ser capturadas simultaneamente junto com uma entrada normal (como o microfone). HwAudioSources
também não são considerados parte das restrições de captura simultânea.
Os aplicativos projetados para funcionar com dispositivos AUDIO_DEVICE_IN_BUS
ou com dispositivos AUDIO_DEVICE_IN_FM_TUNER
secundários devem depender da identificação explícita desses dispositivos e do uso de AudioRecord.setPreferredDevice()
para ignorar a lógica de seleção de fonte padrão do Android.
Usos de áudio
AAOS utiliza principalmente AudioAttributes.AttributeUsages
para roteamento, ajustes de volume e gerenciamento de foco. Os usos são uma representação do “por que” o stream está sendo reproduzido. Portanto, todos os fluxos e solicitações de foco de áudio devem especificar um uso para sua reprodução de áudio. Quando não for definido especificamente ao criar um objeto AudioAttributes, o uso será padronizado como USAGE_UNKNOWN
. Embora atualmente seja tratado da mesma forma que USAGE_MEDIA
, esse comportamento não deve ser considerado para 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 exigem o uso de APIs do sistema, bem como android.permission.MODIFY_AUDIO_ROUTING
. Os novos usos do sistema são:
-
USAGE_EMERGENCY
-
USAGE_SAFETY
-
USAGE_VEHICLE_STATUS
-
USAGE_ANNOUNCEMENT
Para construir um AudioAttributes
com uso do sistema, use AudioAttributes.Builder#setSystemUsage
em vez de setUsage
. Chamar esse método sem uso do sistema resultará no lançamento de uma IllegalArgumentException
. Além disso, se o uso do sistema e o uso tiverem sido definidos em um construtor, ele lançará uma IllegalArgumentException
durante a construçã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 AAOS, usos semelhantes foram agrupados em CarAudioContext
. Esses contextos de áudio são usados em todo 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 surge um novo conjunto de casos de uso em torno de usuários simultâneos interagindo com a plataforma e procurando consumir mídias separadas. Por exemplo, um motorista pode tocar música na cabine enquanto os passageiros no banco de trás assistem a um vídeo do YouTube no display traseiro. O áudio multizona permite isso, permitindo que diferentes fontes de áudio sejam reproduzidas simultaneamente em diferentes áreas do veículo.
O áudio multizona a partir do Android 10 permite que os OEMs configurem o áudio em zonas separadas. Cada zona é uma coleção de dispositivos dentro do veículo com seus próprios grupos de volumes, configuração de roteamento para contextos e gerenciamento de foco. Desta forma, a cabine principal pode ser configurada como uma zona de áudio, enquanto os fones de ouvido do display traseiro podem ser configurados como uma segunda zona.
As zonas são definidas como parte de car_audio_configuration.xml
. CarAudioService
então lê a configuração e ajuda o AudioService a rotear fluxos de áudio com base em sua zona associada. Cada zona ainda define regras de roteamento com base nos contextos e no uid das aplicações. Quando um player é criado, CarAudioService
determina a qual zona o player está associado e, com base no uso, para qual dispositivo o AudioFlinger deve rotear o áudio.
O foco também é mantido de forma independente para cada zona de áudio. Isso permite que aplicativos em zonas diferentes produzam áudio de forma independente, sem interferir uns nos outros, ao mesmo tempo em que os aplicativos ainda respeitam as mudanças de foco dentro de sua zona. CarZonesAudioFocus
dentro CarAudioService
é responsável por gerenciar o foco de cada zona.
Figura 2. Configurar áudio multizona
Áudio HAL
As implementações de áudio automotivo contam com o Android Audio HAL padrão, que inclui o seguinte:
-
IDevice.hal
. Cria fluxos de entrada e saída, lida com volume principal e silenciamento e usa:-
createAudioPatch
. Para criar patches externos-externos entre dispositivos. -
IDevice.setAudioPortConfig()
para fornecer volume para cada fluxo físico.
-
-
IStream.hal
. Juntamente com as variantes de entrada e saída, gerencia o streaming de amostras de áudio de e para o hardware.
Tipos de dispositivos automotivos
Os seguintes tipos de dispositivos são relevantes para plataformas automotivas.
Tipo de dispositivo | Descrição |
---|---|
AUDIO_DEVICE_OUT_BUS | Saída primária do Android (é assim que todo o áudio do Android é entregue ao veículo). Usado como endereço para desambiguar fluxos para cada contexto. |
AUDIO_DEVICE_OUT_TELEPHONY_TX | Usado para áudio roteado para o rádio celular para transmissão. |
AUDIO_DEVICE_IN_BUS | Usado para insumos não classificados de outra forma. |
AUDIO_DEVICE_IN_FM_TUNER | Usado apenas para entrada de transmissão de rádio. |
AUDIO_DEVICE_IN_TV_TUNER | Usado para um dispositivo de TV, se presente. |
AUDIO_DEVICE_IN_LINE | Usado para conector de entrada AUX. |
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. |
Configurando dispositivos de áudio
Os dispositivos de áudio visíveis para Android devem ser definidos em /audio_policy_configuration.xml
, que inclui os seguintes componentes:
- nome do módulo. Suporta "primário" (usado para casos de uso automotivo), "A2DP", "remote_submix" e "USB". O nome do módulo e o driver de áudio correspondente devem ser compilados em
audio.primary.$(variant).so
. - portas do dispositivo. Contém uma lista de descritores de dispositivos para todos os dispositivos de entrada e saída (inclui dispositivos permanentemente conectados e dispositivos removíveis) que podem ser acessados a partir deste módulo.
- Para cada dispositivo de saída, você pode definir o controle de ganho que consiste em valores mínimo/máximo/padrão/passo em milibel (1 milibel = 1/100 dB = 1/1000 bel).
- O atributo address em uma instância devicePort pode ser usado para localizar o dispositivo, mesmo se houver vários dispositivos com o mesmo tipo de dispositivo que
AUDIO_DEVICE_OUT_BUS
. - mixPorts. Contém uma lista de todos os fluxos de saída e entrada expostos pelo HAL de áudio. Cada instância mixPort pode ser considerada um stream físico para Android AudioService.
- rotas. Define uma lista de conexões possíveis entre dispositivos de entrada e saída ou entre fluxo e dispositivo.
O exemplo a seguir define um dispositivo de saída bus0_phone_out no qual todos os fluxos 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>