Gerenciamento de volume

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, exceto SAFETY, para garantir que o motorista ouça o som
  • SAFETY: Reduzir tudo, exceto EMERGENCY para garantir O motorista ouve o som.
  • NAVIGATION: Reduzir tudo, exceto SAFETY e EMERGENCY
  • CALL: Reduzir tudo, exceto SAFETY, EMERGENCY e NAVIGATION
  • VOICE: Pato CALL_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 e ANNOUNCEMENT precisam ser ocultadas por tudo. A principal exceção são os tons de interação por toque, que atualmente são reproduzidos SYSTEM_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() e getGroupMaxVolume() para acessar os limites inferior e superior.
  • getGroupVolume() para saber o volume atual.
  • registerVolumeChangeObserver() para receber notificações sobre mudanças no volume.