Gerenciamento de volumes

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, exceto SAFETY , para garantir que o motorista ouça o som
  • SAFETY . Abaixe tudo, exceto EMERGENCY , para garantir que o motorista ouça o som
  • NAVIGATION . Abaixe tudo, exceto SAFETY e EMERGENCY
  • CALL . Evite tudo, exceto SAFETY , EMERGENCY e NAVIGATION
  • VOICE . Pato CALL_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 e ANNOUNCEMENT devem ser evitados por tudo. A principal exceção são os tons de interação por toque que atualmente são reproduzidos como SYSTEM_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() e getGroupMaxVolume() para obter os limites inferior e superior.
  • getGroupVolume() para obter o volume atual.
  • registerVolumeChangeObserver() para ser notificado sobre alterações de volume.