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, l'audio di un'auto potrebbe iniziare dietro l'utente, avanzare e svanire in lontananza. 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 alla tua app a partire da Android 13 (livello API 33).
Esegui query sulle funzionalità
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 dell'uscita audio corrente. |
isAvailable() è true |
La spazializzazione è attivata? | isEnabled() è true |
È possibile spazializzare una traccia audio con i parametri specificati? | 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 output 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 verificare se è disponibile un tracker per la testa per il routing dell'uscita audio corrente, chiama isHeadTrackerAvailable()
.
Contenuti compatibili
Spatializer.canBeSpatialized()
indica se l'audio con le proprietà specificate può essere spaziale con il routing corrente del dispositivo di output. Questo metodo prende 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 contenuti sono già stati spazializzati, chiama
setIsContentSpatialized(true)
in modo che l'audio non venga elaborato due volte. In alternativa, modifica il comportamento di spazializzazione per disattivarla del tutto 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
sullo stesso formato di output previsto dal decoder. Devi anche impostare una maschera canale corrispondente 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()
.
Questo può essere utile se vuoi regolare la selezione delle tracce durante la riproduzione
utilizzando i callback del listener. Ad esempio, quando un utente connette o scollega le cuffie dal dispositivo, il callback di onSpatializerAvailableChanged
indica se l'effetto spazializzatore è disponibile per il nuovo routing dell'output audio. A questo punto, ti consigliamo di aggiornare la logica di selezione dei brani del tuo player in modo che corrisponda 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 autonoma ExoPlayer (nome pacchetto com.google.android.exoplayer2
), la versione 2.17 configura la piattaforma per l'output dell'audio spaziale, mentre la versione 2.18 introduce vincoli per il numero di canali audio.
Se utilizzi il modulo ExoPlayer della libreria Media3, (nome pacchetto
androidx.media3
), le versioni 1.0.0-beta01
e successive 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 attiva una nuova selezione della traccia per selezionare una traccia audio corrispondente alle proprietà correnti. Tieni presente che questa nuova selezione di tracce può causare un 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 sul 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() );
Se i vincoli relativi al numero di canali audio sono disattivati e i contenuti hanno più tracce audio, ExoPlayer seleziona inizialmente la traccia con il maggior numero di canali e riproducibile dal dispositivo. Ad esempio, se i contenuti contengono una traccia audio multicanale e una traccia audio stereo e il dispositivo supporta la riproduzione di entrambe, ExoPlayer seleziona la traccia multicanale. Consulta la sezione Selezione traccia audio per informazioni dettagliate 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. In alternativa, puoi personalizzare la logica di selezione delle tracce di ExoPlayer impostando i parametri di 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 dei canali 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 delle tracce 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 di spazializzazione predefinito 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 dei contenuti audio multicanale, potrebbe essere necessario configurare il numero massimo di canali che possono essere in uscita da un decodificatore audio su un numero elevato. Ciò garantisce che il decoder audio emetta un PCM multicanale per la piattaforma da spazializzare.
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. Per disattivare la spazializzazione autonomamente, indipendentemente dalla personalizzazione dell'OEM, consulta Disattivare l'audio spaziale.AudioAttributes
: l'audio è idoneo per la spazializzazione seusage
è impostato suUSAGE_MEDIA
oUSAGE_GAME
.AudioFormat
: utilizza una maschera di canali che contenga almeno i canaliAudioFormat.CHANNEL_OUT_QUAD
(anteriore sinistro, anteriore destro, posteriore sinistro e posteriore destro) per consentire la spazializzazione dell'audio. Nell'esempio riportato di seguito, utilizziamoAudioFormat.CHANNEL_OUT_5POINT1
per una traccia audio 5.1. Per una traccia audio stereo, utilizzaAudioFormat.CHANNEL_OUT_STEREO
.Se utilizzi Media3, puoi utilizzare
Util.getAudioTrackChannelConfig(int channelCount)
per convertire un conteggio dei canali in una maschera di canali.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 attivo sul 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 dispositivo wireless > Audio spaziale.
Per verificare la disponibilità dell'audio spaziale per il routing corrente, esegui il comando
adb shell dumpsys audio
sul tuo dispositivo. Mentre la riproduzione è attiva, dovresti vedere i seguenti
parametri nell'output:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)