Jetpack SceneCore의 공간 오디오 기능을 사용하면 Android XR 애플리케이션 내에서 몰입형 오디오 환경을 만들 수 있습니다.
서라운드 오디오는 사용자가 3D 환경에서 소리를 인식하는 방식을 시뮬레이션합니다. 사용자의 위와 아래를 비롯한 모든 방향에서 소리가 나는 듯한 느낌을 줍니다. 시스템은 3D 공간의 특정 위치에서 하나 이상의 '가상 스피커'를 시뮬레이션하여 이를 실행합니다.
Android XR용으로 설계되거나 수정되지 않은 기존 앱은 Android XR에서 오디오가 자동으로 공간화됩니다. 사용자가 스페이스에서 이동하면 앱의 UI가 렌더링되는 패널에서 모든 앱 오디오가 방출됩니다. 예를 들어 시계 앱에서 타이머가 울리면 오디오가 앱 패널 위치에서 나오는 것처럼 들립니다. Android XR은 위치 사실성을 위해 사운드를 자동으로 변경합니다. 예를 들어 앱 패널과 사용자 간의 인식된 거리는 현실감을 높이기 위해 오디오 볼륨에 미묘한 영향을 미칩니다.
기존 앱이 공간 오디오를 렌더링하는 방법에 관한 자세한 내용은 이 페이지의 앱에 스테레오 및 서라운드 사운드 추가를 참고하세요.
XR용 앱을 최적화하는 경우 Jetpack SceneCore는 고급 공간 음향 맞춤설정을 위한 도구를 제공합니다. 3D 환경에서 소리를 정확하게 배치하고, 사실적인 사운드 필드를 위해 앰비소닉 오디오를 사용하고, 내장 서라운드 사운드 통합을 활용할 수 있습니다.
Android XR에서 사용할 수 있는 공간 음향 유형
Android XR은 위치, 스테레오, 서라운드 사운드, 앰비소닉 오디오를 지원합니다.
위치 오디오
위치 오디오는 3D 공간의 특정 지점에서 재생되도록 배치할 수 있습니다. 예를 들어 가상 환경의 모퉁이에 짖는 개의 3D 모델을 표시할 수 있습니다. 각 위치에서 소리를 내는 여러 항목이 있을 수 있습니다. 위치 오디오를 렌더링하려면 파일이 모노 또는 스테레오여야 합니다.
공간화된 스테레오 및 서라운드 사운드
위치, 스테레오, 서라운드 사운드에는 모든 Android 미디어 형식이 지원됩니다.
스테레오 오디오는 채널이 2개인 오디오 형식을 의미하고 서라운드 사운드는 5.1 서라운드 사운드 또는 7.1 서라운드 사운드 구성과 같이 채널이 3개 이상인 오디오 형식을 의미합니다. 각 채널의 소리 데이터는 하나의 스피커와 연결됩니다. 예를 들어 스테레오로 음악을 재생할 때 왼쪽 스피커 채널은 오른쪽과 다른 악기 트랙을 내보낼 수 있습니다.
서라운드 사운드는 여러 스피커 채널을 사용하여 현실감과 몰입도를 높이기 위해 영화와 TV 프로그램에서 자주 사용됩니다. 예를 들어 대화는 중앙 스피커 채널에서 재생되는 경우가 많지만 헬리콥터가 나는 소리는 헬리콥터가 3D 공간을 날아다니는 느낌을 주기 위해 여러 채널을 순서대로 사용할 수 있습니다.
앰비소닉 오디오
앰비소닉 오디오 (또는 앰비소닉)는 오디오용 스카이박스와 같으며 사용자에게 몰입감 있는 사운드스케이프를 제공합니다. 앰비소닉은 배경 환경 소리나 청취자를 둘러싸는 완전한 구형 음장을 복제하려는 기타 시나리오에 사용합니다. Android XR은 1차, 2차, 3차 앰비소닉에서 AmbiX 앰비소닉 오디오 형식을 지원합니다. Opus (.ogg
) 및 PCM/Wave (.wav
) 파일 형식을 사용하는 것이 좋습니다.
Jetpack SceneCore로 공간 음향 사용
Jetpack SceneCore로 서라운드 오디오를 구현하려면 서라운드 기능을 확인하고 서라운드 오디오를 로드하는 API를 선택해야 합니다.
공간 기능 확인
서라운드 오디오 기능을 사용하기 전에 Session
가 서라운드 오디오를 지원하는지 확인하세요. 다음 섹션의 모든 코드 스니펫에서 공간화된 오디오를 재생하기 전에 기능을 확인합니다.
공간 음향 로드
다음 API를 사용하여 Jetpack SceneCore에서 사용할 공간 오디오를 로드할 수 있습니다.
SoundPool
: 크기가 1MB 미만인 짧은 음향 효과에 적합하며, 미리 로드되어 소리를 반복적으로 사용할 수 있습니다. 이는 위치 오디오의 오디오를 로드하는 좋은 방법입니다.ExoPlayer
: 음악, 동영상 등 스테레오 및 서라운드 사운드 콘텐츠를 로드하는 데 적합합니다. 백그라운드 미디어 재생도 허용합니다.MediaPlayer
: 앰비소닉 오디오를 로드하는 가장 간단한 방법을 제공합니다.AudioTrack
: 오디오 데이터를 로드하는 방식을 가장 많이 제어할 수 있습니다. 오디오 버퍼를 직접 쓰거나 자체 오디오 파일을 합성 또는 디코딩할 수 있습니다.
앱에 위치 오디오 추가
위치 사운드 소스는 PointSourceParams
와 연결된 Entity
로 정의됩니다. Entity
의 위치와 방향에 따라 PointSourceParams
이 3D 공간에 렌더링되는 위치가 결정됩니다.
위치 오디오 예
다음 예에서는 사운드 효과 오디오 파일을 사운드 풀에 로드하고 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
을 구성하여 백그라운드에서 스테레오 또는 서라운드 사운드를 계속 재생하는 경우 앱이 백그라운드로 전환되면 가상 스피커 위치가 변경됩니다. 소리를 고정할 패널이나 기타 공간 내 지점이 없으므로 공간 오디오는 사용자와 함께 이동합니다 (즉, '헤드락'됨).
서라운드 사운드 예시
다음 예시에서는 MediaPlayer
를 사용하여 5.1 오디오 파일을 로드하고 파일의 센터 채널을 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
로 설정하고 용도를AudioAttributes.USAGE_MEDIA
로 설정하면 시스템에서 이 오디오 파일을 서라운드 사운드로 처리할 수 있습니다.
앱에 앰비소닉 사운드 필드 추가
앰비소닉 음장을 재생하는 가장 간단한 방법은 MediaPlayer
로 파일을 로드하는 것입니다. 앰비소닉 사운드는 전체 사운드스케이프에 적용되므로 Entity
를 지정하여 위치를 제공할 필요가 없습니다. 대신 채널 수를 지정하는 적절한 앰비소닉 순서로 SoundFieldAttributes
인스턴스를 만듭니다.
Ambionics 예시
다음 예에서는 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
은 사운드 필드 파일이 4개의 채널을 정의한다고 SceneCore에 알립니다.