Функции пространственного звука в Jetpack SceneCore позволяют вам создавать захватывающие звуковые эффекты в приложениях Android XR.
Пространственный звук имитирует восприятие звука пользователями в трёхмерном пространстве. Он создаёт ощущение звука, исходящего со всех сторон, в том числе сверху и снизу от пользователя. Система делает это, имитируя один или несколько «виртуальных динамиков» в определённых точках трёхмерного пространства.
В существующих приложениях, не разработанных или не модифицированных для Android XR, звук автоматически пространственно локализуется в Android XR. При перемещении пользователя по экрану весь звук приложения будет воспроизводиться с панели, на которой отображается пользовательский интерфейс. Например, если в приложении с часами срабатывает таймер, звук будет звучать так, как будто он исходит с панели приложения. Android XR автоматически изменяет звук для достижения позиционного реализма. Например, воспринимаемое расстояние между панелью приложения и пользователем будет слегка влиять на громкость звука, создавая более реалистичное ощущение.
Дополнительную информацию о том, как существующие приложения воспроизводят пространственный звук, можно найти в статье «Добавление стерео и объемного звука в ваше приложение» на этой странице.
Если вы оптимизируете своё приложение для XR, Jetpack SceneCore предоставляет инструменты для расширенной настройки пространственного звука. Вы можете точно позиционировать звуки в трёхмерной среде, использовать объемный звук для создания реалистичных звуковых полей и воспользоваться встроенной интеграцией объёмного звука.
Типы пространственного звука, доступные в 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
отображается в трёхмерном пространстве.
Пример позиционного звука
В следующем примере аудиофайл со звуковым эффектом загружается в звуковой пул и воспроизводится в позиции 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 }
Ключевые моменты кода
- Первый шаг — проверить, доступны ли в данный момент возможности пространственного звука, с помощью
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.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 }
Ключевые моменты кода
- Как и в примере с позиционным звуком , первым шагом является проверка доступности возможностей пространственного звука с помощью
spatialCapabilities
. - Установка
contentType
наAudioAttributes.CONTENT_TYPE_MUSIC
и usage наAudioAttributes.USAGE_MEDIA
позволяет системе обрабатывать этот аудиофайл как объемный звук.
Добавьте объемные звуковые поля в свое приложение
Самый простой способ воспроизвести звуковые поля с эффектом амбисонического звучания — загрузить файл с помощью MediaPlayer
. Поскольку амбисоническое звучание применяется ко всему звуковому ландшафту, вам не нужно указывать Entity
для определения позиции. Вместо этого вы создаёте экземпляр SoundFieldAttributes
с соответствующим порядком амбисонического звучания, определяющим количество каналов.
Пример амбионики
В следующем примере воспроизводится объемное звуковое поле с помощью 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 }
Ключевые моменты кода
- Как и в предыдущих фрагментах, первым шагом является проверка доступности возможностей пространственного звука с помощью
hasCapability()
. - Тип
contentType
и использование носят исключительно информационный характер. -
AMBISONICS_ORDER_FIRST_ORDER
сигнализирует SceneCore о том, что файл звукового поля определяет четыре канала.