Skip to content

Commit 4b82c1f

Browse files
committed
Port spatial audio snippets from DAC
1 parent 1846eb4 commit 4b82c1f

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.xr.scenecore
18+
19+
import android.content.Context
20+
import android.media.AudioAttributes
21+
import android.media.AudioAttributes.CONTENT_TYPE_SONIFICATION
22+
import android.media.AudioAttributes.USAGE_ASSISTANCE_SONIFICATION
23+
import android.media.MediaPlayer
24+
import android.media.SoundPool
25+
import androidx.xr.scenecore.Entity
26+
import androidx.xr.scenecore.PointSourceAttributes
27+
import androidx.xr.scenecore.Session
28+
import androidx.xr.scenecore.SoundFieldAttributes
29+
import androidx.xr.scenecore.SpatialCapabilities
30+
import androidx.xr.scenecore.SpatialMediaPlayer
31+
import androidx.xr.scenecore.SpatialSoundPool
32+
import androidx.xr.scenecore.SpatializerConstants
33+
import androidx.xr.scenecore.getSpatialCapabilities
34+
35+
private fun playSpatialAudioAtEntity(session: Session, appContext: Context, entity: Entity) {
36+
// [START androidxr_scenecore_playSpatialAudio]
37+
// Check spatial capabilities before using spatial audio
38+
if (session.getSpatialCapabilities()
39+
.hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)
40+
) { // The session has spatial audio capabilities
41+
val maxVolume = 1F
42+
val lowPriority = 0
43+
val infiniteLoop = -1
44+
val normalSpeed = 1F
45+
46+
val soundPool = SoundPool.Builder()
47+
.setAudioAttributes(
48+
AudioAttributes.Builder()
49+
.setContentType(CONTENT_TYPE_SONIFICATION)
50+
.setUsage(USAGE_ASSISTANCE_SONIFICATION)
51+
.build()
52+
)
53+
.build()
54+
55+
val pointSource = PointSourceAttributes(entity)
56+
57+
val soundEffect = appContext.assets.openFd("sounds/tiger_16db.mp3")
58+
val pointSoundId = soundPool.load(soundEffect, lowPriority)
59+
60+
soundPool.setOnLoadCompleteListener { soundPool, sampleId, status ->
61+
// wait for the sound file to be loaded into the soundPool
62+
if (status == 0) {
63+
SpatialSoundPool.play(
64+
session = session,
65+
soundPool = soundPool,
66+
soundID = pointSoundId,
67+
attributes = pointSource,
68+
volume = maxVolume,
69+
priority = lowPriority,
70+
loop = infiniteLoop,
71+
rate = normalSpeed
72+
)
73+
}
74+
}
75+
} else {
76+
// The session does not have spatial audio capabilities
77+
}
78+
// [END androidxr_scenecore_playSpatialAudio]
79+
}
80+
81+
private fun playSpatialAudioAtEntitySurround(session: Session, appContext: Context) {
82+
// [START androidxr_scenecore_playSpatialAudioSurround]
83+
// Check spatial capabilities before using spatial audio
84+
if (session.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
85+
// The session has spatial audio capabilities
86+
87+
val pointSourceAttributes = PointSourceAttributes(session.mainPanelEntity)
88+
89+
val mediaPlayer = MediaPlayer()
90+
91+
val fivePointOneAudio = appContext.assets.openFd("sounds/aac_51.ogg")
92+
mediaPlayer.reset()
93+
mediaPlayer.setDataSource(fivePointOneAudio)
94+
95+
val audioAttributes =
96+
AudioAttributes.Builder()
97+
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
98+
.setUsage(AudioAttributes.USAGE_MEDIA)
99+
.build()
100+
101+
SpatialMediaPlayer.setPointSourceAttributes(
102+
session,
103+
mediaPlayer,
104+
pointSourceAttributes
105+
)
106+
107+
mediaPlayer.setAudioAttributes(audioAttributes)
108+
mediaPlayer.prepare()
109+
mediaPlayer.start()
110+
} else {
111+
// The session does not have spatial audio capabilities
112+
}
113+
// [END androidxr_scenecore_playSpatialAudioSurround]
114+
}
115+
116+
private fun playSpatialAudioAtEntityAmbionics(session: Session, appContext: Context) {
117+
// [START androidxr_scenecore_playSpatialAudioAmbionics]
118+
// Check spatial capabilities before using spatial audio
119+
if (session.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
120+
// The session has spatial audio capabilities
121+
122+
val soundFieldAttributes =
123+
SoundFieldAttributes(SpatializerConstants.AMBISONICS_ORDER_FIRST_ORDER)
124+
125+
val mediaPlayer = MediaPlayer()
126+
127+
val soundFieldAudio = appContext.assets.openFd("sounds/foa_basketball_16bit.wav")
128+
129+
mediaPlayer.reset()
130+
mediaPlayer.setDataSource(soundFieldAudio)
131+
132+
val audioAttributes =
133+
AudioAttributes.Builder()
134+
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
135+
.setUsage(AudioAttributes.USAGE_MEDIA)
136+
.build()
137+
138+
SpatialMediaPlayer.setSoundFieldAttributes(
139+
session,
140+
mediaPlayer,
141+
soundFieldAttributes
142+
)
143+
144+
mediaPlayer.setAudioAttributes(audioAttributes)
145+
mediaPlayer.prepare()
146+
mediaPlayer.start()
147+
} else {
148+
// The session does not have spatial audio capabilities
149+
}
150+
// [END androidxr_scenecore_playSpatialAudioAmbionics]
151+
}

0 commit comments

Comments
 (0)