Ajouter le son spatial à votre application XR

Les fonctionnalités d'audio spatial de Jetpack SceneCore vous permettent de créer des expériences audio immersives dans vos applications Android XR.

L'audio spatial simule la façon dont les utilisateurs perçoivent le son dans un environnement 3D. Il crée la sensation que le son émane de toutes les directions, y compris au-dessus et en dessous de l'utilisateur. Pour ce faire, le système simule un ou plusieurs "haut-parleurs virtuels" à des emplacements spécifiques dans l'espace 3D.

Les applications existantes qui n'ont pas été conçues ni modifiées pour Android XR ont leur audio spatialisé automatiquement dans Android XR. Lorsque l'utilisateur se déplace dans son espace, tous les éléments audio de l'application sont émis à partir du panneau sur lequel l'interface utilisateur de l'application est affichée. Par exemple, si un minuteur se déclenche à partir d'une application d'horloge, le son semble provenir de la position du panneau de l'application. Android XR modifie automatiquement le son pour un réalisme de position. Par exemple, la distance perçue entre le panneau de l'application et l'utilisateur aura un impact subtil sur le volume audio pour un plus grand réalisme.

Pour en savoir plus sur la façon dont les applications existantes génèrent l'audio spatial, consultez la section Ajouter le son stéréo et surround à votre application sur cette page.

Si vous optimisez votre application pour la réalité XR, Jetpack SceneCore fournit des outils de personnalisation avancée de l'audio spatial. Vous pouvez positionner précisément les sons dans l'environnement 3D, utiliser l'audio ambisonique pour des champs sonores réalistes et profiter de l'intégration du son surround intégrée.

Types de son spatial disponibles dans Android XR

Android XR est compatible avec le son spatial, stéréo, surround et ambisonique.

Audio positionnel

L'audio spatial peut être positionné pour être diffusé à partir d'un point spécifique dans l'espace 3D. Par exemple, vous pouvez ajouter un modèle 3D d'un chien qui aboie dans un coin de votre environnement virtuel. Vous pouvez avoir plusieurs entités émettant du son à partir de chacune de leurs positions respectives. Pour afficher l'audio spatial, les fichiers doivent être mono ou stéréo.

Son stéréo et surround spatialisé

Tous les formats multimédias Android sont compatibles avec le son spatial, stéréo et surround.

Le son stéréo désigne les formats audio à deux canaux, tandis que le son surround désigne les formats audio à plus de deux canaux, comme les configurations son surround 5.1 ou son surround 7.1. Les données audio de chaque canal sont associées à un locuteur. Par exemple, lorsque vous écoutez de la musique en stéréo, le canal de l'enceinte gauche peut émettre des pistes d'instruments différentes de celles de l'enceinte droite.

Le son surround est souvent utilisé dans les films et les séries télévisées pour améliorer le réalisme et l'immersion grâce à l'utilisation de plusieurs canaux d'enceintes. Par exemple, les dialogues sont souvent diffusés à partir d'un canal d'enceinte central, tandis que le son d'un hélicoptère en vol peut utiliser différents canaux de manière séquentielle pour donner l'impression que l'hélicoptère vole autour de votre espace 3D.

Audio ambisonique

L'audio ambisonique (ou ambisonics) est comme un ciel en boîte pour l'audio, offrant un paysage sonore immersif à vos utilisateurs. Utilisez l'ambisonique pour les sons ambiants de fond ou d'autres scénarios où vous souhaitez reproduire un champ sonore sphérique complet qui entoure l'auditeur. Android XR est compatible avec le format audio ambisonique AmbiX en ambisonique de premier, deuxième et troisième ordre. Nous vous recommandons les types de fichiers Opus (.ogg) et PCM/Wave (.wav).

Utiliser le son spatial avec Jetpack SceneCore

L'implémentation du son spatial avec Jetpack SceneCore implique de vérifier les fonctionnalités spatiales et de choisir une API pour charger le son spatial.

Vérifier les fonctionnalités spatiales

Avant d'utiliser les fonctionnalités de son spatial, vérifiez que Session est compatible avec le son spatial. Dans tous les extraits de code des sections suivantes, les fonctionnalités sont vérifiées avant de tenter de lire l'audio spatialisé.

Charger le son spatial

Vous pouvez utiliser l'une des API suivantes pour charger l'audio spatial à utiliser dans Jetpack SceneCore.

  • SoundPool: idéal pour les effets sonores courts de moins de 1 Mo. Ils sont chargés à l'avance et peuvent être utilisés plusieurs fois. C'est un excellent moyen de charger l'audio pour l'audio spatial.
  • ExoPlayer: idéal pour charger des contenus stéréo et surround, comme de la musique et de la vidéo. Permet également la lecture multimédia en arrière-plan.
  • MediaPlayer: fournit le moyen le plus simple de charger de l'audio ambisonique.
  • AudioTrack: offre le plus de contrôle sur le chargement des données audio. Permet d'écrire directement des tampons audio ou si vous avez synthétisé ou décodé vos propres fichiers audio.

Ajouter l'audio spatial à votre application

Les sources sonores positionnelles sont définies par PointSourceAttributes et un Entity associé. La position et l'orientation de Entity déterminent l'emplacement de l'élément PointSourceAttribute dans l'espace 3D.

Exemple d'audio positionnel

L'exemple suivant charge un fichier audio d'effet sonore dans un pool de sons et le lit à la position de l'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
}

Points clés à retenir concernant le code

  • La première étape consiste à vérifier si les fonctionnalités de son spatial sont actuellement disponibles à l'aide de getSpatialCapabilities().
  • Définir le paramètre contentType sur CONTENT_TYPE_SONIFICATION et usage sur USAGE_ASSISTANCE_SONIFICATION permet au système de traiter ce fichier audio comme un effet sonore.
  • L'exemple précédent charge le fichier audio dans le pool immédiatement avant de l'utiliser pour regrouper le code par souci de simplicité. Idéalement, vous devez charger tous vos effets sonores de manière asynchrone lorsque vous chargez votre application afin que tous les fichiers audio soient disponibles dans le pool lorsque vous en avez besoin.

Ajouter du son stéréo et surround à votre application

La méthode recommandée pour ajouter du son stéréo et surround à votre application consiste à utiliser Exoplayer. Pour en savoir plus sur l'utilisation du son spatial avec Exoplayer, consultez le guide du son spatial.

Positionnement des enceintes stéréo et surround

Avec le positionnement des enceintes de son surround, les enceintes de son surround virtuel sont positionnées et orientées par rapport à une enceinte centrale, autour de l'utilisateur dans une configuration ITU standard.

Par défaut, l'enceinte du canal central est placée sur l'mainPanelEntity de l'application. Cela inclut les applications mobiles dont l'audio est spatialisé automatiquement par Android XR.

Pour le son stéréo, le positionnement des enceintes est semblable au son surround, à l'exception des canaux gauche et droit, qui sont placés respectivement à gauche et à droite du panneau.

Si vous disposez de plusieurs panneaux et que vous souhaitez choisir celui qui émet le son, ou si vous souhaitez que le son stéréo ou surround soit affiché par rapport à un autre Entity, vous pouvez utiliser PointSourceAttributes pour définir l'emplacement du canal central. Les autres chaînes seront placées comme indiqué précédemment. Dans ce cas, vous devez également utiliser MediaPlayer.

Lorsque l'utilisateur se déplace dans son espace, les enceintes virtuelles stéréo et surround se déplacent et s'ajustent pour s'assurer qu'elles sont toujours dans une position optimale.

Si vous avez configuré MediaPlayer ou ExoPlayer pour continuer à lire le son stéréo ou surround en arrière-plan, le positionnement des enceintes virtuelles sera modifié lorsque l'application sera en arrière-plan. Étant donné qu'il n'y a pas de panneau ni d'autre point dans l'espace auquel ancrer le son, l'audio spatial se déplace avec l'utilisateur (en d'autres termes, il est "verrouillé sur la tête").

Exemple de son surround

L'exemple suivant charge un fichier audio 5.1 à l'aide de MediaPlayer et définit le canal central du fichier sur 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
}

Points clés à retenir concernant le code

Ajouter des champs sonores ambisoniques à votre application

Le moyen le plus simple de lire des champs sonores ambisoniques consiste à charger le fichier avec un MediaPlayer. Étant donné que le son ambisonique s'applique à l'ensemble du paysage sonore, vous n'avez pas besoin de spécifier un Entity pour indiquer une position. Vous devez plutôt créer une instance de SoundFieldAttributes avec l'ordre ambisonique approprié spécifiant le nombre de canaux.

Exemple d'ambionics

L'exemple suivant lit un champ sonore ambisonique à l'aide de 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
}

Points clés à retenir concernant le code

  • Comme pour les extraits de code précédents, la première étape consiste à vérifier si les fonctionnalités de son spatial sont actuellement disponibles à l'aide de getSpatialCapabilities().
  • Les valeurs contentType et usage sont purement informatives.
  • AMBISONICS_ORDER_FIRST_ORDER indique à SceneCore que le fichier de champ sonore définit quatre canaux.