Administración de volumen

AAOS tiene su propia administración de volumen dentro de CarAudioService. Usa volúmenes fijos con la expectativa de que un amplificador de hardware, en lugar de software, debe aplicar los volúmenes debajo del HAL. También organiza los dispositivos de salida en grupos de volumen para aplicar las mismas ganancias a todos los dispositivos asociados con el grupo de volumen.

Cómo usar volúmenes fijos

Las implementaciones de AAOS deben controlar el volumen con un amplificador de hardware en lugar de un mezclador de software. Para evitar efectos secundarios, establece la marca config_useFixedVolume como verdadera (superposición según sea necesario):

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

Cuando no se establece la marca config_useFixedVolume (o se establece en "false"), las aplicaciones pueden llamar a AudioManager.setStreamVolume() y cambiar el volumen por tipo de transmisión en el mezclador de software. Esto puede no ser deseable debido al efecto potencial en otras aplicaciones y al hecho de que la atenuación del volumen en el mezclador de software genera menos bits significativos disponibles en la señal cuando se recibe en el amplificador de hardware.

Grupos de volúmenes

Los grupos de volumen administran los volúmenes de un conjunto de dispositivos dentro de una zona de audio. Para cada grupo de volumen, el volumen se puede controlar de forma independiente, y las ganancias resultantes se configuran en los dispositivos asociados para que las aplique el amplificador del vehículo. La configuración de volumen se conserva para el usuario y se carga cuando este accede.

Cómo definir grupos de volúmenes

CarAudioService usa grupos de volumen definidos en 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>

Ejemplo de implementación de car_audio_configuration.xml.

Cada grupo de volumen debe contener uno o más dispositivos de salida con direcciones asociadas. Estas direcciones deben corresponder a los dispositivos de salida definidos en audio_policy_configuration.xml.

Cómo configurar las ganancias de los grupos de volumen

Cada grupo de volumen tiene valores de ganancia mínimos, máximos y predeterminados, así como un tamaño de paso. Se determinan en función de los valores configurados en audio_policy_configuration.xml para los dispositivos asociados con el grupo de volumen.

<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 la inicialización, el grupo de volumen verificará los valores de ganancia de los dispositivos asociados y configurará el grupo de la siguiente manera:

  • Tamaño del paso. Debe ser el mismo para todos los dispositivos controlados por el grupo de volumen.
  • Ganancia mínima. La ganancia mínima más pequeña entre los dispositivos del grupo
  • Ganancia máxima. Ganancia máxima más alta entre los dispositivos del grupo
  • Ganancia predeterminada. La ganancia predeterminada más alta entre los dispositivos del grupo

Debido a la forma en que se configuran estos valores, es posible establecer la ganancia de un grupo de volumen fuera del rango admitido para un dispositivo asociado con el grupo de volumen. En este caso, para ese dispositivo, la ganancia se establecerá en el valor mínimo o máximo de la ganancia del dispositivo según si el valor del grupo de volumen está por debajo o por encima del rango.

Identificadores de grupos de volúmenes

Los grupos de volumen se identifican en el tiempo de ejecución por su orden de definición en el archivo en formato XML. Los IDs varían de 0 a N-1 dentro de una zona de audio, en la que N es la cantidad de grupos de volumen en esa zona. De esta manera, los IDs de los grupos de volúmenes no son únicos en todas las zonas. Estos identificadores se usan para las APIs de CarAudioManager asociadas con grupos de volúmenes. Cualquier API que tome un groupId sin un zoneId se establecerá de forma predeterminada en la zona de audio principal.

Administración de volúmenes multizona

Se espera que cada zona de audio tenga uno o más grupos de volumen, y cada grupo de volumen solo se asocie con una sola zona de audio. Esta relación se define como parte de car_audio_configuration.xml. Consulta el ejemplo que se proporciona en Cómo definir grupos de volúmenes más arriba.

Los niveles de volumen actuales de cada zona se conservan para el usuario asociado con esa zona. Este parámetro de configuración es específico de la zona, lo que significa que, si un usuario accede a una pantalla asociada con la zona principal y, luego, accede a una zona asociada con una zona de audio secundaria, los niveles de volumen cargados y persistentes para la primera zona serán diferentes de los de la zona secundaria.

Cómo controlar los eventos de teclas de volumen

Android define varios códigos de teclas para el control de volumen, como KEYCODE_VOLUME_UP, KEYCODE_VOLUME_DOWN y KEYCODE_VOLUME_MUTE. De forma predeterminada, Android enruta los eventos de tecla de volumen a las aplicaciones. Las implementaciones de Automotive deben forzar estos eventos de tecla a CarAudioService, que luego puede llamar a setGroupVolume o setMasterMute según corresponda.

Para forzar este comportamiento, establece la marca config_handleVolumeKeysInWindowManager como true:

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

Actualmente, los eventos de teclas de volumen no tienen forma de distinguir para qué zona están destinados y, por lo tanto, se supone que todos están asociados con la zona de audio principal. Cuando se recibe un evento de tecla de volumen, CarAudioService determina qué grupo de volumen ajustar recuperando los contextos de audio de los reproductores activos y, luego, ajusta el grupo de volumen que contiene el dispositivo de salida asociado con el contexto de audio de mayor prioridad. La priorización se determina en función de un orden fijo definido en CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY.

Balance y fundido

Ambas versiones de la HAL de AudioControl incluyen APIs para configurar la atenuación y el balance en el vehículo. Existen APIs del sistema correspondientes para CarAudioManager que pasan valores al HAL de AudioControl. Estas APIs requieren android.car.permission.CAR_CONTROL_AUDIO_VOLUME.

Las APIs de AudioControl son las siguientes:

  • setBalanceTowardRight(float value): Desplaza el volumen de las bocinas hacia el lado derecho (+) o izquierdo (-) del automóvil. 0.0 está centrado, +1.0 está completamente a la derecha, -1.0 está completamente a la izquierda y un valor fuera del rango de -1 a 1 es un error.
  • setFadeTowardFront(float value): Desplaza el volumen de las bocinas hacia la parte frontal (+) o posterior (-) del automóvil. 0.0 está centrado, +1.0 está completamente hacia adelante, -1.0 está completamente hacia atrás y un valor fuera del rango de -1 a 1 es un error.

Depende de los OEMs decidir cómo se deben aplicar estos valores y cómo se mostrarán a los usuarios. Se pueden aplicar estrictamente al contenido multimedia o a todos los sonidos de Android.

Android 11 también introdujo compatibilidad para aplicar efectos de audio a dispositivos de salida. Con esto, es posible administrar la atenuación y el balance de forma alternativa a través de efectos de audio en los dispositivos de salida adecuados en lugar de hacerlo a través de estas APIs.

Autosilenciado de fondo

El autosilencio de audio se produce cuando el vehículo reduce la ganancia de una transmisión para que se pueda escuchar con mayor claridad otra transmisión que se reproduce al mismo tiempo. En AAOS, el silenciamiento de audio queda a cargo de HAL para implementarlo, ya que hay muchos sonidos fuera de Android sobre los que el SO no tiene control. En Android 11, la información principal disponible para el HAL para tomar decisiones de silenciamiento es si dos dispositivos de salida tienen transmisiones activas.

Cuándo agacharse

Si bien depende de cada OEM determinar cómo su HAL controlará la atenuación, hay algunos lineamientos generales que recomendamos. Por lo general, se reproducen varias transmisiones en Android cuando dos apps o servicios mantienen el enfoque de audio de forma simultánea. Con eso en mente, consulta la Matriz de interacción para saber cuándo Android puede otorgar enfoque simultáneo y, por lo tanto, cuándo es posible que se reproduzcan dos transmisiones diferentes de forma simultánea.

Ten en cuenta que Android combinará las transmisiones antes de aplicar las ganancias. Por lo tanto, cualquier transmisión que se deba atenuar cuando se reproduce de forma simultánea con otra debe enrutarse a dispositivos de salida separados para que el HAL pueda aplicar la atenuación antes de mezclarlos.

Comportamiento de atenuación recomendado

Las siguientes son posibles interacciones simultáneas en las que recomendamos que se aplique la atenuación:

  • EMERGENCY. Baja o silencia todo excepto SAFETY para asegurarte de que el conductor escuche el sonido.
  • SAFETY. Silencia todo excepto EMERGENCY para asegurarte de que el conductor escuche el sonido.
  • NAVIGATION. Oculta todo excepto SAFETY y EMERGENCY.
  • CALL. Oculta todo, excepto SAFETY, EMERGENCY y NAVIGATION.
  • VOICE. Pato CALL_RING
  • Depende de los OEMs determinar la importancia del VEHICLE_SOUNDS activo y si deben o no atenuar otros sonidos para garantizar que el conductor los escuche.
  • MUSIC y ANNOUNCEMENT deben estar ocultos por todo. La principal excepción a esto son los tonos de interacción táctil que actualmente se reproducen como SYSTEM_SOUND.

Otras consideraciones para usar la función de atenuación

Algunas apps o servicios, como la navegación o el asistente, pueden usar varios reproductores para completar sus acciones. Los OEMs deben evitar desactivar el sonido demasiado agresivamente en función de cuándo dejan de llegar datos de transmisión a través de estos dispositivos de salida para garantizar que el usuario no vuelva a tener el volumen de contenido multimedia al máximo por un momento antes de que se vuelva a bajar cuando comience la próxima reproducción de la app de navegación o asistente.

En el caso de los vehículos con varias etapas de sonido con un aislamiento lo suficientemente bueno, también existe la opción de enrutar el audio a diferentes áreas del automóvil en lugar de atenuarlo. Por ejemplo, las instrucciones de navegación se pueden dirigir a las bocinas del reposacabezas del conductor mientras la música sigue sonando en la cabina a un volumen normal.

Sonido de seguridad crítica

Si bien Android 11 introdujo APIs de enfoque de audio de HAL, depende de la HAL garantizar que los sonidos críticos de seguridad se prioricen sobre los demás. Incluso si el HAL mantiene el enfoque de audio para USAGE_EMERGENCY, eso no garantiza que las apps y los servicios de Android no reproduzcan sonidos. Depende de la HAL determinar qué transmisiones de Android se deben mezclar o silenciar a medida que se reproducen sonidos críticos de seguridad.

Cómo configurar la IU de configuración de volumen

AAOS separa la IU de configuración de volumen de la configuración del grupo de volúmenes (que se puede superponer como se describe en Configuración de grupos de volúmenes). Esta separación garantiza que no se requieran cambios si la configuración de los grupos de volúmenes cambia en el futuro.

En la IU de la configuración del automóvil, el archivo packages/apps/Car/Settings/res/xml/car_volume_items.xml contiene elementos de la IU (recursos de título y de ícono) asociados con cada AudioAttributes.USAGE definido. Este archivo proporciona una renderización razonable del VolumeGroups definido mediante el uso de recursos asociados con el primer uso reconocido contenido en cada VolumeGroup.

Por ejemplo, en el siguiente ejemplo, se define un VolumeGroup como que incluye voice_communication y voice_communication_signalling. La implementación predeterminada de la IU de configuración del automóvil renderiza el VolumeGroup con los recursos asociados con voice_communication, ya que es el primero en el archivo.

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

Los atributos y valores que se usan en la configuración anterior se declaran en packages/apps/Car/Settings/res/values/attrs.xml. La IU de configuración de volumen usa las siguientes APIs de CarAudioManager basadas en VolumeGroup:

  • getVolumeGroupCount() para saber cuántos controles se deben dibujar.
  • getGroupMinVolume() y getGroupMaxVolume() para obtener límites inferior y superior.
  • getGroupVolume() para obtener el volumen actual.
  • registerVolumeChangeObserver() para recibir notificaciones sobre los cambios de volumen.