Добавьте пространственный звук в свое приложение XR. Добавьте пространственный звук в свое приложение XR.

Применимые устройства XR
Данное руководство поможет вам создавать приложения для устройств XR такого типа.
XR-гарнитуры
Проводные XR-очки

Функции пространственного звука в Jetpack SceneCore позволяют создавать захватывающие звуковые впечатления в ваших приложениях для Android XR.

Пространственный звук имитирует то, как пользователи воспринимают звук в трехмерном пространстве. Он создает ощущение звука, исходящего со всех сторон, включая пространство над и под пользователем. Система делает это, имитируя одного или нескольких «виртуальных динамиков», расположенных в определенных местах трехмерного пространства.

В существующих приложениях, которые не были разработаны или модифицированы для Android XR, звук автоматически пространственно обрабатывается в Android XR. Когда пользователь перемещается в пространстве, весь звук приложения будет излучаться с панели, на которой отображается пользовательский интерфейс приложения. Например, если срабатывает таймер в приложении «Часы», звук будет казаться исходящим с панели приложения. Android XR автоматически изменяет звук для большей реалистичности позиционирования. Например, воспринимаемое расстояние между панелью приложения и пользователем будет незначительно влиять на громкость звука для большего ощущения реализма.

Для получения более подробной информации о том, как существующие приложения воспроизводят пространственный звук, прочитайте раздел «Добавление стерео и объемного звука в ваше приложение» на этой странице.

Если вы оптимизируете свое приложение для XR, Jetpack SceneCore предоставляет инструменты для расширенной настройки пространственного звука. Вы можете точно позиционировать звуки в 3D-среде, использовать амбисонический звук для создания реалистичных звуковых полей и воспользоваться преимуществами встроенной интеграции объемного звука.

Типы пространственного звука, доступные в Android XR

Android XR поддерживает позиционный, стереофонический, объемный и амбисонический звук.

Позиционный звук

Позиционный звук может воспроизводиться из определенной точки в трехмерном пространстве. Например, у вас может быть 3D-модель собаки, лающей в углу вашей виртуальной среды. У вас может быть несколько объектов, издающих звук из каждой из своих соответствующих точек. Для рендеринга позиционного звука файлы должны быть монофоническими или стереофоническими.

Пространственное стерео и объемное звучание

Поддерживаются все медиаформаты Android для позиционного, стерео и объемного звука. Помимо этих форматов, устройства Android XR могут поддерживать аудиоформаты Dolby Atmos , Dolby Digital и Dolby Digital+ .

Стереофоническое аудио — это аудиоформат с двумя каналами, а объемный звук — это аудиоформат с более чем двумя каналами, например, конфигурации 5.1 или 7.1 . Звуковые данные каждого канала связаны с одним динамиком. Например, при воспроизведении музыки в стереорежиме левый динамик может воспроизводить другие инструментальные треки, чем правый.

Объемный звук часто используется в фильмах и телешоу для повышения реализма и погружения за счет использования нескольких каналов динамиков. Например, диалоги часто воспроизводятся через центральный канал динамика, в то время как звук летящего вертолета может воспроизводиться через разные каналы последовательно, создавая ощущение, что вертолет летит в трехмерном пространстве.

Амбисонический звук

Амбисоническое аудио (или амбисоника) — это как скайбокс для звука, создающий для пользователей захватывающее звуковое пространство. Используйте амбисонику для фоновых звуков окружающей среды или других сценариев, где вы хотите воспроизвести полное сферическое звуковое поле, окружающее слушателя. Android XR поддерживает формат амбисонического аудио AmbiX в амбисонике первого, второго и третьего порядка. Мы рекомендуем файлы типов Opus ( .ogg ) и PCM/Wave ( .wav ).

Используйте пространственное аудио с Jetpack SceneCore.

Реализация пространственного звука с помощью Jetpack SceneCore включает проверку наличия пространственных возможностей и выбор API для загрузки пространственного звука.

Проверьте наличие пространственных возможностей.

Перед использованием функций пространственного звука убедитесь, что Session поддерживает пространственное звучание. Во всех фрагментах кода в следующих разделах перед попыткой воспроизведения пространственного звука проверяются соответствующие возможности.

Загрузка пространственного звука

Для загрузки пространственного звука для использования в Jetpack SceneCore можно использовать любой из следующих API.

  • SoundPool : Идеально подходит для коротких звуковых эффектов размером менее 1 МБ. Они загружаются заранее, и звуки можно использовать многократно. Это отличный способ загрузки аудио для позиционного звука.
  • ExoPlayer : Идеально подходит для загрузки стереофонического и объемного звука, такого как музыка и видео. Также позволяет воспроизводить медиафайлы в фоновом режиме.
  • MediaPlayer : Предоставляет самый простой способ загрузки амбисонического звука.
  • AudioTrack : Обеспечивает максимальный контроль над способом загрузки аудиоданных. Позволяет напрямую записывать аудиобуферы или, если вы синтезировали или декодировали собственные аудиофайлы.

Проверьте наличие поддержки форматов мультимедиа.

Некоторые медиаформаты поддерживаются платформой Android . Однако конкретное устройство Android XR может поддерживать дополнительные форматы, такие как Dolby Atmos . Чтобы узнать о поддержке медиаформатов, используйте AudioCapabilities в ExoPlayer:

val audioCapabilities = AudioCapabilities.getCapabilities(context, androidx.media3.common.AudioAttributes.DEFAULT, null)
if (audioCapabilities.supportsEncoding(C.ENCODING_AC3)) {
    // Device supports playback of the Dolby Digital media format.
}
if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3)) {
    // Device supports playback of the Dolby Digital Plus media format.
}
if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3_JOC)) {
    // Device supports playback of the Dolby Digital Plus with Dolby Atmos media format.
}

Проверка наличия этих возможностей потенциально может включать блокирующие вызовы и не должна выполняться в основном потоке .

Добавьте позиционный звук в ваше приложение.

Позиционные источники звука определяются параметрами PointSourceParams и связанным с ними Entity . Положение и ориентация Entity определяют, где PointSourceParams отображается в трехмерном пространстве. Вызовите setPointSourceParams для SpatialMediaPlayer , чтобы установить PointSourceParams и связанный с ним entity для экземпляра MediaPlayer .

Пример позиционного звука

В следующем примере аудиофайл со звуковым эффектом загружается в пул звуков и воспроизводится в позиции Entity .

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.contains(SpatialCapability.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()

    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,
                entity = entity,
                soundPool = soundPool,
                soundID = pointSoundId,
                params = pointSource,
                volume = maxVolume,
                priority = lowPriority,
                loop = infiniteLoop,
                rate = normalSpeed
            )
        }
    }
} else {
    // The session does not have spatial audio capabilities
}

Основные моменты, касающиеся кода.

  • Первый шаг — проверить наличие возможностей пространственного звука, используя spatialCapabilities .
  • Установка параметра contentType в значение CONTENT_TYPE_SONIFICATION и параметра usage в значение USAGE_ASSISTANCE_SONIFICATION позволяет системе рассматривать этот аудиофайл как звуковой эффект.
  • В приведенном выше примере аудиофайл загружается в пул непосредственно перед его использованием, чтобы код оставался единым для простоты. В идеале все звуковые эффекты следует загружать асинхронно при загрузке приложения, чтобы все аудиофайлы были доступны в пуле, когда они вам понадобятся.

Добавьте стерео и объемный звук в ваше приложение.

Рекомендуемый способ добавления стерео- и объемного звука в ваше приложение — использование Exoplayer . Для получения дополнительной информации о том, как использовать пространственное аудио с Exoplayer , обратитесь к руководству по пространственному аудио .

Расположение динамиков для стерео и объемного звука

При использовании позиционирования динамиков объемного звучания виртуальные динамики объемного звучания располагаются и ориентируются относительно центрального динамика вокруг пользователя в стандартной конфигурации ITU .

По умолчанию центральный динамик размещается на mainPanelEntity приложения. Это относится и к мобильным приложениям, в которых Android XR автоматически выполняет пространственную обработку звука.

В стереорежиме расположение динамиков аналогично объемному звуку, за исключением того, что левый и правый каналы располагаются, соответственно, с левой и правой стороны панели.

Если у вас несколько панелей и вы хотите выбрать, какая из них будет воспроизводить звук, или если вы хотите, чтобы стерео или объемный звук воспроизводился относительно другого Entity , вы можете использовать PointSourceAttributes для определения расположения центрального канала. Остальные каналы будут размещены, как указано ранее. В таких ситуациях вам также необходимо использовать MediaPlayer .

По мере перемещения пользователя в пространстве виртуальные стерео- и объемные колонки будут перемещаться и подстраиваться, чтобы всегда находиться в оптимальном положении.

Если вы настроили MediaPlayer или ExoPlayer на продолжение воспроизведения стерео или объемного звука в фоновом режиме, положение виртуальных динамиков будет изменяться при переходе приложения в фоновый режим. Поскольку нет панели или другой точки в пространстве, к которой можно было бы привязать звук, пространственный звук перемещается вместе с пользователем (другими словами, он «привязан к голове»).

Пример объемного звука

В следующем примере загружается аудиофайл в формате 5.1 с помощью MediaPlayer , и центральный канал файла устанавливается в качестве Entity .

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.contains(SpatialCapability.SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val pointSourceAttributes = PointSourceParams()

    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,
        entity = session.scene.mainPanelEntity,
    )

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

Основные моменты, касающиеся кода.

Добавьте амбисонические звуковые поля в ваше приложение.

Простейший способ воспроизведения амбисонических звуковых полей — загрузка файла с помощью MediaPlayer . Поскольку амбисонический звук применяется ко всей звуковой картине, вам не нужно указывать Entity для определения позиции. Вместо этого вы создаете экземпляр SoundFieldAttributes с соответствующим амбисоническим порядком, указывая количество каналов.

Пример Ambionics

В следующем примере воспроизводится амбисоническое звуковое поле с помощью MediaPlayer .

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.contains(SpatialCapability.SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val soundFieldAttributes =
        SoundFieldAttributes(SpatializerConstants.AmbisonicsOrder.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
}

Основные моменты, касающиеся кода.

  • Как и в предыдущих фрагментах кода, первым шагом является проверка наличия возможностей пространственного звука с помощью hasCapability() .
  • Тип contentType и информация об использовании носят исключительно информационный характер.
  • Параметр AMBISONICS_ORDER_FIRST_ORDER сообщает SceneCore, что файл звукового поля определяет четыре канала.