O AAOS tem o próprio gerenciamento de volume no CarAudioService
. Ele usa
com a expectativa de que sejam aplicados abaixo da HAL por um hardware
amplificador de som, e não em 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.
Como usar 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 a flag config_useFixedVolume
como true (sobreposição conforme necessário):
<resources> <!-- Car uses hardware amplifier for volume. --> <bool name="config_useFixedVolume">true</bool> </resources>
Quando a sinalização config_useFixedVolume
não estiver definida (ou for definida como falsa),
aplicativos podem chamar AudioManager.setStreamVolume()
e mudar a
volume por tipo de transmissão no mixer de software. Isso pode ser indesejável devido
o efeito potencial em outras aplicações e o fato de que a atenuação do volume
o misturador de software resulta em menos bits significativos disponíveis no sinal quando
no amplificador de hardware.
Grupos de volumes
Os grupos gerenciam os volumes de uma coleção de dispositivos em uma zona de áudio. Para cada grupo de volumes, o volume pode ser controlado de forma independente, e o resultado ganhos 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 ele faz login.
Como definir 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 de car_audio_configuration.xml
.
Cada grupo de volumes precisa conter um ou mais dispositivos de saída com endereços associados.
Esses endereços devem corresponder aos dispositivos de saída definidos no
audio_policy_configuration.xml
:
Como configurar ganhos do grupo de volumes
Cada grupo de volumes tem valores de ganho mínimo, máximo e padrão, bem como
uma taxa de aprendizado. Elas são determinadas com base nos valores configurados
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 vai verificar os valores de ganho do conjunto e configure o grupo da seguinte forma:
- Tamanho da etapa. Precisa ser o mesmo para todos os dispositivos controlados pelo grupo de volumes
- Ganho mínimo. Menor ganho mínimo entre os dispositivos no grupo
- Ganho máximo. Maior ganho máximo entre os dispositivos no grupo
- Ganho padrão. Maior ganho padrão entre os dispositivos no grupo
Devido à forma como esses valores são configurados, é possível definir o ganho de um grupo de volumes fora do intervalo compatível com um dispositivo associado a ele. Nesse caso, para esse dispositivo, o ganho será definido como mínimo ou máximo Ganho de valor com base em se o valor do grupo de volumes está abaixo ou acima do intervalo.
Identificadores de grupo de volumes
Os grupos de volumes são identificados no ambiente 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, em que N é o número de grupos de volumes em
nessa zona. Dessa forma, os IDs dos grupos de volumes não são exclusivos entre as zonas. Esses identificadores
são usados para APIs CarAudioManager
associadas a grupos de volumes. Qualquer API
que usa um groupId
sem um zoneId
tem como padrão o
na zona de áudio principal.
Gerenciamento de volume de várias zonas
Cada zona de áudio precisa ter um ou mais grupos de volumes, e cada um deles
está associado a apenas uma zona de áudio. Essa relação é definida como parte
car_audio_configuration.xml
: Confira o exemplo fornecido
Como definir grupos de volumes acima.
Os níveis de volume atuais de cada zona são mantidos para o usuário associado nessa zona. Essas configurações são específicas da zona, ou seja, se um usuário fizer login em uma tela associada à zona principal e, depois, sinais em uma zona associada com em uma zona de áudio secundária, os níveis de volume carregados e mantidos na primeira zona diferentes das da zona secundária.
Como processar eventos das teclas de volume
O Android define vários códigos de tecla para o controle de volume, incluindo:
KEYCODE_VOLUME_UP
, KEYCODE_VOLUME_DOWN
e
KEYCODE_VOLUME_MUTE
Por padrão, o Android roteia a tecla de volume
de eventos a aplicativos. Implementações automotivas devem forçar esses eventos principais a
CarAudioService
, que pode chamar setGroupVolume
ou
setMasterMute
, conforme apropriado.
Para forçar esse comportamento, defina o config_handleVolumeKeysInWindowManager
para true
:
<resources> <bool name="config_handleVolumeKeysInWindowManager">true</bool> </resources>
No momento, os eventos de tecla de volume não conseguem distinguir a zona
destinadas e, como tal, são consideradas associadas à zona de áudio principal.
Quando um evento de tecla de volume é recebido, o CarAudioService
determina qual volume
ajustar, buscando os contextos de áudio para os players ativos e, em seguida, ajustando
o grupo de volumes que contém o dispositivo de saída associado com a prioridade mais alta
contexto de áudio. A priorização é determinada com base em uma ordem fixa definida em
CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY
:
Esmaecer e equilibrar
Ambas as versões da HAL AudioControl incluem APIs para definir a exibição de esmaecimento e equilíbrio
o veículo. Há APIs de sistema correspondentes para CarAudioManager que transmitem valores
até a HAL AudioControl. Essas APIs exigem
android.car.permission.CAR_CONTROL_AUDIO_VOLUME
:
As APIs AudioControl são:
setBalanceTowardRight(float value)
: Diminui o volume do alto-falante na direção de lado direito (+) ou esquerdo (-) do carro. 0,0 está centralizado, +1,0 está totalmente à direita, -1,0 é totalmente à esquerda, e um valor fora do intervalo de -1 a 1 é um erro.setFadeTowardFront(float value)
: muda o volume do alto-falante na direção de para a frente (+) ou para trás (-) do carro. 0,0 é centralizado, +1,0 é totalmente à frente, -1,0 é totalmente retroativo, e um valor fora do intervalo de -1 a 1 representa um erro.
Cabe aos OEMs decidir como esses valores devem ser aplicados e como serão exibidos aos usuários. Elas podem ser aplicadas estritamente à mídia ou em todo o todos os sons do Android.
O Android 11 também introduziu suporte à aplicação de efeitos de áudio em dispositivos de saída. Com isso, é possível gerenciar o esmaecimento e o equilíbrio usando efeitos de áudio nos dispositivos de saída apropriados, e não por essas APIs.
Redução de áudio
A redução de áudio ocorre quando o veículo reduz o ganho de um stream para que outra transmissão em reprodução ao mesmo tempo possa ser ouvida com mais clareza. No AAOS, a redução de áudio é deixada para a HAL implementar, já que pode haver muitos sons fora do Android, sobre as quais o SO não tem controle. No Android 11, as principais informações para a HAL tomar decisões de redução de volume é se dois dispositivos de saída têm streams ativos.
Quando se abaixar
Embora cabe ao OEM individual determinar como a redução de volume será tratada pela HAL, há algumas diretrizes gerais que recomendamos. Ao reproduzir várias transmissões no Android, geralmente ocorre quando dois apps/serviços mantêm a seleção de áudio ao mesmo tempo. 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 streams diferentes para serem reproduzidos simultaneamente.
Lembre-se de que os streams misturados pelo Android serão feitos antes de qualquer ganho que estão sendo aplicados. Dessa forma, qualquer transmissão que precise diminuir ao ser tocada simultaneamente outro deve ser roteado para dispositivos de saída separados, de modo que a HAL possa aplicar atenuação antes misturando-as.
Comportamento de redução de volume recomendado
Confira a seguir possíveis interações simultâneas em que recomendamos reduzir o volume que serão aplicadas:
EMERGENCY
: Desative ou desative o som de tudo, excetoSAFETY
, para garantir que o motorista ouça o somSAFETY
: Reduzir tudo, excetoEMERGENCY
para garantir O motorista ouve o som.NAVIGATION
: Reduzir tudo, excetoSAFETY
eEMERGENCY
CALL
: Reduzir tudo, excetoSAFETY
,EMERGENCY
eNAVIGATION
VOICE
: PatoCALL_RING
- Cabe aos OEMs determinar a importância do
VEHICLE_SOUNDS
ativo. e se é necessário recuar ou não outros sons para garantir que o motorista os ouça. MUSIC
eANNOUNCEMENT
precisam ser ocultadas por tudo. A principal exceção são os tons de interação por toque, que atualmente são reproduzidosSYSTEM_SOUND
Outras considerações ao reduzir o volume
Alguns apps/serviços, como navegação ou assistente, podem usar vários players para concluir as ações deles. Os OEMs precisam evitar o ato de fechar de forma muito agressiva com base no momento em que os dados de streaming são interrompidos. por esses dispositivos de saída para garantir que o usuário não tenha retorno de mídia para o volume máximo antes de abaixar de novo na reprodução seguinte da navegação ou o app assistente será iniciado.
Para veículos com vários estágios de som com isolamento bom o suficiente, há também a opção para encaminhar o áudio para diferentes áreas do carro, em vez de reduzir o volume. Por exemplo, navegação as instruções podem ser encaminhadas aos alto-falantes do encosto de cabeça do motorista enquanto a música continua tocar por toda a cabine em um volume normal.
Sons críticos para a segurança
Enquanto o Android 11 introduziu
APIs de foco de áudio HAL,
ainda cabe à HAL garantir que sons críticos para a segurança sejam priorizados em relação
outros. Mesmo que a HAL mantenha a seleção de áudio para USAGE_EMERGENCY
, isso não
garantir que apps e serviços do Android não tocarão sons. Cabe à HAL
determine quais streams do Android devem ser misturados ou silenciados, já que sons críticos para a segurança são
tocado.
Como definir a interface de configurações de volume
O AAOS dissocia a interface das configurações de volume da configuração do grupo de volumes (que pode ser sobrepostas conforme descrito em Como configurar grupos de volumes). Essa separação garante que nenhuma mudanças são necessárias se a configuração dos grupos de volumes for alterada no futuro.
Na interface "Configurações do carro", o packages/apps/Car/Settings/res/xml/car_volume_items.xml
contém elementos da interface (recursos de título e ícone) associados a cada um deles
AudioAttributes.USAGE
. Esse arquivo fornece uma renderização razoável de
o VolumeGroups
definido usando recursos associados à primeira
uso reconhecido contido em cada VolumeGroup.
O exemplo a seguir define que um VolumeGroup inclui
voice_communication
e voice_communication_signalling
. O padrão
A implementação da interface de configurações do carro renderiza o VolumeGroup usando os recursos associados
com voice_communication
, já que ele é 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
: As configurações de volume
A interface usa as seguintes APIs CarAudioManager baseadas em VolumeGroup:
getVolumeGroupCount()
para saber quantos controles precisam ser desenhados.getGroupMinVolume()
egetGroupMaxVolume()
para acessar os limites inferior e superior.getGroupVolume()
para saber o volume atual.registerVolumeChangeObserver()
para receber notificações sobre mudanças no volume.