Aggiungere l'audio spaziale all'app XR

Le funzionalità di audio spaziale di Jetpack SceneCore ti consentono di creare esperienze audio immersive nelle tue applicazioni Android XR.

L'audio spaziale simula il modo in cui gli utenti percepiscono il suono in un ambiente 3D. Crea la sensazione di un suono proveniente da tutte le direzioni, sopra e sotto l'utente. Il sistema lo fa simulando uno o più "altoparlanti virtuali" in posizioni specifiche nello spazio 3D.

L'audio delle app esistenti che non sono state progettate o modificate per Android XR viene spazializzato automaticamente in Android XR. Quando l'utente si muove nello spazio, tutto l'audio dell'app viene emesso dal riquadro su cui viene visualizzata l'interfaccia utente dell'app. Ad esempio, se un timer si attiva da un'app orologio, l'audio sembra provenire dalla posizione del riquadro delle app. Android XR modificherà automaticamente l'audio per un realismo posizionale. Ad esempio, la distanza percepita tra il riquadro dell'app e l'utente influirà in modo sottile sul volume dell'audio per un maggiore realismo.

Per saperne di più su come le app esistenti riproducono l'audio spaziale, leggi l'articolo Aggiungere audio stereo e surround all'app in questa pagina.

Se stai ottimizzando la tua app per XR, Jetpack SceneCore fornisce strumenti per la personalizzazione avanzata dell'audio spaziale. Puoi posizionare con precisione i suoni nell'ambiente 3D, utilizzare l'audio ambisonico per campi sonori realistici e sfruttare l'integrazione dell'audio surround integrato.

Tipi di audio spaziale disponibili in Android XR

Android XR supporta l'audio posizionale, stereo, surround e ambisonico.

Audio posizionale

L'audio posizionale può essere posizionato in modo da essere riprodotto da un punto specifico nello spazio 3D. Ad esempio, puoi avere un modello 3D di un cane che abbaia all'angolo del tuo ambiente virtuale. Puoi avere più entità che emettono suoni da ciascuna delle rispettive posizioni. Per il rendering dell'audio posizionale, i file devono essere mono o stereo.

Audio stereo e surround spazializzato

Tutti i formati multimediali Android sono supportati per l'audio posizionale, stereo e surround.

L'audio stereo si riferisce ai formati audio con due canali, mentre l'audio surround si riferisce ai formati audio con più di due canali, come le configurazioni audio surround 5.1 o audio surround 7.1. I dati audio di ogni canale sono associati a un altoparlante. Ad esempio, quando riproduci musica in stereo, il canale dell'altoparlante sinistro potrebbe emettere tracce strumentali diverse rispetto a quello destro.

L'audio surround viene spesso utilizzato in film e programmi televisivi per migliorare il realismo e l'immersione tramite l'uso di più canali di altoparlanti. Ad esempio, il dialogo viene spesso riprodotto da un canale dello speaker centrale, mentre l'audio di un elicottero in volo può utilizzare canali diversi in sequenza per dare la sensazione che l'elicottero stia volando intorno al tuo spazio 3D.

Audio ambisonico

L'audio ambisonico (o ambisonica) è come una sfera celeste per l'audio, in quanto offre un paesaggio sonoro immersivo per gli utenti. Utilizza l'ambisonics per i suoni ambientali di sottofondo o altri scenari in cui vuoi replicare un campo sonoro sferico completo che circonda l'ascoltatore. Android XR supporta il formato audio ambisonic AmbiX in ambisonic di primo, secondo e terzo ordine. Consigliamo i tipi di file Opus (.ogg) e PCM/Wave (.wav).

Utilizzare l'audio spaziale con Jetpack SceneCore

L'implementazione dell'audio spaziale con Jetpack SceneCore prevede il controllo delle funzionalità spaziali e la scelta di un'API per il caricamento dell'audio spaziale.

Verificare le funzionalità spaziali

Prima di utilizzare le funzionalità di audio spaziale, verifica che Session supporti l'audio spaziale. In tutti gli snippet di codice nelle sezioni seguenti, le funzionalità vengono controllate prima di tentare di riprodurre l'audio spazializzato.

Caricare l'audio spaziale

Puoi utilizzare una delle seguenti API per caricare l'audio spaziale da utilizzare in Jetpack SceneCore.

  • SoundPool: ideali per effetti sonori brevi di dimensioni inferiori a 1 MB, vengono caricati in anticipo e possono essere utilizzati ripetutamente. Questo è un ottimo modo per caricare l'audio per l'audio posizionale.
  • ExoPlayer: ideale per caricare contenuti audio stereo e surround, come musica e video. Consente inoltre la riproduzione di contenuti multimediali in background.
  • MediaPlayer: fornisce il modo più semplice per caricare l'audio ambisonico.
  • AudioTrack: offre il massimo controllo sul modo in cui caricare i dati audio. Consente di scrivere direttamente i buffer audio o se hai sintetizzato o decodificato i tuoi file audio.

Aggiungere l'audio posizionale all'app

Le sorgenti sonore posizionali sono definite da PointSourceAttributes e da un Entity associato. La posizione e l'orientamento del Entity determinano dove viene visualizzato il PointSourceAttribute nello spazio 3D.

Esempio di audio posizionale

L'esempio seguente carica un file audio con effetto sonoro in una raccolta audio e lo riproduce nella posizione del Entity.

// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val maxVolume = 1F
    val lowPriority = 0
    val infiniteLoop = -1
    val normalSpeed = 1F

    val soundPool = SoundPool.Builder()
        .setAudioAttributes(
            AudioAttributes.Builder()
                .setContentType(CONTENT_TYPE_SONIFICATION)
                .setUsage(USAGE_ASSISTANCE_SONIFICATION)
                .build()
        )
        .build()

    val pointSource = PointSourceAttributes(entity)

    val soundEffect = appContext.assets.openFd("sounds/tiger_16db.mp3")
    val pointSoundId = soundPool.load(soundEffect, lowPriority)

    soundPool.setOnLoadCompleteListener{ soundPool, sampleId, status ->
        //wait for the sound file to be loaded into the soundPool
        if (status == 0){

            SpatialSoundPool.play(
                session = xrSession,
                soundPool = soundPool,
                soundID = pointSoundId,
                attributes = pointSource,
                volume = maxVolume,
                priority = lowPriority,
                loop = infiniteLoop,
                rate = normalSpeed
            )
        }
    }
} else {
    // The session does not have spatial audio capabilities
}

Aspetti fondamentali del codice

  • Il primo passaggio consiste nel verificare se le funzionalità di audio spaziale sono attualmente disponibili utilizzando getSpatialCapabilities().
  • Se imposti contentType su CONTENT_TYPE_SONIFICATION e usage su USAGE_ASSISTANCE_SONIFICATION, il sistema tratta questo file audio come un effetto sonoro.
  • L'esempio precedente carica il file audio nel pool immediatamente prima di utilizzarlo per mantenere il codice insieme per semplicità. Idealmente, dovresti caricare tutti gli effetti sonori in modo asincrono durante il caricamento dell'app, in modo che tutti i file audio siano disponibili nel pool quando ti servono.

Aggiungere audio stereo e surround all'app

Il modo consigliato per aggiungere audio stereo e surround alla tua app è utilizzare Exoplayer. Per saperne di più su come utilizzare l'audio spaziale con Exoplayer, consulta la guida all'audio spaziale.

Posizionamento degli altoparlanti stereo e audio surround

Con il posizionamento degli altoparlanti surround, gli altoparlanti surround virtuali sono posizionati e orientati rispetto a un altoparlante centrale, intorno all'utente in una configurazione ITU standard.

Per impostazione predefinita, l'altoparlante del canale centrale si trova nel mainPanelEntity dell'app. Sono incluse le app mobile per le quali l'audio è stato spazializzato automaticamente da Android XR.

Per l'audio stereo, la posizione degli altoparlanti è simile a quella del suono surround, tranne per il fatto che i canali sinistro e destro sono posizionati rispettivamente sul lato sinistro e destro del pannello.

Se hai più pannelli e vuoi scegliere quale emette l'audio o se vuoi che l'audio stereo o surround venga visualizzato in base a un altro Entity, puoi utilizzare PointSourceAttributes per definire la posizione del canale centrale. I canali rimanenti verranno posizionati come indicato in precedenza. In questi casi, devi utilizzare anche MediaPlayer.

Quando l'utente si sposta nella stanza, gli altoparlanti virtuali stereo e surround si spostano e si regolano per garantire che siano sempre in una posizione ottimale.

Se hai configurato MediaPlayer o ExoPlayer per continuare a riprodurre l'audio stereo o surround in background, il posizionamento degli altoparlanti virtuali verrà modificato quando l'app viene messa in background. Poiché non c'è un pannello o un altro punto nello spazio a cui ancorare il suono, l'audio spaziale si muove con l'utente (in altre parole, è "bloccato sulla testa").

Esempio di audio surround

L'esempio seguente carica un file audio 5.1 utilizzando MediaPlayer e imposta il canale centrale del file come Entity.

// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val pointSourceAttributes = PointSourceAttributes(xrSession.mainPanelEntity)

    val mediaPlayer = MediaPlayer()

    val fivePointOneAudio = appContext.assets.openFd("sounds/aac_51.ogg")
    mediaPlayer.reset()
    mediaPlayer.setDataSource(fivePointOneAudio)

    val audioAttributes =
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()

    SpatialMediaPlayer.setPointSourceAttributes(
        xrSession,
        mediaPlayer,
        pointSourceAttributes)

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()

} else {
    // The session does not have spatial audio capabilities
}

Aspetti fondamentali del codice

Aggiungere campi audio ambisonici all'app

Il modo più semplice per riprodurre i campi sonori ambisonici è caricare il file con un MediaPlayer. Poiché l'audio ambisonico si applica all'intero paesaggio sonoro, non è necessario specificare un Entity per fornire una posizione. Devi invece creare un'istanza di SoundFieldAttributes con l'ordine ambisonico appropriato che specifica il numero di canali.

Esempio di Ambionics

L'esempio seguente riproduce un campo sonoro ambisonico utilizzando MediaPlayer.

// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val soundFieldAttributes =
        SoundFieldAttributes(SpatializerConstants.AMBISONICS_ORDER_FIRST_ORDER)

    val mediaPlayer = MediaPlayer()

    val soundFieldAudio = appContext.assets.openFd("sounds/foa_basketball_16bit.wav")

    mediaPlayer.reset()
    mediaPlayer.setDataSource(soundFieldAudio)

    val audioAttributes =
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()

    SpatialMediaPlayer.setSoundFieldAttributes(
        xrSession,
        mediaPlayer,
        soundFieldAttributes)

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()

} else {
    // The session does not have spatial audio capabilities
}

Aspetti fondamentali del codice

  • Come per gli snippet precedenti, il primo passaggio consiste nel verificare se le funzionalità di audio spaziale sono attualmente disponibili utilizzando getSpatialCapabilities().
  • contentType e usage sono puramente informativi.
  • AMBISONICS_ORDER_FIRST_ORDER indica a SceneCore che il file del campo sonoro definisce quattro canali.