HAL per il controllo audio

Il controllo audio HAL è stato introdotto in Android 9 per Supporta i casi d'uso audio relativi al settore auto e motori. A partire da Android 14. La funzionalità Controllo audio di HAL supporta:

  • Dissolvenza e bilancia
  • Richiesta di messa a fuoco audio HAL
  • Disattivazione dell'audio e Attenuazione automatica del dispositivo
  • Variazioni del guadagno del dispositivo audio
  • Modifiche alla configurazione della porta audio

La Figura 1 mostra una panoramica generale dell'architettura dei servizi audio per automobili, in che il servizio audio dell'auto comunica con il controllo audio HAL.

Configura audio multizona

Figura 1. Configura l'audio multizona.

Dissolvenza e bilanciamento audio

In Android è stata introdotta la versione 1 del controllo audio HIDL 9 per supportare il bilanciamento e la dissolvenza audio in auto e motori d'uso diversi. A parte dagli effetti audio generici già forniti in Android, di sistema consente alle app di sistema di impostare il bilanciamento dell'audio e la dissolvenza CarAudioManager API:

class CarAudioManager {
       /**
       *   Adjust the relative volume in the front vs back of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the back through
       *   fully toward the front. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setFadeTowardFront(float value);

       /**
       *   Adjust the relative volume on the left vs right side of the vehicle cabin.
       *
       *   @param value in the range -1.0 to 1.0 for fully toward the left through
       *   fully toward the right. 0.0 means evenly balanced.
       */
       @SystemApi
       @RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
       public void setBalanceTowardRight(float value);
}

Una volta chiamate queste API, le rispettive API HAL di controllo audio vengono chiamate dal servizio audio dell'auto:

interface IAudioControl {
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway setBalanceTowardRight(float value);

       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway setFadeTowardFront(float value);
}

L'API è disponibile su tutte le versioni dell'HAL per il controllo audio, inclusa la nuova AIDL HAL.

Richiesta di messa a fuoco audio da HAL

AAOS, simile ad Android, si basa sulla partecipazione attiva delle app su contenuti audio per gestire la riproduzione audio nelle auto. Le informazioni sul focus vengono utilizzate per gestire quali stream controllare per volume e attenuazione automatica. Pertanto, per approfondire l'audio e di fornire una migliore integrazione dei suoni specifici dell'auto l'esperienza Android, sono stati introdotti i seguenti attributi audio Android 11:

  • EMERGENCY
  • SAFETY
  • VEHICLE_STATUS
  • ANNOUNCEMENT

Oltre a questa modifica, è stato aggiunto un meccanismo per i suoni che provengono da al di fuori di Android per partecipare alle richieste di messa a fuoco audio. Di conseguenza, l'audio HIDL è stata introdotta la versione 2 dell'HAL per consentire le richieste di messa a fuoco che hanno origine da dispositivi esterni ad Android:

interface IAudioControl {
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface
       *   @return closeHandle A handle to unregister observer.
       */
       registerFocusListener(IFocusListener listener)
       generates (ICloseHandle closeHandle);

       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *   @param zoneId The identifier for the audio zone that the HAL is
       *   playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred
       */
       oneway onAudioFocusChange(bitfield<AudioUsage> usage, int32_t zoneId,
       bitfield<AudioFocusChange> focusChange);
}

Dove IFocusListener viene definito come:

interface IFocusListener {
       /**
       *   Called whenever HAL is requesting focus as it is starting to play
       *   audio of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone where the HAL is
       *    requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway requestAudioFocus(bitfield<AudioUsage> usage,
       int32_t zoneId, bitfield<AudioFocusChange> focusGain);
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *    {@code AttributeUsage}
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway abandonAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId);
}

Le API riportate sopra possono essere utilizzate per richiedere e abbandonare l'audio attivo dall'HAL, rispettivamente. In risposta, il servizio audio per auto considera il focus audio richiesta e inoltra i risultati in modo asincrono IAudioControl#onAudioFocusChange.

Questa API può essere utilizzata anche per monitorare le modifiche per la richiesta di messa a fuoco audio che proviene dal controllo audio HAL. In generale, l'audio in piedi una richiesta dall'HAL è considerata attiva, diversa da un focus audio richiesta da Android, in cui viene riprodotta solo una traccia audio attiva corrispondente è considerata attiva.

Esegui la migrazione dell'HAL per il controllo audio da HIDL ad AIDL

Con l'avvento dell'AIDL e la migrazione necessaria in Android 12 (per saperne di più, consulta AIDL per HAL), il controllo audio HAL era è migrata ad AIDL. Per le API di controllo audio HIDL esistenti versione 2, la migrazione richiedevano piccoli aggiornamenti ai metodi esistenti:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   @param usage The audio usage associated with the focus change
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL is
       *        playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChange(in String usage, in int zoneId,
              in AudioFocusChange focusChange);
       /**
       *   Registers focus listener to be used by HAL for requesting and
       *   abandoning audio focus.
       *   @param listener the listener interface.
       */
       oneway void registerFocusListener(in IFocusListener listener);
       /**
       *   Control the right/left balance setting of the car speakers.
       */
       oneway void setBalanceTowardRight(in float value);
       /**
       *   Control the fore/aft fade setting of the car speakers.
       */
       oneway void setFadeTowardFront(in float value);
}

E il valore IFocusListener corrispondente:

       interface IFocusListener {
       /**
       *   Called whenever HAL is abandoning focus as it is finished playing audio
       *   of a given usage in a specific zone.
       *
       *   @param usage The audio usage for which the HAL is abandoning focus
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone that the HAL
       *        abandoning focus
       */
       oneway void abandonAudioFocus(in String usage, in int zoneId);
       /**
       *   Called whenever HAL is requesting focus as it is starting to play audio
       *        of a given usage in a specified zone.
       *
       *   @param usage The audio usage associated with the focus request
       *        {@code AttributeUsage}. See {@code audioUsage} in
       *        audio_policy_configuration.xsd for the list of allowed values.
       *   @param zoneId The identifier for the audio zone where the HAL is
       *        requesting focus
       *   @param focusGain The AudioFocusChange associated with this request.
       */
       oneway void requestAudioFocus(in String usage, in int zoneId,
              in AudioFocusChange focusGain);
}

Disattivazione gruppo di volumi

Android 12 ha introdotto la disattivazione dell'audio dei gruppi di volumi per consentire un controllo della disattivazione audio più completo durante le interazioni audio dell'utente. Questo consente al controllo audio HAL di ricevere gli eventi di disattivazione audio intercettati dall'auto servizio audio.

Per attivare la funzionalità, gli OEM devono impostare la configurazione di audioUseCarVolumeGroupMuting a true nel servizio auto config.xml:

<!-- Configuration to enable muting of individual volume groups.
If this is set to false, muting of individual volume groups is disabled,
instead muting will toggle master mute. If this is set to true, car volume
group muting is enabled and each individual volume group can be muted separately. -->
<bool name="audioUseCarVolumeGroupMuting">true</bool>

Prima di Android 13, la configurazione doveva essere sovrascritta con un overlay di risorse di runtime packages/services/Car/service/res/values/config.xml (per saperne di più, vedi Personalizzazione della build con la risorsa overlay). Da Android 13, puoi utilizzare gli overlay delle risorse della configurazione iniziale. Per saperne di più, consulta Modificare il valore delle risorse di un'app durante l'esecuzione.

Le app di sistema possono determinare se la funzione è abilitata utilizzando il comando API CarAudioManager#isAudioFeatureEnabled. Il parametro trasmesso deve essere il CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING costante. Il metodo restituisce true se la funzionalità è attiva sul dispositivo, altrimenti false.

Oltre ad abilitare la funzionalità audioUseCarVolumeGroupMuting, l'AIDL L'HAL per il controllo audio deve implementare il meccanismo di disattivazione del gruppo di volume:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   muting to.
       *
       *   This will be called in response to changes in audio mute state for each
       *   volume group and will include a {@link MutingInfo} object per audio
       *   zone that experienced a mute state event.
       *
       *   @param mutingInfos an array of {@link MutingInfo} objects for the audio
       *   zones where audio mute state has changed.
       */
       oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos);
}

Dove le informazioni di disattivazione contengono le informazioni di disattivazione pertinenti per il sistema audio:

parcelable MutingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be muted.
       */
       String[] deviceAddressesToMute;
       /**
       *   List of addresses for audio output devices that were previously be
       *   muted and should now be unmuted.
       */
       String[] deviceAddressesToUnmute;
}

AAOS prevede due diversi meccanismi per la disattivazione, basati su:

  • Eventi chiave che utilizzano l'audio KEYCODE_VOLUME_MUTE.

  • Chiamate dirette al servizio audio dell'auto utilizzando l'API di disattivazione audio di gestore audio car audio, CarAudioManager#setVolumeGroupMute.

Quando sono attivati, entrambi i meccanismi attivano l'audio della chiamata per il controllo audio HAL.

Attenuazione automatica dell'audio dell'auto

Android 12 ha introdotto l'attenuazione automatica dell'audio delle auto per ottimizzare il controllo delle la riproduzione di stream audio. Ciò consente agli OEM di implementare il proprio attenuazione automatica comportamento basato sulla configurazione audio fisica dell'auto e sulla riproduzione corrente lo stato desiderato, come stabilito dal servizio audio dell'auto.

Il meccanismo di attenuazione automatica si basa sulle modifiche apportate allo stack dello stato attivo dell'audio. Ogni volta che si verifica una modifica dello stato attivo (che sia una richiesta di impostazione dello stato attivo o l'abbandono dello stato attivo), l'audio di controllo HAL. Analogamente al supporto per la disattivazione dell'audio del gruppo del volume dell'auto, l'attenuazione automatica audio può essere attivata con il flag di configurazione audioUseHalDuckingSignals:

<!-- Configuration to enable IAudioControl#onDevicesToDuckChange API to
inform HAL when to duck. If this is set to true, the API will receive signals
indicating which output devices to duck as well as what usages are currently
holding focus. If set to false, the API will not be called. -->
<bool name="audioUseHalDuckingSignals">true</bool>

Per attivare la funzionalità, l'HAL del controllo audio AIDL deve implementare il con il segnale ricevuto dal servizio audio dell'auto:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in output devices that the HAL should apply
       *   ducking to.
       *
       *   This will be called in response to changes in audio focus, and will
       *   include a {@link DuckingInfo} object per audio zone that experienced
       *   a change in audo focus.
       *
       *   @param duckingInfos an array of {@link DuckingInfo} objects for the
       *   audio zones where audio focus has changed.
       */
       oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos);
}

Le informazioni pertinenti sul sistema audio sono contenute nell'attenuazione automatica audio informazioni:

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
}

A parte le informazioni di configurazione dell'audio dell'auto contenute negli indirizzi dei dispositivi per annullare l'operazione, le informazioni relative all'attenuazione automatica contengono anche informazioni su quale gli utilizzi degli attributi mantengono lo stato attivo. L'intenzione di questi dati è informare sistema audio in cui gli utilizzi degli attributi audio sono attivi.

Questa operazione è necessaria perché, nella configurazione dell'audio dell'auto, vengono è possibile assegnare gli attributi a un singolo dispositivo e, senza informazioni, non è chiaro quali utilizzi siano attivi.

Controllo audio AIDL HAL 2.0

Per aggiornare le API e facilitare nuove funzionalità, il controllo audio AIDL HAL È stato aggiornato alla versione 2.0 in Android 13:

  • Messa a fuoco audio con PlaybackTrackMetadata
  • Callback sui guadagni audio

I metadati di riproduzione sono definiti in android.hardware.audio.common come segue:

parcelable PlaybackTrackMetadata {
       AudioUsage usage = INVALID;
       AudioContentType contentType = UNKNOWN;
       float gain;
       AudioChannelLayout channelMask;
       AudioDevice sourceDevice;
       String[] tags;
}

Tutte le altre funzionalità della versione 1.0 del controllo audio AIDL sono rimaste e possono essere in uso. Un'eccezione riguarda il metodo di modifica dell'elemento attivo audio, come descritto in Sul metodo di modifica dell'audio attivo.

Stato attivo del controllo audio con metadati della traccia di riproduzione

Per mostrare maggiori informazioni al sistema audio sottostante l'HAL, gli aggiornamenti ora espongono PlaybackTrackMetadata. Nello specifico, l'HAL per il controllo audio è stato ampliato con una nuovo metodo:

interface IAudioControl {
       /**
       *   Notifies HAL of changes in audio focus status for focuses requested
       *   or abandoned by the HAL.
       *
       *   The HAL is not required to wait for a callback of AUDIOFOCUS_GAIN
       *   before playing audio, nor is it required to stop playing audio in the
       *   event of a AUDIOFOCUS_LOSS callback is received.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL is
       *    playing the stream in
       *   @param focusChange the AudioFocusChange that has occurred.
       */
       oneway void onAudioFocusChangeWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusChange);
}

Viene apportata una modifica simile e corrispondente a IFocusListener:

       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} is
       *   abandoning focus as playback has stopped.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       */
       oneway void abandonAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId);
       /**
       *   Called to indicate that the audio output stream associated with
       *   {@link android.hardware.audio.common.PlaybackTrackMetadata} has taken
       *   the focus as playback is starting for the corresponding stream.
       *
       *   @param playbackMetaData The output stream metadata associated with
       *    the focus request
       *   @param zoneId The identifier for the audio zone that the HAL
       *    abandoning focus
       *   @param focusGain The focus type requested.
       */
       oneway void requestAudioFocusWithMetaData(
       in PlaybackTrackMetadata playbackMetaData, in int zoneId,
       in AudioFocusChange focusGain);
}

Metodo di modifica del focus audio

Le operazioni di impostazione dello stato attivo sopra riportate funzionano allo stesso modo di quelle descritte in Audio richiesta di focus da parte dell'HAL. Solo i metadati della traccia di riproduzione dispongono di più elementi informazioni insieme agli utilizzi degli attributi audio. In generale, a meno che il necessarie le informazioni fornite dai metadati della traccia di riproduzione, la versione di Android controllo HAL può continuare a utilizzare i metodi precedenti.

Se gli sviluppatori HAL decidono di non supportare IAudioControl#onAudioFocusChangeWithMetaData, il metodo deve restituire risultati con l'errore UNKNOWN_TRANSACTION come descritto in Utilizzo dell'interfaccia con più versioni Metodi.

Il servizio audio prima chiama onAudioFocusChangeWithMetaData e quindi riprova con il metodo onAudioFocusChange se UNKNOWN_TRANSACTION di errore.

Attenuazione automatica dell'audio dell'auto con metadati della traccia di riproduzione

La versione 2.0 del controllo audio AIDL HAL ha aggiunto i metadati della traccia di riproduzione alla le informazioni sulla funzionalità Attenuazione automatica audio:

parcelable DuckingInfo {
       /**
       *   ID of the associated audio zone
       */
       int zoneId;
       /**
       *   List of addresses for audio output devices that should be ducked.
       */
       String[] deviceAddressesToDuck;
       /**
       *   List of addresses for audio output devices that were previously be
       *   ducked and should now be unducked.
       */
       String[] deviceAddressesToUnduck;
       /**
       *   List of usages currently holding focus for this audio zone.
       */
       String[] usagesHoldingFocus;
       /**
       *   List of output stream metadata associated with the current focus
       *   holder for this audio zone
       */
       @nullable PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}

L'API usagesHoldingFocus è deprecata. Gli sviluppatori ora dovrebbero utilizzare playbackMetaDataHoldingFocus per determinare l'utilizzo degli attributi audio e altri le informazioni audio. In ogni caso, il parametro usagesHoldingFocus contiene le informazioni richieste fino a quando questa opzione non verrà formalmente rimossa.

Callback guadagno audio

Per apportare modifiche audio sotto l'HAL più visibili all'AAOS in Android 13, abbiamo aggiunto un meccanismo che ti consente di comunicare l'audio cambia dal sistema audio dell'auto al servizio audio dell'auto. La espone i cambiamenti dell'indice del volume del guadagno audio con un rispettivo motivo il guadagno è cambiato:

  • Limitazioni bloccate o disattivate
  • Limitazioni
  • Restrizioni di attenuazione

Queste modifiche espongono queste restrizioni al di sotto dell'HAL car audio e, infine, a un'app di interfaccia utente di sistema per informare l'utente. L'ultima parte, l'esposizione a una possibile interfaccia utente di sistema, è stata ulteriormente ampliata Android 14 per consentire alle app UI di sistema di ottenere più facilmente queste informazioni attraverso un meccanismo di callback delle informazioni sui gruppi di volumi.

L'API HAL per il controllo audio registra il callback di guadagno come segue:

interface IAudioControl {
       /**
       *   Registers callback to be used by HAL for reporting unexpected gain(s)
       *    changed and the reason(s) why.
       *
       *   @param callback The {@link IAudioGainCallback}.
       */
       oneway void registerGainCallback(in IAudioGainCallback callback);
}

IAudioGainCallback è definito come segue:

interface IAudioGainCallback {
       /**
       *   Used to indicate that one or more audio device port gains have changed,
       *   i.e. initiated by HAL, not by CarAudioService.
       *   This is the counter part of the
       *   {@link onDevicesToDuckChange}, {@link onDevicesToMuteChange} and,
       *   {@link setAudioDeviceGainsChanged} APIs.
       *
       *   @param reasons List of reasons that triggered the given gains changed.
       *   @param gains List of gains affected by the change.
       */
       void onAudioDeviceGainsChanged(in Reasons[] reasons,
       in AudioGainConfigInfo[] gains);
}

Come evidenziato nella documentazione dell'API, il callback di guadagno viene registrato servizio car audio all'HAL per il controllo audio. Quando l'API viene chiamata dal il controllo audio HAL, il servizio audio dell'auto risponde con un'azione corrispondente (come blocco, limitazione o attenuazione dell'indice di guadagno) .

L'HAL determina quando viene chiamata l'API, principalmente per segnalare le modifiche al ottenere lo stato di indice. Nello specifico per i requisiti di legge, il sistema audio dell'auto deve eseguire l'azione richiesta e utilizzare il callback per segnalare le informazioni a il servizio audio dell'auto per consentire il consumo da parte degli utenti. Ad esempio, per mostrare una UI all'utente.

Controllo audio AIDL HAL 3.0

La versione HAL del controllo audio AIDL di Android 14 è Aggiornato alla versione 3.0 per aggiornare le API e offrire un guadagno audio più solido una funzionalità di indice. L'API Audio Control HAL consente al servizio audio di imposta e annulla l'impostazione di un IModuleChangeCallback:

interface IAudioControl {
       /**
       *   Sets callback with HAL for notifying changes to hardware module
       *   (that is: {@link android.hardware.audio.core.IModule}) configurations.
       *
       *   @param callback The {@link IModuleChangeCallback} interface to use
       *    use when new updates are available for
       */
       void setModuleChangeCallback(in IModuleChangeCallback callback);
       /**
       *   Clears module change callback
       */
       void clearModuleChangeCallback();
}

Il setModuleChangeCallback viene registrato dal servizio audio dell'auto quando o durante il ripristino in seguito a un errore. Ad esempio, un controllo audio Notifica di morte del legante HAL ricevuta dal servizio audio dell'auto. L'audio l'implementazione dell'HAL di controllo deve sostituire qualsiasi callback di modifica del modulo esistente quando viene chiamata l'API.

Per l'API clearModuleChangeCallback, l'implementazione dovrebbe cancellare il valore il callback esistente o non fare nulla se non ne esiste uno. È una buona pratica l'implementazione del controllo audio per registrare un osservatore della morte per il callback e quindi cancellare il callback se viene attivata la morte.

IModuleChangeCallback è definito come segue:

oneway interface IModuleChangeCallback {
       /**
       *   Used to indicate that one or more {@link AudioPort} configs have
       *   changed. Implementations MUST return at least one AudioPort.
       *
       *   @param audioPorts list of {@link AudioPort} that are updated
       */
       void onAudioPortsChanged(in AudioPort[] audioPorts);
}

Quando il servizio audio dell'auto registra il callback di modifica del modulo, pronto a ricevere modifiche alle porte audio tramite l'API onAudioPortChanged. La l'API può essere utilizzata per inizializzare il guadagno di volume per il sistema audio non appena il callback è registrato. Per altre variazioni del guadagno dinamico, l'API può essere chiamata in qualsiasi momento. Le modifiche corrispondenti vengono applicate e il servizio audio dell'auto viene aggiornato di conseguenza.