Audio automotriz

Android Automotive OS (AAOS) se basa en la pila de audio principal de Android para admitir los casos de uso para operar como el sistema de infoentretenimiento en un vehículo. AAOS es responsable de los sonidos de infoentretenimiento (es decir, medios, navegación y comunicaciones), pero no es directamente responsable de las campanadas y advertencias que tienen requisitos estrictos de disponibilidad y tiempo. Si bien AAOS proporciona señales y mecanismos para ayudar al vehículo a administrar el audio, al final depende del vehículo tomar la decisión sobre qué sonidos deben reproducirse para el conductor y los pasajeros, asegurando que los sonidos críticos para la seguridad y los sonidos reglamentarios se escuchen correctamente sin interrupción.

Dado que Android gestiona la experiencia multimedia del vehículo, las fuentes multimedia externas, como el sintonizador de radio, deben estar representadas por aplicaciones, que pueden manejar el enfoque de audio y los eventos clave multimedia para la fuente.

Android 11 incluye los siguientes cambios en la compatibilidad con el audio relacionado con la automoción:

Sonidos y transmisiones de Android

Los sistemas de audio para automóviles manejan los siguientes sonidos y flujos:

Diagrama de arquitectura centrada en flujo

Figura 1. Diagrama de arquitectura centrada en flujo

Android administra los sonidos provenientes de las aplicaciones de Android, controlando esas aplicaciones y enrutando sus sonidos a los dispositivos de salida en el HAL según el tipo de sonido:

  • Los flujos lógicos , conocidos como fuentes en la nomenclatura de audio central, están etiquetados con Atributos de audio .
  • Las transmisiones físicas , conocidas como dispositivos en la nomenclatura de audio central, no tienen información de contexto después de la mezcla.

Para mayor confiabilidad, los sonidos externos (que provienen de fuentes independientes, como las campanadas de advertencia del cinturón de seguridad) se administran fuera de Android, por debajo del HAL o incluso en un hardware separado. Los implementadores del sistema deben proporcionar un mezclador que acepte uno o más flujos de entrada de sonido de Android y luego combine esos flujos de manera adecuada con las fuentes de sonido externas requeridas por el vehículo.

La implementación de HAL y el mezclador externo son responsables de garantizar que se escuchen los sonidos externos críticos para la seguridad y de mezclar las transmisiones proporcionadas por Android y enrutarlas a los altavoces adecuados.

Sonidos de Android

Las aplicaciones pueden tener uno o más reproductores que interactúan a través de las API estándar de Android (por ejemplo, AudioManager para control de enfoque o MediaPlayer para transmisión) para emitir uno o más flujos lógicos de datos de audio. Estos datos pueden ser mono de un solo canal o envolvente 7.1, pero se enrutan y tratan como una sola fuente. La transmisión de la aplicación está asociada con los atributos de audio que le dan al sistema sugerencias sobre cómo debe expresarse el audio.

Los flujos lógicos se envían a través de AudioService y se enrutan a uno (y solo uno) de los flujos de salida físicos disponibles, cada uno de los cuales es la salida de un mezclador dentro de AudioFlinger. Una vez que los atributos de audio se han mezclado en una transmisión física, ya no están disponibles.

Luego, cada transmisión física se entrega a la HAL de audio para su procesamiento en el hardware. En las aplicaciones automotrices, el hardware de renderizado puede ser códecs locales (similares a los dispositivos móviles) o un procesador remoto a través de la red física del vehículo. De cualquier manera, es el trabajo de la implementación de Audio HAL entregar los datos de muestra reales y hacer que se vuelvan audibles.

corrientes externas

Los flujos de sonido que no deben enrutarse a través de Android (por motivos de certificación o de sincronización) pueden enviarse directamente al mezclador externo. A partir de Android 11, HAL ahora puede solicitar el enfoque de estos sonidos externos para informar a Android de modo que pueda tomar las medidas apropiadas, como pausar los medios o evitar que otros se enfoquen.

Si las transmisiones externas son fuentes de medios que deben interactuar con el entorno de sonido que genera Android (por ejemplo, detener la reproducción de MP3 cuando se enciende un sintonizador externo), esas transmisiones externas deben estar representadas por una aplicación de Android. Dicha aplicación solicitaría el enfoque de audio en nombre de la fuente de medios en lugar de HAL, y respondería a las notificaciones de enfoque iniciando/deteniendo la fuente externa según sea necesario para adaptarse a la política de enfoque de Android. La aplicación también es responsable de manejar eventos clave de medios como reproducir/pausar. Un mecanismo sugerido para controlar tales dispositivos externos es HwAudioSource .

Dispositivos de salida

En el nivel HAL de audio, el tipo de dispositivo AUDIO_DEVICE_OUT_BUS proporciona un dispositivo de salida genérico para usar en los sistemas de audio del vehículo. El dispositivo de bus admite puertos direccionables (donde cada puerto es el punto final de un flujo físico) y se espera que sea el único tipo de dispositivo de salida admitido en un vehículo.

La implementación de un sistema puede usar un puerto de bus para todos los sonidos de Android, en cuyo caso, Android mezcla todo y lo entrega como una sola transmisión. Alternativamente, HAL puede proporcionar un puerto de bus para cada CarAudioContext para permitir la entrega simultánea de cualquier tipo de sonido. Esto hace posible que la implementación de HAL mezcle y elimine los diferentes sonidos según lo desee.

La asignación de contextos de audio a los dispositivos de salida se realiza a través car_audio_configuration.xml .

Entrada de micrófono

Al capturar audio, Audio HAL recibe una llamada openInputStream que incluye un argumento AudioSource que indica cómo debe procesarse la entrada del micrófono.

La fuente VOICE_RECOGNITION (específicamente el Asistente de Google) espera una transmisión de micrófono estéreo que tiene un efecto de cancelación de eco (si está disponible) pero no se le aplica ningún otro procesamiento. Se espera que la formación de haces sea realizada por el Asistente.

Entrada de micrófono multicanal

Para capturar audio desde un dispositivo con más de dos canales (estéreo), use una máscara de índice de canal en lugar de una máscara de índice posicional (como CHANNEL_IN_LEFT ). Ejemplo:

final AudioFormat audioFormat = new AudioFormat.Builder()
    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
    .setSampleRate(44100)
    .setChannelIndexMask(0xf /* 4 channels, 0..3 */)
    .build();
final AudioRecord audioRecord = new AudioRecord.Builder()
    .setAudioFormat(audioFormat)
    .build();
audioRecord.setPreferredDevice(someAudioDeviceInfo);

Cuando se configuran tanto setChannelMask como setChannelIndexMask , AudioRecord usa solo el valor establecido por setChannelMask (máximo de dos canales).

captura concurrente

A partir de Android 10, el marco de trabajo de Android admite la captura simultánea de entradas , pero con restricciones para proteger la privacidad del usuario. Como parte de estas restricciones, las fuentes virtuales como AUDIO_SOURCE_FM_TUNER se ignoran y, como tales, se pueden capturar simultáneamente con una entrada normal (como el micrófono). HwAudioSources tampoco se considera parte de las restricciones de captura simultánea.

Las aplicaciones diseñadas para funcionar con dispositivos AUDIO_DEVICE_IN_BUS o con dispositivos AUDIO_DEVICE_IN_FM_TUNER secundarios deben basarse en la identificación explícita de esos dispositivos y el uso AudioRecord.setPreferredDevice() para omitir la lógica de selección de fuente predeterminada de Android.

usos de audio

AAOS utiliza principalmente AudioAttributes.AttributeUsages para el enrutamiento, los ajustes de volumen y la gestión del enfoque. Los usos son una representación del "por qué" se está reproduciendo la transmisión. Por lo tanto, todas las transmisiones y solicitudes de enfoque de audio deben especificar un uso para su reproducción de audio. Cuando no se establece específicamente al crear un objeto AudioAttributes, el uso se establecerá de manera predeterminada en USAGE_UNKOWN . Si bien esto se trata actualmente de la misma manera que USAGE_MEDIA , no se debe confiar en este comportamiento para la reproducción de medios.

usos del sistema

En Android 11, se introdujeron los usos del sistema. Estos usos se comportan de manera similar a los usos establecidos anteriormente, excepto que requieren API del sistema para usarlos, así como android.permission.MODIFY_AUDIO_ROUTING . Los nuevos usos del sistema son:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Para construir AudioAttributes con un uso del sistema, use AudioAttributes.Builder#setSystemUsage en lugar de setUsage . Llamar a este método con un uso que no sea del sistema dará como resultado que se lance una IllegalArgumentException . Además, si tanto el uso del sistema como el uso se han establecido en un constructor, lanzará una IllegalArgumentException al construir.

Para verificar qué uso está asociado con una instancia de AudioAttributes , llama a AudioAttributes#getSystemUsage . Esto devuelve el uso o el uso del sistema asociado.

Contextos de audio

Para simplificar la configuración del audio AAOS, se han agrupado usos similares en CarAudioContext . Estos contextos de audio se utilizan en todo CarAudioService para definir el enrutamiento, los grupos de volumen y la gestión del foco de audio.

Los contextos de audio en Android 11 son:

CarAudioContexto Usos de atributos asociados
MUSIC UNKNOWN, GAME, MEDIA
NAVIGATION ASSISTANCE_NAVIGATION_GUIDANCE
VOICE_COMMAND ASSISTANT, ASSISTANCE_ACCESSIBILITY
CALL_RING NOTIFICATION_RINGTONE
CALL VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING
ALARM ALARM
NOTIFICATION NOTIFICATION, NOTIFICATION_*
SYSTEM_SOUND ASSISTANCE_SONIFICATION
EMERGENCY EMERGENCY
SAFETY SAFETY
VEHICLE_STATUS VEHICLE_STATUS
ANNOUNCEMENT ANNOUNCEMENT

Mapeo entre contextos de audio y usos. Las filas resaltadas son para nuevos usos del sistema .

Audio multizona

Con la industria automotriz viene un nuevo conjunto de casos de uso en torno a usuarios simultáneos que interactúan con la plataforma y buscan consumir medios separados. Por ejemplo, un conductor puede reproducir música en la cabina mientras los pasajeros en el asiento trasero miran un video de YouTube en la pantalla trasera. El audio multizona permite esto al permitir que diferentes fuentes de audio se reproduzcan simultáneamente en diferentes áreas del vehículo.

El audio multizona a partir de Android 10 permite a los OEM configurar el audio en zonas separadas. Cada zona es una colección de dispositivos dentro del vehículo con sus propios grupos de volumen, configuración de enrutamiento para contextos y administración de enfoque. De esta manera, la cabina principal podría configurarse como una zona de audio, mientras que los conectores para auriculares de la pantalla trasera se configurarían como una segunda zona.

Las zonas se definen como parte de car_audio_configuration.xml . Luego, CarAudioService lee la configuración y ayuda a AudioService a enrutar las transmisiones de audio en función de su zona asociada. Cada zona sigue definiendo reglas para el enrutamiento según los contextos y el uid de las aplicaciones. Cuando se crea un reproductor, CarAudioService determina a qué zona está asociado el reproductor y luego, en función del uso, a qué dispositivo AudioFlinger debe enrutar el audio.

El enfoque también se mantiene de forma independiente para cada zona de audio. Esto permite que las aplicaciones en diferentes zonas produzcan audio de forma independiente sin interferir entre sí mientras que las aplicaciones siguen respetando los cambios de enfoque dentro de su zona. CarZonesAudioFocus dentro de CarAudioService es responsable de administrar el enfoque de cada zona.

Configurar audio multizona

Figura 2. Configurar audio multizona

HAL de audio

Las implementaciones de audio automotriz se basan en el estándar Android Audio HAL , que incluye lo siguiente:

  • IDevice.hal . Crea flujos de entrada y salida, maneja el volumen maestro y el silenciamiento, y usa:
    • createAudioPatch . Para crear parches externo-externo entre dispositivos.
    • IDevice.setAudioPortConfig() para proporcionar volumen para cada transmisión física.
  • IStream.hal . Junto con las variantes de entrada y salida, gestiona la transmisión de muestras de audio hacia y desde el hardware.

Tipos de dispositivos automotrices

Los siguientes tipos de dispositivos son relevantes para las plataformas automotrices.

Tipo de dispositivo Descripción
AUDIO_DEVICE_OUT_BUS Salida principal de Android (así es como todo el audio de Android se envía al vehículo). Se usa como la dirección para eliminar la ambigüedad de los flujos para cada contexto.
AUDIO_DEVICE_OUT_TELEPHONY_TX Se utiliza para el audio enrutado a la radio celular para su transmisión.
AUDIO_DEVICE_IN_BUS Utilizado para insumos no clasificados de otra manera.
AUDIO_DEVICE_IN_FM_TUNER Se usa solo para la entrada de radiodifusión.
AUDIO_DEVICE_IN_TV_TUNER Se utiliza para un dispositivo de TV si está presente.
AUDIO_DEVICE_IN_LINE Se utiliza para el conector de entrada AUX.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Música recibida por Bluetooth.
AUDIO_DEVICE_IN_TELEPHONY_RX Se utiliza para el audio recibido de la radio celular asociada con una llamada telefónica.

Configuración de dispositivos de audio

Los dispositivos de audio visibles para Android deben definirse en /audio_policy_configuration.xml , que incluye los siguientes componentes:

  • Nombre del módulo. Admite "primario" (utilizado para casos de uso automotriz), "A2DP", "remote_submix" y "USB". El nombre del módulo y el controlador de audio correspondiente deben compilarse en audio.primary.$(variant).so .
  • dispositivosPuertos. Contiene una lista de descriptores de dispositivos para todos los dispositivos de entrada y salida (incluye dispositivos conectados permanentemente y dispositivos extraíbles) a los que se puede acceder desde este módulo.
    • Para cada dispositivo de salida, puede definir el control de ganancia que consiste en valores mínimos/máximos/predeterminados/pasos en milibel (1 milibel = 1/100 dB = 1/1000 bel).
    • El atributo de dirección en una instancia de devicePort se puede usar para encontrar el dispositivo, incluso si hay varios dispositivos con el mismo tipo de dispositivo que AUDIO_DEVICE_OUT_BUS .
  • mixPorts. Contiene una lista de todos los flujos de entrada y salida expuestos por la HAL de audio. Cada instancia de mixPort se puede considerar como una transmisión física para Android AudioService.
  • rutas Define una lista de posibles conexiones entre dispositivos de entrada y salida o entre flujo y dispositivo.

El siguiente ejemplo define un dispositivo de salida bus0_phone_out en el que mixer_bus0_phone_out mezcla todas las transmisiones de audio de Android. La ruta lleva el flujo de salida de mixer_bus0_phone_out al dispositivo bus0_phone_out .

<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_phone_out</item>
<defaultOutputDevice>bus0_phone_out</defaultOutputDevice>
            <mixPorts>
                <mixPort name="mixport_bus0_phone_out"
                         role="source"
                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_phone_out"
                            role="sink"
                            type="AUDIO_DEVICE_OUT_BUS"
                            address="BUS00_PHONE">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400"
                                maxValueMB="4000"
                                defaultValueMB="0"
                                stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_phone_out"
                       sources="mixport_bus0_phone_out"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>