Gerenciamento de volumes

AAOS tem 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. Isso pode ser indesejável devido ao efeito potencial em outras aplicações e ao fato de que a atenuação de 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 volume gerenciam os volumes de uma coleção de dispositivos dentro de uma zona de áudio. Para cada grupo de volume o volume pode ser controlado independentemente, e os ganhos resultantes são configurados nos dispositivos associados a serem aplicados pelo amplificador do veículo. As configurações de volume são mantidas para o usuário e são carregadas quando o usuário entra.

Definindo grupos de volumes

CarAudioService usa grupos de volume 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 volume 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 volume tem 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. Nesse caso, para esse dispositivo, o ganho será definido para o valor de ganho mínimo ou máximo do dispositivo com base no valor do grupo de volume estar abaixo ou acima da faixa.

Identificadores de grupos de volumes

Os grupos de volumes são identificados no tempo de execução por sua 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 volume nessa zona. Dessa forma, os IDs do grupo 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 aceite 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 seja 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 para 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 persistentes para a primeira zona serão diferentes dos aqueles para a zona secundária.

Manipulando eventos de chave de volume

O Android define vários códigos de tecla para controle de volume, incluindo KEYCODE_VOLUME_UP , KEYCODE_VOLUME_DOWN e KEYCODE_VOLUME_MUTE . Por padrão, o Android roteia os eventos de tecla de volume para aplicativos. As implementações automotivas devem forçar esses eventos-chave 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>

Os eventos de tecla de volume atualmente não têm como distinguir a zona a que se destinam e, como tal, presume-se que todos estejam associados à zona de áudio principal. Quando um evento de tecla 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 prioridade mais alta. A priorização é determinada com base em uma ordem fixa definida em CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY .

Desvanecer e equilibrar

Ambas as versões do AudioControl HAL incluem APIs para definir fade e balance 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 do AudioControl são:

  • setBalanceTowardRight(float value) . Muda o volume do alto-falante para o lado direito (+) ou esquerdo (-) do carro. 0,0 é centralizado, +1,0 é totalmente à direita, -1,0 é totalmente à esquerda e um valor fora do intervalo -1 a 1 é um erro.
  • setFadeTowardFront(float value) - Desloca 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 -1 a 1 é um erro.

Cabe aos OEMs decidir como esses valores devem ser aplicados e como eles serão apresentados aos usuários. Eles podem ser aplicados estritamente à mídia ou a todos os sons do Android.

O Android 11 também introduziu suporte para aplicar efeitos de áudio a dispositivos de saída. Com isso, é possível gerenciar alternativamente o fade e o balanceamento por meio de efeitos de áudio nos dispositivos de saída apropriados, em vez de usar essas APIs.

Abaixamento de áudio

A redução de áudio ocorre quando o veículo reduz o ganho de um fluxo para que outro fluxo reproduzido ao mesmo tempo possa ser ouvido 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 para tomar decisões de redução é se dois dispositivos de saída têm fluxos ativos.

Quando abaixar

Embora dependa do OEM individual determinar como o ducking será tratado por seu HAL, existem algumas diretrizes gerais que recomendamos. Múltiplos fluxos reproduzidos no Android geralmente ocorrem 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.

Lembre-se de que todos os fluxos misturados pelo Android serão feitos antes da aplicação de quaisquer ganhos. 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 a redução antes de misturá-los.

Comportamento de esquiva recomendado

A seguir, são possíveis interações simultâneas em que recomendamos a aplicação de 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 . Evite tudo, exceto SAFETY e EMERGENCY
  • CALL . Abaixe 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 a isso são os tons de interação por toque que atualmente são tocados 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 reduzir de forma muito agressiva com base em quando os dados de fluxo param de passar por esses dispositivos de saída para garantir que o usuário não tenha momentaneamente o retorno da mídia ao volume total antes de ser reduzido de volta 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 há 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 roteadas para os alto-falantes do encosto de cabeça do motorista enquanto a música continua a tocar na cabine em um 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 os 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 conforme os sons críticos de segurança são reproduzidos.

Configurando a IU de configurações de volume

O AAOS separa a interface do usuário das 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 alteração seja necessária se a configuração dos grupos de volumes for alterada no futuro.

Na IU do Car Settings, 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 IU 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.