Функции пространственного звука в Jetpack SceneCore позволяют создавать иммерсивные аудиоэффекты в приложениях 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 поддерживает его. Во всех фрагментах кода в следующих разделах возможности проверяются перед попыткой воспроизведения пространственного звука.
Загрузить пространственный звук
Вы можете использовать любой из следующих API, чтобы загрузить пространственный звук для использования в Jetpack SceneCore.
SoundPool– идеально подходит для коротких звуковых эффектов размером менее 1 МБ. Они загружаются заранее и могут использоваться многократно. Это отличный способ загрузки аудио для позиционного аудио.ExoPlayer– идеально подходит для загрузки стерео- и объемного звука, например музыки и видео. Также позволяет воспроизводить медиаконтент в фоновом режиме.MediaPlayer– самый простой способ загрузить амбифоническое аудио.AudioTrack– обеспечивает максимальный контроль над загрузкой аудиоданных. Позволяет напрямую записывать буферы аудио или синтезировать или декодировать собственные аудиофайлы.
Проверьте поддержку формата медиафайлов
Некоторые форматы медиафайлов поддерживаются платформой Android. Однако некоторые устройства Android XR могут поддерживать дополнительные форматы, например Dolby Atmos. Чтобы узнать, поддерживается ли формат медиафайла, используйте AudioCapabilities ExoPlayer:
val audioCapabilities = AudioCapabilities.getCapabilities( context, androidx.media3.common.AudioAttributes.DEFAULT, null, emptyList() ) 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 так, чтобы стерео- или объемный звук продолжал воспроизводиться в фоновом режиме, расположение виртуальных динамиков будет изменено, когда приложение будет работать в фоновом режиме. Поскольку в пространстве нет панели или другой точки, к которой можно привязать звук, пространственный звук перемещается вместе с пользователем (другими словами, он "привязан к голове").
Пример объемного звука
В примере ниже с помощью MediaPlayer загружается аудиофайл 5.1, а центральный канал файла устанавливается как 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 }
Важная информация о коде
- Как и в примере с позиционированием звука, сначала нужно проверить, доступны ли возможности пространственного звука, с помощью
spatialCapabilities. - Если задать для
contentTypeзначениеAudioAttributes.CONTENT_TYPE_MUSIC, а для usage –AudioAttributes.USAGE_MEDIA, система будет обрабатывать этот аудиофайл как объемный звук.
Добавление амбифонических звуковых полей в приложение
Проще всего воспроизвести амбифоническое звуковое поле, загрузив файл с помощью 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 }
Важная информация о коде
- Как и в предыдущих фрагментах кода, сначала нужно проверить, доступно ли пространственное звучание, с помощью
spatialCapabilities. contentTypeи их использование носят исключительно информационный характер.SpatializerConstants.AmbisonicsOrder.FIRST_ORDERсообщает SceneCore, что в файле звукового поля определены четыре канала.