Gestion des volumes

AAOS dispose de sa propre gestion des volumes dans CarAudioService. Il utilise des volumes fixes, en supposant que les volumes doivent être appliqués sous le HAL par un amplificateur matériel plutôt que par logiciel. Il organise également les appareils de sortie en groupes de volume pour appliquer les mêmes gains à tous les appareils associés au groupe de volume.

Utiliser des volumes fixes

Les implémentations AAOS doivent contrôler le volume à l'aide d'un amplificateur matériel plutôt que d'un mélangeur logiciel. Pour éviter les effets secondaires, définissez l'indicateur config_useFixedVolume sur "true" (superposition si nécessaire):

<resources>
    <!-- Car uses hardware amplifier for volume. -->
    <bool name="config_useFixedVolume">true</bool>
</resources>

Lorsque l'indicateur config_useFixedVolume n'est pas défini (ou est défini sur "false"), les applications peuvent appeler AudioManager.setStreamVolume() et modifier le volume par type de flux dans le mixeur logiciel. Cela peut être indésirable en raison de l'effet potentiel sur d'autres applications et du fait que l'atténuation du volume dans le mélangeur logiciel entraîne moins de bits significatifs disponibles dans le signal lorsqu'il est reçu à l'amplificateur matériel.

Groupes de volumes

Les groupes de volumes gèrent les volumes d'un ensemble d'appareils dans une zone audio. Pour chaque groupe de volume, le volume peut être contrôlé indépendamment, et les gains obtenus sont configurés sur les appareils associés pour être appliqués par l'amplificateur du véhicule. Les paramètres de volume sont conservés pour l'utilisateur et sont chargés lorsqu'il se connecte.

Définir des groupes de volumes

CarAudioService utilise des groupes de volume définis dans 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>

Exemple d'implémentation de car_audio_configuration.xml.

Chaque groupe de volumes doit contenir un ou plusieurs périphériques de sortie avec des adresses associées. Ces adresses doivent correspondre aux périphériques de sortie définis dans audio_policy_configuration.xml.

Configurer les gains de groupe de volume

Chaque groupe de volume a des valeurs de gain minimal, maximal et par défaut, ainsi qu'une taille de pas. Elles sont déterminées en fonction des valeurs configurées dans audio_policy_configuration.xml pour les appareils associés au groupe 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>

Lors de l'initialisation, le groupe de volume vérifie les valeurs de gain des appareils associés et configure le groupe comme suit:

  • Taille de pas. Doit être identique pour tous les appareils contrôlés par le groupe de volume
  • Gain minimal. Gain minimal le plus faible parmi les appareils du groupe
  • Gain maximal Gain maximal le plus élevé parmi les appareils du groupe
  • Gain par défaut. Gain par défaut le plus élevé parmi les appareils du groupe

En raison de la façon dont ces valeurs sont configurées, il est possible de définir le gain d'un groupe de volumes en dehors de la plage compatible pour un appareil associé au groupe de volumes. Dans ce cas, pour cet appareil, le gain sera défini sur la valeur de gain minimale ou maximale de l'appareil, selon que la valeur du groupe de volume est inférieure ou supérieure à la plage.

Identifiants de groupe de volumes

Les groupes de volumes sont identifiés au moment de l'exécution par leur ordre de définition dans le fichier XML. Les ID varient de 0 à N-1 dans une zone audio, où N correspond au nombre de groupes de volume dans cette zone. Par conséquent, les ID de groupe de volumes ne sont pas uniques entre les zones. Ces identifiants sont utilisés pour les API CarAudioManager associées à des groupes de volumes. Toute API qui reçoit un groupId sans zoneId est définie par défaut sur la zone audio principale.

Gestion multizone des volumes

Chaque zone audio doit comporter un ou plusieurs groupes de volume, et chaque groupe de volume n'est associé qu'à une seule zone audio. Cette relation est définie dans le cadre de car_audio_configuration.xml. Consultez l'exemple fourni dans la section Définir des groupes de volumes ci-dessus.

Les niveaux de volume actuels de chaque zone sont conservés pour l'utilisateur associé à cette zone. Ces paramètres sont spécifiques à la zone. Par conséquent, si un utilisateur se connecte sur un écran associé à la zone principale, puis se connecte plus tard sur une zone associée à une zone audio secondaire, les niveaux de volume chargés et conservés pour la première zone seront différents de ceux de la zone secondaire.

Gérer les événements de touche de volume

Android définit plusieurs codes de touche pour le contrôle du volume, y compris KEYCODE_VOLUME_UP, KEYCODE_VOLUME_DOWN et KEYCODE_VOLUME_MUTE. Par défaut, Android achemine les événements de la touche de volume vers les applications. Les implémentations automobiles doivent forcer ces événements de touche à CarAudioService, qui peuvent ensuite appeler setGroupVolume ou setMasterMute selon le cas.

Pour forcer ce comportement, définissez l'indicateur config_handleVolumeKeysInWindowManager sur true:

<resources>
    <bool name="config_handleVolumeKeysInWindowManager">true</bool>
</resources>

Les événements de touche de volume n'ont actuellement aucun moyen de distinguer la zone à laquelle ils sont destinés. Par conséquent, ils sont tous supposés être associés à la zone audio principale. Lorsqu'un événement de touche de volume est reçu, CarAudioService détermine le groupe de volume à ajuster en récupérant les contextes audio des lecteurs actifs, puis en ajustant le groupe de volume contenant l'appareil de sortie associé au contexte audio de priorité la plus élevée. La hiérarchisation est déterminée en fonction d'un ordre fixe défini dans CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY.

Fondu et équilibre

Les deux versions du HAL AudioControl incluent des API permettant de régler le fondu et l'équilibre dans le véhicule. Des API système correspondantes pour CarAudioManager transmettent des valeurs à l'HAL AudioControl. Ces API nécessitent android.car.permission.CAR_CONTROL_AUDIO_VOLUME.

Les API AudioControl sont les suivantes:

  • setBalanceTowardRight(float value) : déplace le volume des haut-parleurs vers la droite (+) ou la gauche (-) de la voiture. 0,0 est centré, +1,0 est complètement à droite, -1,0 est complètement à gauche, et une valeur en dehors de la plage de -1 à 1 est une erreur.
  • setFadeTowardFront(float value) : déplace le volume des haut-parleurs vers l'avant (+) ou l'arrière (-) de la voiture. 0,0 correspond au centre, +1,0 à l'avant, -1,0 à l'arrière, et une valeur en dehors de la plage -1 à 1 est une erreur.

Il appartient aux OEM de décider comment ces valeurs doivent être appliquées et comment elles seront présentées aux utilisateurs. Ils peuvent être appliqués strictement aux contenus multimédias ou à tous les sons Android.

Android 11 permet également d'appliquer des effets audio aux appareils de sortie. Il est ainsi possible de gérer le fondu et l'équilibre via des effets audio sur les périphériques de sortie appropriés plutôt que via ces API.

Atténuation audio

La diminution du volume se produit lorsque le véhicule réduit le gain d'un flux afin qu'un autre flux diffusé en même temps soit entendu plus clairement. Dans AAOS, le masquage audio est laissé à la charge de la HAL, car il existe potentiellement de nombreux sons en dehors d'Android sur lesquels l'OS n'a aucun contrôle. Dans Android 11, la principale information disponible pour le HAL afin de prendre des décisions de masquage est de savoir si deux appareils de sortie ont tous deux des flux actifs.

Quand se baisser

Bien qu'il soit de la responsabilité de chaque OEM de déterminer comment le masquage sera géré par son HAL, nous vous recommandons de suivre certaines consignes générales. La lecture de plusieurs flux dans Android se produit le plus souvent lorsque deux applications/services maintiennent la sélection audio en même temps. Gardez cela à l'esprit et consultez la section Matrice d'interaction pour savoir quand Android peut accorder la sélection simultanée et, par conséquent, quand il est possible que deux flux différents soient lus simultanément.

N'oubliez pas que les flux mélangés par Android le seront avant que des gains ne soient appliqués. Par conséquent, tout flux qui doit être masqué lorsqu'il est lu simultanément avec un autre doit être acheminé vers des périphériques de sortie distincts afin que le HAL puisse appliquer le masquage avant de les mélanger.

Comportement de masquage recommandé

Voici les interactions simultanées potentielles pour lesquelles nous vous recommandons d'appliquer le masquage:

  • EMERGENCY. Coupez ou coupez le son de tout sauf de SAFETY pour vous assurer que le conducteur entend le son.
  • SAFETY. Coupez tout sauf EMERGENCY pour vous assurer que le pilote entend le son.
  • NAVIGATION. Masquer tout sauf SAFETY et EMERGENCY
  • CALL. Masquer tout sauf SAFETY, EMERGENCY et NAVIGATION
  • VOICE. Canard CALL_RING
  • Il appartient aux OEM de déterminer l'importance des VEHICLE_SOUNDS actifs et de savoir s'ils doivent ou non réduire le volume d'autres sons pour s'assurer que le conducteur les entend.
  • MUSIC et ANNOUNCEMENT doivent être masqués par tout. La principale exception à cette règle concerne les tonalités d'interaction tactile, qui sont actuellement diffusées en tant que SYSTEM_SOUND.

Autres points à prendre en compte lors du masquage

Certaines applications/services, comme la navigation ou l'assistant, peuvent utiliser plusieurs acteurs pour effectuer leurs actions. Les OEM doivent éviter de démasquer trop agressivement en fonction du moment où les données de flux cessent d'être transmises via ces appareils de sortie afin de s'assurer que l'utilisateur ne voit pas momentanément le volume multimédia revenir à son niveau maximal avant d'être à nouveau masqué lorsque la lecture suivante de l'application de navigation ou de l'assistant commence.

Pour les véhicules dotés de plusieurs scènes sonores avec une isolation suffisante, il est également possible de router l'audio vers différentes zones de la voiture plutôt que de réduire le volume. Par exemple, les instructions de navigation peuvent être acheminées vers les haut-parleurs du repose-tête du conducteur, tandis que la musique continue de jouer dans l'habitacle à un volume normal.

Sons critiques pour la sécurité

Bien qu'Android 11 ait introduit les API de mise au point audio HAL, il revient toujours au HAL de s'assurer que les sons essentiels à la sécurité sont prioritaires par rapport aux autres. Même si le HAL détient la sélection audio pour USAGE_EMERGENCY, cela ne garantit pas que les applications et les services d'Android ne diffusent pas de sons. C'est à l'HAL de déterminer quels flux Android doivent être mélangés ou coupés lorsque des sons critiques pour la sécurité sont diffusés.

Configurer l'UI des paramètres de volume

AAOS dissocie l'UI des paramètres de volume de la configuration du groupe de volumes (qui peut être superposée, comme décrit dans la section "Configurer des groupes de volumes"). Cette séparation garantit qu'aucune modification n'est requise si la configuration des groupes de volumes change à l'avenir.

Dans l'UI des paramètres de la voiture, le fichier packages/apps/Car/Settings/res/xml/car_volume_items.xml contient des éléments d'UI (ressources de titre et d'icône) associés à chaque AudioAttributes.USAGE défini. Ce fichier permet un rendu raisonnable de l'VolumeGroups défini en utilisant les ressources associées à la première utilisation reconnue contenue dans chaque VolumeGroup.

Par exemple, l'exemple suivant définit un VolumeGroup comme incluant à la fois voice_communication et voice_communication_signalling. L'implémentation par défaut de l'UI des paramètres de la voiture affiche le VolumeGroup à l'aide des ressources associées à voice_communication, car il s'agit de la première dans le fichier.

<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>

Les attributs et les valeurs utilisés dans la configuration ci-dessus sont déclarés dans packages/apps/Car/Settings/res/values/attrs.xml. L'UI des paramètres de volume utilise les API CarAudioManager basées sur VolumeGroup suivantes:

  • getVolumeGroupCount() pour connaître le nombre de commandes à dessiner.
  • getGroupMinVolume() et getGroupMaxVolume() pour obtenir les limites inférieure et supérieure.
  • getGroupVolume() pour obtenir le volume actuel.
  • registerVolumeChangeObserver() pour recevoir des notifications en cas de modification du volume.