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 un impianto audio surround, ma attraverso le cuffie.
Ad esempio, in un film, il suono di un'auto potrebbe iniziare dietro l'utente, spostarsi in avanti e svanire in lontananza. In una videochiamata, le voci possono essere separate e posizionate intorno all'utente, in modo da facilitare l'identificazione degli interlocutori.
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).
Query per le funzionalità
Utilizza la classe Spatializer
per
interrogare le funzionalità e il comportamento di spazializzazione del dispositivo. Inizia recuperando
un'istanza di Spatializer
da
AudioManager
:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Dopo aver ricevuto il Spatializer
, verifica le quattro condizioni che devono essere soddisfatte
affinché il dispositivo riproduca l'audio spazializzato:
Criteri | Assegno |
---|---|
Il dispositivo supporta la spazializzazione? |
getImmersiveAudioLevel() non è SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
È disponibile la spazializzazione? La disponibilità di dipende dalla compatibilità con il routing dell'uscita audio corrente. |
isAvailable() è true |
La spazializzazione è abilitata? | 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.
Tracciamento 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 head tracker per il routing dell'uscita audio corrente, chiama isHeadTrackerAvailable()
.
Contenuti compatibili
Spatializer.canBeSpatialized()
indica se l'audio con le proprietà specificate può essere spazializzato con il
routing del dispositivo di output corrente. Questo metodo accetta un AudioAttributes
e un AudioFormat
, entrambi descritti
in modo più dettagliato di seguito.
AudioAttributes
Un oggetto AudioAttributes
descrive l'utilizzo di un
flusso audio (ad esempio, audio di gioco
o media standard),
insieme ai suoi comportamenti di riproduzione e al tipo di contenuti.
Quando chiami canBeSpatialized()
, utilizza la stessa istanza di AudioAttributes
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, regola il
comportamento di spazializzazione per disattivarla completamente chiamando
setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
.
AudioFormat
Un oggetto AudioFormat
descrive
i dettagli sulla configurazione del formato e del canale di una traccia audio.
Quando crei un'istanza di AudioFormat
da passare a canBeSpatialized()
,
imposta la codifica
in modo che corrisponda al formato di output previsto dal decodificatore. Devi anche impostare
una maschera del canale
che corrisponda alla configurazione del canale dei tuoi contenuti. Per indicazioni sui valori specifici da utilizzare, consulta la sezione
Comportamento di spazializzazione predefinito.
Ascolta le modifiche apportate a Spatializer
Per rilevare le modifiche nello stato di Spatializer
, puoi aggiungere un listener
con Spatializer.addOnSpatializerStateChangedListener()
.
Allo stesso modo, per rilevare le modifiche nella disponibilità di un head tracker,
chiama Spatializer.addOnHeadTrackerAvailableListener()
.
Questa opzione può essere utile se vuoi regolare la selezione delle tracce durante la riproduzione
utilizzando i callback dell'ascoltatore. Ad esempio, quando un utente collega o scollega le
cuffie dal dispositivo, il callback onSpatializerAvailableChanged
indica se l'effetto spazializzatore è disponibile per il nuovo
routing dell'output audio. A questo punto, puoi prendere in considerazione l'aggiornamento della logica di selezione delle tracce del lettore in modo che corrisponda alle nuove funzionalità del dispositivo. Per informazioni dettagliate sul comportamento di selezione delle tracce di ExoPlayer, consulta la sezione ExoPlayer e audio spaziale.
ExoPlayer e audio spaziale
Le versioni recenti di ExoPlayer semplificano l'adozione dell'audio spaziale. Se utilizzi
la libreria ExoPlayer autonoma (nome del pacchetto com.google.android.exoplayer2
),
la versione 2.17 configura la piattaforma per l'output di audio spazializzato, mentre la versione
2.18 introduce vincoli sul numero di canali audio.
Se utilizzi il modulo ExoPlayer della libreria Media3 (nome del pacchetto
androidx.media3
), le versioni 1.0.0-beta01
e successive includono questi stessi aggiornamenti.
Dopo aver aggiornato la dipendenza ExoPlayer all'ultima release, la tua app deve solo includere contenuti che possono essere spazializzati.
Vincoli del conteggio dei canali audio
Quando tutte e quattro le condizioni per l'audio spaziale sono soddisfatte, ExoPlayer seleziona
una traccia audio multicanale. In caso contrario, ExoPlayer sceglie una traccia stereo.
Se le proprietà Spatializer
cambiano, ExoPlayer
attiva una nuova selezione di tracce per selezionare una traccia audio che corrisponda alle
proprietà correnti. Tieni presente che questa nuova selezione della traccia potrebbe causare un breve
periodo di ribuffer.
Per disattivare i vincoli sul conteggio dei 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() );
Allo stesso modo, puoi aggiornare i parametri di un selettore di tracce esistente per disattivare i vincoli sul numero di canali audio nel seguente modo:
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 del conteggio dei canali audio sono disattivati, se 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 della traccia audio per informazioni dettagliate su come personalizzare questo comportamento.
Selezione della traccia audio
Quando il comportamento dei vincoli sul 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 i parametri di selezione delle tracce prima o durante la riproduzione. Per impostazione predefinita, ExoPlayer seleziona le tracce audio che sono uguali alla traccia iniziale per quanto riguarda il tipo MIME (codifica), il numero di canali e la frequenza di campionamento.
Modifica dei parametri di selezione delle tracce
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 a metà 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. Per ulteriori informazioni sulla regolazione dei parametri di selezione delle tracce del player, consulta la sezione Selezione delle tracce 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 vengono spazializzati, non quelli stereo. Se non utilizzi ExoPlayer, a seconda del formato dei tuoi contenuti audio multicanale, potresti dover configurare il numero massimo di canali che un decoder audio può riprodurre su un numero elevato. In questo modo il decoder audio restituisce il 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 in azione, vedi
MediaCodecAudioRenderer.java
di ExoPlayer. Per disattivare la spazializzazione, indipendentemente dalla personalizzazione OEM, vedi Disattivare l'audio spaziale.AudioAttributes
: l'audio è idoneo per la spazializzazione seusage
è impostato suUSAGE_MEDIA
oUSAGE_GAME
.AudioFormat
: utilizza una maschera del canale che contenga almeno iAudioFormat.CHANNEL_OUT_QUAD
canali (anteriore sinistro, anteriore destro, posteriore sinistro e posteriore destro) affinché l'audio sia idoneo alla spazializzazione. 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 dei canali.Inoltre, imposta la codifica su
AudioFormat.ENCODING_PCM_16BIT
se hai configurato il decodificatore per l'output 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();
Prova l'audio spaziale
Assicurati che l'audio spaziale sia attivato sul dispositivo di test:
- Per le cuffie con cavo, vai a Impostazioni di sistema > Suoni e vibrazione > Audio spaziale.
- 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 corrente, esegui il comando
adb shell dumpsys audio
sul tuo dispositivo. Durante la riproduzione, nell'output dovresti vedere i seguenti parametri:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)