Aggiungere l'audio spaziale all'app XR

Le funzionalità audio spaziale in Jetpack SceneCore ti consentono di creare esperienze audio immersive all'interno delle tue applicazioni Android XR.

L'audio spaziale simula il modo in cui gli utenti percepiscono il suono in un ambiente 3D. Crea la sensazione che il suono provenga da tutte le direzioni, anche da 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. Man mano che l'utente si sposta nello spazio, tutto l'audio dell'app verrà emesso dal pannello su cui viene visualizzata l'interfaccia utente dell'app. Ad esempio, se un timer si attiva da un'app orologio, l'audio sembrerà provenire dalla posizione del riquadro dell'app. Android XR altererà automaticamente il suono per un realismo posizionale. Ad esempio, la distanza percepita tra il pannello delle app e l'utente influisce in modo sottile sul volume audio per un maggiore senso di realismo.

Per ulteriori informazioni su come le app esistenti eseguono il rendering dell'audio spaziale, leggi 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 audio posizionale, stereo, surround e ambisonico.

Audio posizionale

Un 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 dalle rispettive posizioni. Per il rendering dell'audio posizionale, i file devono essere mono o stereo.

Audio stereo spazializzato e audio surround

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

L'audio stereo si riferisce a formati audio con due canali, mentre l'audio surround si riferisce a formati audio con più di due canali, ad esempio 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 di strumenti diversi rispetto a quello destro.

L'audio surround viene spesso utilizzato in film e programmi televisivi per migliorare il realismo e l'immersione grazie all'utilizzo di più canali audio. Ad esempio, i dialoghi vengono spesso riprodotti da un canale dell'altoparlante centrale, mentre il suono di un elicottero in volo può utilizzare diversi canali in sequenza per dare l'impressione che l'elicottero stia volando intorno al tuo spazio 3D.

Audio ambisonico

L'audio ambisonico è come un box per l'audio, che offre un paesaggio sonoro coinvolgente per gli utenti. Utilizza l'ambisonica per i suoni ambientali di sottofondo o in 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. Ti 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 stereo e audio surround come musica e video. Consente anche la riproduzione di contenuti multimediali in background.
  • MediaPlayer: offre il modo più semplice per caricare l'audio ambisonico.
  • AudioTrack: offre il massimo controllo sul caricamento dei dati audio. Consente di scrivere direttamente i buffer audio o se hai sintetizzato o decodificato i tuoi file audio.

Aggiungere l'audio spaziale all'app

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

Esempio di audio spaziale

L'esempio seguente carica un file audio con effetti sonori in un sound pool e lo riproduce nella posizione di Entity.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities
    .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 = PointSourceParams(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 = session,
                soundPool = soundPool,
                soundID = pointSoundId,
                params = 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 spatialCapabilities.
  • 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 ne hai bisogno.

Aggiungere l'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 speaker 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, lo speaker del canale centrale si trova nella mainPanelEntity dell'app. Sono incluse le app mobile il cui audio viene spazializzato automaticamente da Android XR.

Per l'audio stereo, il posizionamento degli speaker è simile a quello dell'audio surround, tranne per il fatto che solo 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 oppure se vuoi che l'audio stereo o surround venga riprodotto rispetto a un altro Entity, puoi utilizzare PointSourceAttributes per definire la posizione del canale centrale. I canali rimanenti verranno posizionati come indicato in precedenza. In queste situazioni, devi utilizzare anche MediaPlayer.

Mentre l'utente si sposta nello spazio, gli altoparlanti virtuali stereo e surround si muovono e si regolano per garantire che siano sempre in una posizione ottimale.

Se hai configurato MediaPlayer o ExoPlayer per continuare a riprodurre audio stereo o surround in background, il posizionamento dell'altoparlante virtuale verrà modificato quando l'app viene eseguita in background. Poiché non c'è un pannello o un altro punto nello spazio a cui ancorare il suono, l'audio spaziale si sposta 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 su Entity.

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

    val pointSourceAttributes = PointSourceParams(session.scene.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.setPointSourceParams(
        session,
        mediaPlayer,
        pointSourceAttributes
    )

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()
} else {
    // The session does not have spatial audio capabilities
}

Aspetti fondamentali del codice

Aggiungere campi sonori ambisonici alla tua app

Il modo più semplice per riprodurre i campi sonori ambisonici è caricare il file con un MediaPlayer. Poiché il suono ambisonico si applica all'intero paesaggio sonoro, non devi specificare un Entity per fornire una posizione. Crea invece 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 (session.scene.spatialCapabilities.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(
        session,
        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à dell'audio spaziale sono disponibili utilizzando hasCapability().
  • L'contentType e l'utilizzo sono puramente informativi.
  • AMBISONICS_ORDER_FIRST_ORDER indica a SceneCore che il file del campo sonoro definisce quattro canali.