AAOS possui seu próprio gerenciamento de volume dentro CarAudioService
. Ele usa volumes fixos com a expectativa de que os volumes sejam aplicados abaixo do HAL por um amplificador de hardware e não por software. Ele também organiza os dispositivos de saída em grupos de volumes para aplicar os mesmos ganhos a todos os dispositivos associados ao grupo de volumes.
Usando volumes fixos
As implementações AAOS devem controlar o volume usando um amplificador de hardware em vez de um mixer de software. Para evitar efeitos colaterais, defina o sinalizador config_useFixedVolume
como true (sobreponha conforme necessário):
<resources> <!-- Car uses hardware amplifier for volume. --> <bool name="config_useFixedVolume">true</bool> </resources>
Quando o sinalizador config_useFixedVolume
não está definido (ou definido como falso), os aplicativos podem chamar AudioManager.setStreamVolume()
e alterar o volume por tipo de fluxo no mixer de software. Isto pode ser indesejável devido ao efeito potencial em outras aplicações e ao fato de que a atenuação do volume no mixer de software resulta em menos bits significativos disponíveis no sinal quando recebido no amplificador de hardware.
Grupos de volumes
Os grupos de volumes gerenciam os volumes de um conjunto de dispositivos dentro de uma zona de áudio. Para cada grupo de volume o volume pode ser controlado de forma independente, e os ganhos resultantes são configurados nos dispositivos associados para serem aplicados pelo amplificador do veículo. As configurações de volume são mantidas para o usuário e carregadas quando o usuário faz login.
Definindo grupos de volumes
CarAudioService usa grupos de volumes definidos em car_audio_configuration.xml
:
<audioZoneConfiguration version="2.0"> <zones> <zone name="primary zone" isPrimary="true"> <volumeGroups> <group> <device address="bus0_media_out"> <context context="music"/> </device> </group> <group> <device address="bus1_navigation_out"> <context context="navigation"/> </device> <device address="bus2_voice_command_out"> <context context="voice_command"/> </device> </group> ... </volumeGroups> </zone> </zones> </audioZoneConfiguration>
Exemplo de implementação car_audio_configuration.xml
.
Cada grupo de volumes deve conter um ou mais dispositivos de saída com endereços associados. Esses endereços devem corresponder aos dispositivos de saída definidos em audio_policy_configuration.xml
.
Configurando ganhos do grupo de volumes
Cada grupo de volumes possui valores de ganho mínimo, máximo e padrão, bem como um tamanho de passo. Eles são determinados com base nos valores configurados em audio_policy_configuration.xml
para os dispositivos associados ao grupo de volumes.
<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> <gains> <gain name="" mode="AUDIO_GAIN_MODE_JOINT" minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/> </gains> </devicePort>
Durante a inicialização, o grupo de volumes verificará os valores de ganho dos dispositivos associados e configurará o grupo da seguinte forma:
- Tamanho do passo. Deve ser o mesmo para todos os dispositivos controlados pelo grupo de volumes
- Ganho mínimo. Menor ganho mínimo entre os dispositivos do grupo
- Ganho máximo. Maior ganho máximo entre os dispositivos do grupo
- Ganho padrão. Maior ganho padrão entre os dispositivos do grupo
Devido à forma como esses valores são configurados, é possível definir o ganho de um grupo de volumes fora da faixa suportada por um dispositivo associado ao grupo de volumes. Neste caso, para esse dispositivo, o ganho será definido para o valor de ganho mínimo ou máximo do dispositivo, dependendo se o valor do grupo de volumes está abaixo ou acima da faixa.
Identificadores de grupos de volumes
Os grupos de volumes são identificados no tempo de execução pela ordem de definição no arquivo XML. Os IDs variam de 0 a N-1 dentro de uma zona de áudio, onde N é o número de grupos de volumes nessa zona. Dessa forma, os IDs de grupos de volumes não são exclusivos entre zonas. Esses identificadores são usados para APIs CarAudioManager
associadas a grupos de volumes. Qualquer API que receba um groupId
sem um zoneId
será padronizada para a zona de áudio primária.
Gerenciamento de volume multizona
Espera-se que cada zona de áudio tenha um ou mais grupos de volume, e cada grupo de volume está associado apenas a uma única zona de áudio. Esse relacionamento é definido como parte de car_audio_configuration.xml
. Consulte o exemplo fornecido em Definindo grupos de volumes acima.
Os níveis de volume atuais de cada zona são mantidos para o usuário associado a essa zona. Essas configurações são específicas da zona, o que significa que se um usuário fizer login em um monitor associado à zona primária e, posteriormente, entrar em uma zona associada a uma zona de áudio secundária, os níveis de volume carregados e persistidos para a primeira zona serão diferentes dos níveis de volume carregados e persistentes para a primeira zona. aqueles para a zona secundária.
Tratamento de eventos de chave de volume
O Android define vários códigos-chave para controle de volume, incluindo KEYCODE_VOLUME_UP
, KEYCODE_VOLUME_DOWN
e KEYCODE_VOLUME_MUTE
. Por padrão, o Android roteia os eventos de teclas de volume para aplicativos. As implementações automotivas devem forçar esses eventos principais para CarAudioService
, que pode então chamar setGroupVolume
ou setMasterMute
conforme apropriado.
Para forçar esse comportamento, defina o sinalizador config_handleVolumeKeysInWindowManager
como true
:
<resources> <bool name="config_handleVolumeKeysInWindowManager">true</bool> </resources>
Atualmente, os eventos de teclas de volume não têm como distinguir a qual zona se destinam e, como tal, presume-se que todos estejam associados à zona de áudio primária. Quando um evento de chave de volume é recebido, CarAudioService
determina qual grupo de volume ajustar, buscando os contextos de áudio para os players ativos e, em seguida, ajustando o grupo de volume que contém o dispositivo de saída associado ao contexto de áudio de maior prioridade. A priorização é determinada com base em uma ordem fixa definida em CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY
.
Desvanecimento e equilíbrio
Ambas as versões do AudioControl HAL incluem APIs para definir fade e equilíbrio no veículo. Existem APIs de sistema correspondentes para CarAudioManager que passam valores para o AudioControl HAL. Essas APIs requerem android.car.permission.CAR_CONTROL_AUDIO_VOLUME
.
As APIs AudioControl são:
-
setBalanceTowardRight(float value)
. Muda o volume do alto-falante para o lado direito (+) ou esquerdo (-) do carro. 0,0 está centralizado, +1,0 está totalmente à direita, -1,0 está totalmente à esquerda e um valor fora do intervalo de -1 a 1 é um erro. -
setFadeTowardFront(float value)
- Muda o volume do alto-falante para a frente (+) ou para trás (-) do carro. 0,0 é centralizado, +1,0 é totalmente para frente, -1,0 é totalmente para trás e um valor fora do intervalo de -1 a 1 é um erro.
Cabe aos OEMs decidir como esses valores devem ser aplicados e como serão divulgados aos usuários. Eles podem ser aplicados estritamente à mídia ou de maneira geral a todos os sons do Android.
O Android 11 também introduziu suporte para aplicação de efeitos de áudio em dispositivos de saída. Com isso, é possível gerenciar alternativamente o fade e o equilíbrio por meio de efeitos de áudio nos dispositivos de saída apropriados, em vez de por meio dessas APIs.
Esquiva de áudio
A redução de áudio ocorre quando o veículo reduz o ganho de uma transmissão para que outra transmissão reproduzida ao mesmo tempo possa ser ouvida com mais clareza. No AAOS, a redução de áudio é deixada para o HAL implementar, pois há potencialmente muitos sons fora do Android sobre os quais o sistema operacional não tem controle. No Android 11, a principal informação disponível para o HAL tomar decisões de redução é se dois dispositivos de saída possuem fluxos ativos.
Quando se abaixar
Embora caiba ao OEM individual determinar como o ducking será tratado pelo seu HAL, existem algumas diretrizes gerais que recomendamos. Vários streams reproduzidos no Android ocorrerão mais comumente quando dois aplicativos/serviços mantêm o foco de áudio simultaneamente. Com isso em mente, consulte Matriz de interação para saber quando o Android pode conceder foco simultâneo e, portanto, quando é possível que dois fluxos diferentes sejam reproduzidos simultaneamente.
Tenha em mente que quaisquer streams misturados pelo Android serão feitos antes de quaisquer ganhos serem aplicados. Como tal, qualquer fluxo que deva ser reduzido quando reproduzido simultaneamente com outro deve ser roteado para dispositivos de saída separados para que o HAL possa aplicar redução antes de misturá-los.
Comportamento de esquiva recomendado
A seguir estão possíveis interações simultâneas nas quais recomendamos a aplicação do ducking:
-
EMERGENCY
. Abaixe ou silencie tudo, excetoSAFETY
, para garantir que o motorista ouça o som -
SAFETY
. Abaixe tudo, excetoEMERGENCY
, para garantir que o motorista ouça o som -
NAVIGATION
. Abaixe tudo, excetoSAFETY
eEMERGENCY
-
CALL
. Evite tudo, excetoSAFETY
,EMERGENCY
eNAVIGATION
-
VOICE
. PatoCALL_RING
- Cabe aos OEMs determinar a importância dos
VEHICLE_SOUNDS
ativos e se devem ou não evitar outros sons para garantir que o motorista os ouça. -
MUSIC
eANNOUNCEMENT
devem ser evitados por tudo. A principal exceção são os tons de interação por toque que atualmente são reproduzidos comoSYSTEM_SOUND
Outras considerações ao se esquivar
Alguns aplicativos/serviços, como navegação ou assistente, podem usar vários jogadores para concluir suas ações. Os OEMs devem evitar a redução muito agressiva com base em quando os dados do fluxo param de passar por esses dispositivos de saída para garantir que o usuário não tenha a mídia retornando momentaneamente ao volume máximo antes de ser reduzida novamente quando a próxima reprodução do aplicativo de navegação ou assistente começar.
Para veículos com vários estágios de som com isolamento bom o suficiente, também existe a opção de direcionar o áudio para diferentes áreas do carro, em vez de se abaixar. Por exemplo, as instruções de navegação podem ser encaminhadas para os alto-falantes do encosto de cabeça do motorista enquanto a música continua a tocar em toda a cabine em volume normal.
Sons críticos de segurança
Embora o Android 11 tenha introduzido APIs de foco de áudio HAL , ainda cabe ao HAL garantir que sons críticos de segurança sejam priorizados em detrimento de outros. Mesmo que o HAL mantenha o foco de áudio para USAGE_EMERGENCY
, isso não garante que aplicativos e serviços no Android não reproduzam sons. Cabe ao HAL determinar quais fluxos do Android devem ser mixados ou silenciados à medida que sons críticos de segurança são reproduzidos.
Configurando a IU de configurações de volume
O AAOS desacopla a UI de configurações de volume da configuração do grupo de volumes (que pode ser sobreposta conforme descrito em Configurando grupos de volumes). Essa separação garante que nenhuma mudança será necessária se a configuração dos grupos de volumes mudar no futuro.
Na IU de configurações do carro, o arquivo packages/apps/Car/Settings/res/xml/car_volume_items.xml
contém elementos da IU (recursos de título e ícone) associados a cada AudioAttributes.USAGE
definido. Este arquivo fornece uma renderização razoável dos VolumeGroups
definidos usando recursos associados ao primeiro uso reconhecido contido em cada VolumeGroup.
Por exemplo, o exemplo a seguir define um VolumeGroup como incluindo voice_communication
e voice_communication_signalling
. A implementação padrão da interface do usuário de configurações do carro renderiza o VolumeGroup usando os recursos associados a voice_communication
, pois é o primeiro no arquivo.
<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto"> <item car:usage="voice_communication" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="voice_communication_signalling" car:title="@*android:string/volume_call" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="media" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="game" car:title="@*android:string/volume_music" car:icon="@*android:drawable/ic_audio_media"/> <item car:usage="alarm" car:title="@*android:string/volume_alarm" car:icon="@*android:drawable/ic_audio_alarm"/> <item car:usage="assistance_navigation_guidance" car:title="@string/navi_volume_title" car:icon="@drawable/ic_audio_navi"/> <item car:usage="notification_ringtone" car:title="@*android:string/volume_ringtone" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistant" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="notification" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_request" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_instant" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_communication_delayed" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="notification_event" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_accessibility" car:title="@*android:string/volume_notification" car:icon="@*android:drawable/ic_audio_ring_notif"/> <item car:usage="assistance_sonification" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> <item car:usage="unknown" car:title="@*android:string/volume_unknown" car:icon="@*android:drawable/ic_audio_vol"/> </carVolumeItems>
Os atributos e valores usados na configuração acima são declarados em packages/apps/Car/Settings/res/values/attrs.xml
. A IU de configurações de volume usa as seguintes APIs CarAudioManager baseadas em VolumeGroup:
-
getVolumeGroupCount()
para saber quantos controles devem ser desenhados. -
getGroupMinVolume()
egetGroupMaxVolume()
para obter os limites inferior e superior. -
getGroupVolume()
para obter o volume atual. -
registerVolumeChangeObserver()
para ser notificado sobre alterações de volume.