Audio spaziale

L'audio spaziale è un'esperienza sonora immersiva che mette gli utenti al centro dell'azione, rendendo i contenuti più realistici. Il suono viene "spazializzato" in modo da creare un effetto multi-altoparlante, simile a una configurazione audio surround, ma tramite cuffie.

Ad esempio, in un film, il suono di un'auto potrebbe iniziare dietro l'utente, spostare in avanti e scivolare verso la distanza. In una videochiamata, le voci possono essere separate e posizionate intorno all'utente, facilitando l'identificazione degli altoparlanti.

Se i tuoi contenuti utilizzano un formato audio supportato, puoi aggiungere l'audio spaziale al tuo a partire da Android 13 (livello API 33).

Query sulle capacità

Utilizza la classe Spatializer per eseguire query sulle funzionalità e sul comportamento di spazializzazione del dispositivo. Per iniziare, recupera un'istanza di Spatializer da AudioManager:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Dopo aver ricevuto il codice Spatializer, controlla le quattro condizioni che devono essere soddisfatte per consentire al dispositivo di riprodurre audio spazializzato:

Criteri Assegno
Il dispositivo supporta la spazializzazione? getImmersiveAudioLevel() non è SPATIALIZER_IMMERSIVE_LEVEL_NONE
La spazializzazione è disponibile?
La disponibilità dipende dalla compatibilità con il routing corrente dell'uscita audio.
isAvailable() è true
La spazializzazione è attivata? isEnabled() è true
Una traccia audio con i determinati parametri può essere spaziale? canBeSpatialized() è true

Queste condizioni potrebbero non essere soddisfatte, ad esempio se la spazializzazione non è disponibile per la traccia audio corrente o è disattivata del tutto sul dispositivo di uscita audio.

Rilevamento dei movimenti della testa

Con le cuffie supportate, la piattaforma può regolare la spazializzazione dell'audio in base alla posizione della testa dell'utente. Per controllare se un tracker per la testa è disponibile per il routing dell'uscita audio corrente, isHeadTrackerAvailable()

Contenuti compatibili

Spatializer.canBeSpatialized() indica se l'audio con le proprietà specificate può essere spaziale con il l'attuale routing del dispositivo di output. Questo metodo richiede un valore AudioAttributes e AudioFormat, entrambi descritti più dettagliatamente di seguito.

AudioAttributes

Un oggetto AudioAttributes descrive l'utilizzo di uno stream audio (ad esempio audio di giochi o contenuti multimediali standard), nonché i relativi comportamenti di riproduzione e il tipo di contenuti.

Quando chiami canBeSpatialized(), utilizza la stessa istanzaAudioAttributes impostata per Player. Ad esempio, se utilizzi la libreria Jetpack Media3 e non hai personalizzato AudioAttributes, utilizza AudioAttributes.DEFAULT.

Disattivare l'audio spaziale

Per indicare che i tuoi contenuti sono già stati spazializzati, chiama setIsContentSpatialized(true) in modo che l'audio non venga elaborato due volte. In alternativa, modifica il comportamento della spazializzazione per disabilitare completamente la spazializzazione chiamando setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)

AudioFormat

Un oggetto AudioFormat descrive dettagli sul formato e sulla configurazione del canale di una traccia audio.

Quando crei un'istanza di AudioFormat da passare in canBeSpatialized(), imposta la codifica uguale al formato di output previsto dal decoder. Devi inoltre impostare Una maschera del canale che corrisponda alla configurazione del canale dei tuoi contenuti. Consulta la sezione Comportamento di spazializzazione predefinito per indicazioni sui valori specifici da utilizzare.

Tieni d'occhio le modifiche al Spatializer

Per rilevare le modifiche dello stato di Spatializer, puoi aggiungere un ascoltatore con Spatializer.addOnSpatializerStateChangedListener(). Analogamente, per rilevare le modifiche nella disponibilità di un tracker per la testa, chiama Spatializer.addOnHeadTrackerAvailableListener().

Questa opzione può essere utile se vuoi modificare la selezione dei brani durante la riproduzione utilizzando i callback dell'ascoltatore. Ad esempio, quando un utente collega o scollegano gli auricolari dal dispositivo, il callback onSpatializerAvailableChanged indica se l'effetto di spazializzazione è disponibile per il nuovo routing dell'uscita audio. A questo punto dovresti prendere in considerazione l'aggiornamento della logica di selezione del monitoraggio per adattarla alle nuove funzionalità del dispositivo. Per informazioni dettagliate sul comportamento di selezione dei canali di ExoPlayer, consulta la sezione ExoPlayer e audio spaziale.

ExoPlayer e audio spaziale

Le recenti versioni di ExoPlayer semplificano l'adozione dell'audio spaziale. Se utilizzi la libreria ExoPlayer autonoma (nome pacchetto com.google.android.exoplayer2), la versione 2.17 configura la piattaforma per l'uscita di audio spazializzato, mentre 2.18 introduce i limiti del numero di canali audio. Se utilizzi il modulo ExoPlayer della libreria Media3, (nome del pacchetto androidx.media3), versioni 1.0.0-beta01 e più recenti includono gli stessi aggiornamenti.

Dopo aver aggiornato la dipendenza ExoPlayer all'ultima release, la tua app deve solo includere contenuti che possono essere spazializzati.

Vincoli relativi al numero di canali audio

Quando tutte e quattro le condizioni per l'audio spaziale sono soddisfatte, ExoPlayer sceglie una traccia audio multicanale. In caso contrario, ExoPlayer sceglie una traccia stereo. Se le proprietà Spatializer cambiano, ExoPlayer attiverà una nuova selezione di tracce per selezionare una traccia audio che corrisponda al proprietà correnti. Tieni presente che questa nuova selezione di tracce può causare una breve periodo di rebuffering.

Per disattivare i vincoli relativi al numero di canali audio, imposta i parametri di selezione delle tracce sul player come mostrato di seguito:

Kotlin

exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context)
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  new DefaultTrackSelector.Parameters.Builder(context)
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Analogamente, puoi aggiornare i parametri di un selettore di tracce esistente per disattivare i vincoli relativi al numero di canali audio come segue:

Kotlin

val trackSelector = DefaultTrackSelector(context)
...
trackSelector.parameters = trackSelector.buildUponParameters()
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
...
trackSelector.setParameters(
  trackSelector
    .buildUponParameters()
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Con i vincoli relativi al numero di canali audio disattivati se i contenuti hanno più audio tracce, ExoPlayer seleziona inizialmente la traccia con il maggior numero di canali e può essere riprodotto dal dispositivo. Ad esempio, se i contenuti includono un una traccia audio multicanale e una traccia audio stereo; il dispositivo supporta riproducendo entrambi i brani, ExoPlayer seleziona la traccia multicanale. Consulta le Selezione delle tracce audio per i dettagli su come personalizzare questo comportamento.

Selezione della traccia audio

Quando il comportamento dei limiti del numero di canali audio di ExoPlayer è disattivato, ExoPlayer non seleziona automaticamente una traccia audio che corrisponda alle proprietà dello spazializzatore del dispositivo. Puoi invece personalizzare la logica di selezione delle tracce di ExoPlayer impostando la selezione delle tracce prima o durante la riproduzione. Per impostazione predefinita, ExoPlayer seleziona le tracce audio uguali alla traccia iniziale per quanto riguarda il tipo MIME (codifica), il numero di canali e la frequenza di campionamento.

Modificare i parametri di selezione dei canali

Per modificare i parametri di selezione delle tracce di ExoPlayer, utilizza Player.setTrackSelectionParameters() Allo stesso modo, puoi ottenere i parametri attuali di ExoPlayer con Player.getTrackSelectionParameters(). Ad esempio, per selezionare una traccia audio stereo durante la riproduzione:

Kotlin

exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
  .buildUpon()
  .setMaxAudioChannelCount(2)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  exoPlayer.getTrackSelectionParameters()
    .buildUpon()
    .setMaxAudioChannelCount(2)
    .build()
);

Tieni presente che la modifica dei parametri di selezione della traccia durante la riproduzione potrebbe causare un'interruzione della riproduzione. Per ulteriori informazioni sulla regolazione dei parametri di selezione dei canali del player, consulta la sezione Selezione dei canali della documentazione di ExoPlayer.

Comportamento di spazializzazione predefinito

Il comportamento predefinito della spazializzazione in Android include i seguenti comportamenti che possono essere personalizzati dagli OEM:

  • Solo i contenuti multicanale sono spazializzati, non quelli stereo. Se non utilizzi ExoPlayer, a seconda del formato della tua rete multicanale contenuti audio, potresti dover configurare il numero massimo di canali che può essere emesso da un decoder audio a un numero elevato. In questo modo, il decodificatore audio emette PCM multicanale per la spazializzazione della piattaforma.

    Kotlin

    val mediaFormat = MediaFormat()
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)

    Java

    MediaFormat mediaFormat = new MediaFormat();
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);

    Per un esempio pratico, consulta MediaCodecAudioRenderer.java di ExoPlayer. Disattivare la spazializzazione autonomamente, indipendentemente dall'OEM personalizzazione, vedi Disattivare l'audio spaziale.

  • AudioAttributes: l'audio è idoneo per la spazializzazione se usage è impostato su USAGE_MEDIA o USAGE_GAME.

  • AudioFormat: utilizza una maschera di canali contenente almeno i canali AudioFormat.CHANNEL_OUT_QUAD (anteriore sinistro, anteriore destro, posteriore sinistro e posteriore destro) per consentire la spazializzazione dell'audio. Nell'esempio riportato di seguito, utilizziamo AudioFormat.CHANNEL_OUT_5POINT1 per una traccia audio 5.1. Per una traccia audio stereo, usa AudioFormat.CHANNEL_OUT_STEREO.

    Se utilizzi Media3, puoi usare Util.getAudioTrackChannelConfig(int channelCount) per convertire un conteggio dei canali in una maschera del canale.

    Inoltre, imposta la codifica su AudioFormat.ENCODING_PCM_16BIT se hai configurato il decodificatore in modo che esegua l'output in PCM multicanale.

    Kotlin

    val audioFormat = AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build()

    Java

    AudioFormat audioFormat = new AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build();

Testare l'audio spaziale

Assicurati che l'audio spaziale sia abilitato sul tuo dispositivo di test:

  • Per le cuffie con cavo, vai a Impostazioni di sistema > Suoni e vibrazione > Audio immersivo.
  • Per le cuffie wireless, vai a Impostazioni di sistema > Dispositivi connessi > Icona a forma di ingranaggio per il tuo dispositivo wireless > Audio spaziale.

Per verificare la disponibilità dell'audio spaziale per il routing attuale, esegui il comando adb shell dumpsys audio sul dispositivo. Dovresti vedere i seguenti parametri nell'output quando la riproduzione è attiva:

Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)