Audio automobilistico

Il sistema operativo Android Automotive (AAOS) si basa sullo stack audio Android principale per supportare i casi d'uso per il funzionamento come sistema di infotainment in un veicolo. AAOS è responsabile dei suoni dell'infotainment (ovvero contenuti multimediali, navigazione e comunicazioni), ma non è direttamente responsabile dei segnali acustici e degli avvisi che hanno rigidi requisiti di disponibilità e tempistica. Sebbene AAOS fornisca segnali e meccanismi per aiutare il veicolo a gestire l'audio, alla fine spetta al veicolo effettuare la chiamata su quali suoni dovrebbero essere riprodotti per il conducente e i passeggeri, garantendo che i suoni critici per la sicurezza e i suoni normativi vengano correttamente ascoltati senza interruzione.

Poiché Android gestisce l'esperienza multimediale del veicolo, le fonti multimediali esterne come il sintonizzatore radio dovrebbero essere rappresentate da app, che possono gestire il focus audio e gli eventi chiave multimediali per la fonte.

Android 11 include le seguenti modifiche al supporto audio relativo al settore automobilistico:

Suoni e stream Android

I sistemi audio automobilistici gestiscono i seguenti suoni e flussi:

Diagramma dell'architettura incentrata sul flusso

Figura 1. Diagramma dell'architettura incentrata sul flusso

Android gestisce i suoni provenienti dalle app Android, controllando tali app e indirizzandone i suoni ai dispositivi di output nell'HAL in base al tipo di suono:

  • I flussi logici , noti come sorgenti nella nomenclatura audio principale, sono contrassegnati con Attributi audio .
  • I flussi fisici , noti come dispositivi nella nomenclatura audio principale, non hanno informazioni di contesto dopo il missaggio.

Per motivi di affidabilità, i suoni esterni (provenienti da fonti indipendenti come i segnali acustici delle cinture di sicurezza) vengono gestiti all'esterno di Android, sotto l'HAL o anche in hardware separato. Gli implementatori del sistema devono fornire un mixer che accetti uno o più flussi di input audio da Android e quindi combini tali flussi in modo adeguato con le sorgenti sonore esterne richieste dal veicolo.

L'implementazione HAL e il mixer esterno sono responsabili di garantire che i suoni esterni critici per la sicurezza vengano ascoltati e di mixare i flussi forniti da Android e indirizzarli agli altoparlanti adatti.

Suoni Android

Le app possono avere uno o più lettori che interagiscono tramite le API Android standard (ad esempio, AudioManager per il controllo dello stato attivo o MediaPlayer per lo streaming) per emettere uno o più flussi logici di dati audio. Questi dati potrebbero essere mono a canale singolo o surround 7.1, ma vengono instradati e trattati come un'unica sorgente. Lo stream dell'app è associato ad AudioAttributes che forniscono suggerimenti al sistema su come esprimere l'audio.

I flussi logici vengono inviati tramite AudioService e instradati a uno (e solo uno) dei flussi di output fisici disponibili, ognuno dei quali è l'output di un mixer all'interno di AudioFlinger. Dopo che gli attributi audio sono stati mixati in un flusso fisico, non sono più disponibili.

Ogni flusso fisico viene quindi consegnato all'HAL audio per il rendering sull'hardware. Nelle app automobilistiche, l'hardware di rendering può essere costituito da codec locali (simili ai dispositivi mobili) o da un processore remoto attraverso la rete fisica del veicolo. In ogni caso, è compito dell'implementazione dell'HAL audio fornire i dati del campione effettivo e renderli udibili.

Flussi esterni

I flussi audio che non devono essere instradati tramite Android (per ragioni di certificazione o temporizzazione) potrebbero essere inviati direttamente al mixer esterno. A partire da Android 11, l'HAL è ora in grado di richiedere la messa a fuoco di questi suoni esterni per informare Android in modo che possa intraprendere azioni appropriate come mettere in pausa i contenuti multimediali o impedire ad altri di concentrarsi.

Se i flussi esterni sono fonti multimediali che dovrebbero interagire con l'ambiente sonoro generato da Android (ad esempio, interrompere la riproduzione di MP3 quando un sintonizzatore esterno è acceso), tali flussi esterni dovrebbero essere rappresentati da un'app Android. Un'app di questo tipo richiederebbe il focus audio per conto della fonte multimediale anziché dell'HAL e risponderebbe alle notifiche di focus avviando/arrestando la fonte esterna secondo necessità per adattarsi alla policy di focus di Android. L'app è anche responsabile della gestione di eventi chiave multimediali come riproduzione/pausa. Un meccanismo suggerito per controllare tali dispositivi esterni è HwAudioSource .

Dispositivi di uscita

A livello HAL audio, il tipo di dispositivo AUDIO_DEVICE_OUT_BUS fornisce un dispositivo di output generico da utilizzare nei sistemi audio del veicolo. Il dispositivo bus supporta porte indirizzabili (dove ciascuna porta è il punto finale di un flusso fisico) e dovrebbe essere l'unico tipo di dispositivo di output supportato in un veicolo.

Un'implementazione di sistema può utilizzare una porta bus per tutti i suoni Android, nel qual caso Android mescola tutto insieme e lo fornisce come un unico flusso. In alternativa, l'HAL può fornire una porta bus per ciascun CarAudioContext per consentire la consegna simultanea di qualsiasi tipo di suono. Ciò consente all'implementazione HAL di mescolare e attenuare i diversi suoni come desiderato.

L'assegnazione dei contesti audio ai dispositivi di output avviene tramite car_audio_configuration.xml .

Ingresso microfono

Durante l'acquisizione dell'audio, l'HAL audio riceve una chiamata openInputStream che include un argomento AudioSource che indica come deve essere elaborato l'input del microfono.

La sorgente VOICE_RECOGNITION (in particolare l'Assistente Google) prevede un flusso microfonico stereo con un effetto di cancellazione dell'eco (se disponibile) ma ad esso non viene applicata alcuna altra elaborazione. Si prevede che il beamforming venga eseguito dall'Assistente.

Ingresso microfono multicanale

Per acquisire l'audio da un dispositivo con più di due canali (stereo), utilizzare una maschera di indice di canale anziché una maschera di indice posizionale (come CHANNEL_IN_LEFT ). Esempio:

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

Quando sono impostati sia setChannelMask che setChannelIndexMask , AudioRecord utilizza solo il valore impostato da setChannelMask (massimo due canali).

Cattura simultanea

A partire da Android 10, il framework Android supporta l'acquisizione simultanea di input, ma con restrizioni per proteggere la privacy dell'utente. Come parte di queste restrizioni, le sorgenti virtuali come AUDIO_SOURCE_FM_TUNER vengono ignorate e come tali possono essere acquisite contemporaneamente insieme a un ingresso normale (come il microfono). Anche HwAudioSources non sono considerate parte delle restrizioni sull'acquisizione simultanea.

Le app progettate per funzionare con dispositivi AUDIO_DEVICE_IN_BUS o con dispositivi AUDIO_DEVICE_IN_FM_TUNER secondari devono fare affidamento sull'identificazione esplicita di tali dispositivi e sull'utilizzo di AudioRecord.setPreferredDevice() per ignorare la logica di selezione della sorgente predefinita di Android.

Usi audio

AAOS utilizza principalmente AudioAttributes.AttributeUsages per il routing, le regolazioni del volume e la gestione dello stato attivo. Gli utilizzi sono una rappresentazione del "perché" viene riprodotto lo streaming. Pertanto, tutti i flussi e le richieste di focus audio devono specificare un utilizzo per la riproduzione audio. Se non impostato specificatamente durante la creazione di un oggetto AudioAttributes, l'utilizzo verrà impostato per impostazione predefinita su USAGE_UNKNOWN . Anche se attualmente viene trattato allo stesso modo di USAGE_MEDIA , non si dovrebbe fare affidamento su questo comportamento per la riproduzione multimediale.

Usi del sistema

In Android 11 sono stati introdotti gli utilizzi del sistema. Questi usi si comportano in modo simile agli usi stabiliti in precedenza, tranne per il fatto che richiedono l'utilizzo di API di sistema e android.permission.MODIFY_AUDIO_ROUTING . I nuovi utilizzi del sistema sono:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Per costruire un AudioAttributes con un utilizzo del sistema, utilizzare AudioAttributes.Builder#setSystemUsage invece di setUsage . La chiamata a questo metodo con un utilizzo non di sistema comporterà la generazione di un'eccezione IllegalArgumentException . Inoltre, se su un builder sono stati impostati sia l'utilizzo che l'utilizzo del sistema, verrà generata un'eccezione IllegalArgumentException durante la creazione.

Per verificare quale utilizzo è associato a un'istanza AudioAttributes , chiama AudioAttributes#getSystemUsage . Ciò restituisce l'utilizzo o l'utilizzo del sistema associato.

Contesti audio

Per semplificare la configurazione dell'audio AAOS, utilizzi simili sono stati raggruppati in CarAudioContext . Questi contesti audio vengono utilizzati in CarAudioService per definire il routing, i gruppi di volume e la gestione del focus audio.

I contesti audio in Android 11 sono:

CarAudioContext Utilizzi degli attributi associati
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

Mappatura tra contesti e usi audio. Le righe evidenziate si riferiscono ai nuovi utilizzi del sistema .

Audio multizona

Con il settore automobilistico arriva una nuova serie di casi d'uso relativi a utenti simultanei che interagiscono con la piattaforma e cercano di consumare media separati. Ad esempio, un conducente può riprodurre musica in cabina mentre i passeggeri sul sedile posteriore guardano un video di YouTube sul display posteriore. L'audio multizona consente ciò consentendo a diverse sorgenti audio di essere riprodotte contemporaneamente in diverse aree del veicolo.

L'audio multizona a partire da Android 10 consente agli OEM di configurare l'audio in zone separate. Ciascuna zona è una raccolta di dispositivi all'interno del veicolo con i propri gruppi di volumi, configurazione di routing per contesti e gestione del focus. In questo modo, l'abitacolo principale può essere configurato come una zona audio, mentre i jack per le cuffie del display posteriore possono essere configurati come una seconda zona.

Le zone sono definite come parte di car_audio_configuration.xml . CarAudioService legge quindi la configurazione e aiuta AudioService a instradare i flussi audio in base alla zona associata. Ogni zona definisce ancora le regole per il routing in base ai contesti e all'uid delle applicazioni. Quando viene creato un lettore, CarAudioService determina per quale zona è associato il lettore e, in base all'utilizzo, a quale dispositivo AudioFlinger deve instradare l'audio.

La messa a fuoco viene inoltre mantenuta in modo indipendente per ciascuna zona audio. Ciò consente alle applicazioni in zone diverse di produrre audio in modo indipendente senza interferire tra loro, pur rispettando i cambiamenti di messa a fuoco all'interno della propria zona. CarZonesAudioFocus all'interno di CarAudioService è responsabile della gestione del focus per ciascuna zona.

Configura l'audio multizona

Figura 2. Configurazione dell'audio multizona

AudioHAL

Le implementazioni audio automobilistiche si basano sullo standard Android Audio HAL, che include quanto segue:

  • IDevice.hal . Crea flussi di input e output, gestisce il volume principale e il silenziamento e utilizza:
    • createAudioPatch . Per creare patch esterno-esterno tra dispositivi.
    • IDevice.setAudioPortConfig() per fornire volume per ogni flusso fisico.
  • IStream.hal . Insieme alle varianti di input e output, gestisce lo streaming di campioni audio da e verso l'hardware.

Tipi di dispositivi automobilistici

I seguenti tipi di dispositivi sono rilevanti per le piattaforme automobilistiche.

Tipo di dispositivo Descrizione
AUDIO_DEVICE_OUT_BUS Uscita primaria da Android (questo è il modo in cui tutto l'audio da Android viene trasmesso al veicolo). Utilizzato come indirizzo per chiarire le ambiguità dei flussi per ciascun contesto.
AUDIO_DEVICE_OUT_TELEPHONY_TX Utilizzato per l'audio instradato alla radio cellulare per la trasmissione.
AUDIO_DEVICE_IN_BUS Utilizzato per input non altrimenti classificati.
AUDIO_DEVICE_IN_FM_TUNER Utilizzato solo per l'ingresso radiodiffusione.
AUDIO_DEVICE_IN_TV_TUNER Utilizzato per un dispositivo TV, se presente.
AUDIO_DEVICE_IN_LINE Utilizzato per il jack di ingresso AUX.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Musica ricevuta tramite Bluetooth.
AUDIO_DEVICE_IN_TELEPHONY_RX Utilizzato per l'audio ricevuto dalla radio cellulare associata a una chiamata telefonica.

Configurazione dei dispositivi audio

I dispositivi audio visibili su Android devono essere definiti in /audio_policy_configuration.xml , che include i seguenti componenti:

  • nome del modulo. Supporta "primario" (utilizzato per casi d'uso automobilistici), "A2DP", "remote_submix" e "USB". Il nome del modulo e il driver audio corrispondente devono essere compilati in audio.primary.$(variant).so .
  • dispositivoPorte. Contiene un elenco di descrittori di dispositivo per tutti i dispositivi di input e output (include dispositivi collegati in modo permanente e dispositivi rimovibili) a cui è possibile accedere da questo modulo.
    • Per ciascun dispositivo di uscita, è possibile definire il controllo del guadagno che consiste in valori minimo/massimo/predefinito/incremento in millibel (1 millibel = 1/100 dB = 1/1000 bel).
    • L'attributo address su un'istanza devicePort può essere utilizzato per trovare il dispositivo, anche se sono presenti più dispositivi con lo stesso tipo di dispositivo di AUDIO_DEVICE_OUT_BUS .
  • mixPorts. Contiene un elenco di tutti i flussi di output e input esposti dall'HAL audio. Ogni istanza mixPort può essere considerata come un flusso fisico su Android AudioService.
  • itinerari. Definisce un elenco di possibili connessioni tra dispositivi di input e output o tra flusso e dispositivo.

L'esempio seguente definisce un dispositivo di output bus0_phone_out in cui tutti i flussi audio Android vengono mixati da mixer_bus0_phone_out. Il percorso porta il flusso di output di 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>