ฟีเจอร์เสียงรอบทิศทางใน Jetpack SceneCore ช่วยให้คุณสร้างประสบการณ์เสียงสมจริงภายในแอปพลิเคชัน Android XR ได้
เสียงรอบทิศทางจะจำลองวิธีที่ผู้ใช้รับรู้เสียงในสภาพแวดล้อม 3 มิติ ซึ่งจะสร้างความรู้สึกว่าเสียงมาจากทุกทิศทาง รวมถึงเหนือและใต้ผู้ใช้ โดยระบบจะจำลอง "ผู้พูดเสมือนจริง" อย่างน้อย 1 คนในตำแหน่งที่เจาะจงในพื้นที่ 3 มิติ
แอปที่มีอยู่ซึ่งไม่ได้ออกแบบหรือแก้ไขสำหรับ Android XR จะมีระบบจัดเสียงให้เป็นเสียงรอบทิศทางโดยอัตโนมัติใน Android XR เมื่อผู้ใช้ย้ายไปรอบๆ พื้นที่ทำงาน เสียงของแอปทั้งหมดจะส่งออกมาจากแผงที่มีการแสดงผล UI ของแอป เช่น หากตัวจับเวลาจากแอปนาฬิกาดังขึ้น เสียงจะดูเหมือนมาจากตำแหน่งของแผงแอป Android XR จะเปลี่ยนเสียงให้สมจริงตามตำแหน่งโดยอัตโนมัติ ตัวอย่างเช่น ระยะทางที่รับรู้ระหว่างแผงแอปกับผู้ใช้จะส่งผลต่อระดับเสียงเล็กน้อยเพื่อให้รู้สึกสมจริงยิ่งขึ้น
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่แอปที่มีอยู่แสดงผลเสียงเชิงพื้นที่ได้ที่เพิ่มเสียงสเตอริโอและเสียงเซอร์ราวด์ลงในแอปในหน้านี้
หากคุณเพิ่มประสิทธิภาพแอปสำหรับ XR อยู่ Jetpack SceneCore มีเครื่องมือสำหรับการปรับแต่งเสียงรอบทิศทางขั้นสูง คุณสามารถวางตำแหน่งเสียงในสภาพแวดล้อม 3 มิติได้อย่างแม่นยำ ใช้เสียงแบบแอมบิโซนิกส (Ambisonics) เพื่อสนามเสียงสมจริง และใช้ประโยชน์จากการผสานรวมเสียงเซอร์ราวด์ในตัว
ประเภทเสียงรอบทิศทางที่มีใน Android XR
Android XR รองรับเสียงแบบตำแหน่ง สเตอริโอ เซอร์ราวด์ และแอมบิโซนิก
เสียงตามตำแหน่ง
เสียงตามตำแหน่งสามารถกำหนดตำแหน่งให้เล่นจากจุดใดจุดหนึ่งในพื้นที่ 3 มิติ เช่น คุณอาจมีโมเดล 3 มิติของสุนัขที่กำลังเห่าอยู่ที่มุมของสภาพแวดล้อมเสมือนจริง คุณมีเอนทิตีหลายรายการที่ส่งเสียงจากตําแหน่งที่เกี่ยวข้องแต่ละตําแหน่งได้ หากต้องการแสดงผลเสียงตามตำแหน่ง ไฟล์ต้องเป็นแบบโมโนหรือสเตอริโอ
เสียงสเตอริโอและเสียงเซอร์ราวด์แบบสมจริง
รองรับรูปแบบสื่อ Android ทั้งหมดสำหรับเสียงตำแหน่ง สเตอริโอ และเซอร์ราวด์
เสียงสเตอริโอหมายถึงรูปแบบเสียงที่มี 2 ช่อง และเสียงเซอร์ราวด์หมายถึงรูปแบบเสียงที่มีมากกว่า 2 ช่อง เช่น การกำหนดค่าเสียงเซอร์ราวด์ 5.1 หรือเสียงเซอร์ราวด์ 7.1 ข้อมูลเสียงของช่องแต่ละช่องจะเชื่อมโยงกับลำโพง 1 ตัว เช่น เมื่อเล่นเพลงแบบสเตอริโอ ช่องลำโพงด้านซ้ายอาจส่งเสียงแทร็กเครื่องดนตรีที่แตกต่างจากด้านขวา
ระบบเสียงเซอร์ราวด์มักใช้ในภาพยนตร์และรายการทีวีเพื่อเพิ่มความสมจริงและประสบการณ์การรับชมด้วยการใช้ช่องลำโพงหลายช่อง ตัวอย่างเช่น เสียงสนทนามักจะเล่นจากช่องลำโพงกลาง ส่วนเสียงเฮลิคอปเตอร์บินอาจใช้ช่องต่างๆ ตามลำดับเพื่อให้รู้สึกว่าเฮลิคอปเตอร์กำลังบินอยู่รอบๆ พื้นที่ 3 มิติ
เสียงแบบแอมบิโซนิก
เสียง Ambisonic (หรือ Ambisonics) เปรียบเสมือนสกายบ็อกซ์สำหรับเสียง ซึ่งจะสร้างบรรยากาศเสียงที่สมจริงให้แก่ผู้ใช้ ใช้แอมบิโซนิกส์สำหรับเสียงสภาพแวดล้อมในเบื้องหลังหรือสถานการณ์อื่นๆ ที่ต้องการจำลองสนามเสียงแบบทรงกลมรอบตัวผู้ฟัง Android XR รองรับรูปแบบเสียงแบบแอมบิโซนิก AmbiX ในรูปแบบแอมบิโซนิกลำดับที่ 1, 2 และ 3 เราขอแนะนําให้ใช้ไฟล์ประเภท Opus (.ogg
) และ PCM/Wave (.wav
)
ใช้เสียงรอบทิศทางกับ Jetpack SceneCore
การใช้เสียงรอบทิศทางกับ Jetpack SceneCore เกี่ยวข้องกับการตรวจสอบความสามารถของเสียงรอบทิศทางและการเลือก API สำหรับการโหลดเสียงรอบทิศทาง
ตรวจสอบความสามารถเชิงพื้นที่
ก่อนใช้ฟีเจอร์เสียงรอบทิศทาง ให้ตรวจสอบว่า Session
รองรับเสียงรอบทิศทาง ข้อมูลโค้ดทั้งหมดในส่วนต่อไปนี้จะตรวจสอบความสามารถก่อนพยายามเล่นเสียงแบบเสียงรอบทิศทาง
โหลดเสียงรอบทิศทาง
คุณใช้ API ต่อไปนี้เพื่อโหลดเสียงรอบทิศทางเพื่อใช้ใน Jetpack SceneCore ได้
SoundPool
: เหมาะสำหรับซาวด์เอฟเฟกต์สั้นๆ ที่มีขนาดน้อยกว่า 1 MB ระบบจะโหลดซาวด์เอฟเฟกต์เหล่านี้ไว้ล่วงหน้าและสามารถนำเสียงไปใช้ซ้ำได้ วิธีนี้เป็นวิธีที่ยอดเยี่ยมในการโหลดเสียงสำหรับเสียงตามตำแหน่งExoPlayer
: เหมาะสำหรับการโหลดเนื้อหาเสียงสเตอริโอและเสียงเซอร์ราวด์ เช่น เพลงและวิดีโอ รวมถึงอนุญาตให้เล่นสื่อในเบื้องหลังด้วยMediaPlayer
: แสดงวิธีที่ง่ายที่สุดในการโหลดเสียงแบบแอมบิโซนิกAudioTrack
: ให้การควบคุมวิธีโหลดข้อมูลเสียงมากที่สุด อนุญาตให้เขียนบัฟเฟอร์เสียงโดยตรง หรือในกรณีที่คุณสังเคราะห์หรือถอดรหัสไฟล์เสียงของคุณเอง
เพิ่มเสียงตามตำแหน่งลงในแอป
แหล่งเสียงตามตำแหน่งจะกำหนดโดย PointSourceAttributes
และ Entity
ที่เชื่อมโยง ตำแหน่งและการวางแนวของ Entity
จะกำหนดตำแหน่งที่ระบบจะแสดงผล PointSourceAttribute
ในเชิงพื้นที่ 3 มิติ
ตัวอย่างเสียงตามตำแหน่ง
ตัวอย่างต่อไปนี้จะโหลดไฟล์เสียงเอฟเฟกต์ลงในพูลเสียงและเล่นที่ตำแหน่ง Entity
// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().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 = PointSourceAttributes(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 = xrSession,
soundPool = soundPool,
soundID = pointSoundId,
attributes = pointSource,
volume = maxVolume,
priority = lowPriority,
loop = infiniteLoop,
rate = normalSpeed
)
}
}
} else {
// The session does not have spatial audio capabilities
}
ประเด็นสำคัญเกี่ยวกับรหัส
- ขั้นตอนแรกคือตรวจสอบว่าขณะนี้ฟีเจอร์เสียงรอบทิศทางพร้อมใช้งานหรือไม่โดยใช้
getSpatialCapabilities()
- การตั้งค่า contentType เป็น
CONTENT_TYPE_SONIFICATION
และการตั้งค่าการใช้งานเป็น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 (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
// The session has spatial audio capabilities
val pointSourceAttributes = PointSourceAttributes(xrSession.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.setPointSourceAttributes(
xrSession,
mediaPlayer,
pointSourceAttributes)
mediaPlayer.setAudioAttributes(audioAttributes)
mediaPlayer.prepare()
mediaPlayer.start()
} else {
// The session does not have spatial audio capabilities
}
ประเด็นสำคัญเกี่ยวกับรหัส
- เช่นเดียวกับในตัวอย่างเสียงตามตำแหน่ง ขั้นตอนแรกคือตรวจสอบว่าขณะนี้ความสามารถของเสียงตามตำแหน่งพร้อมใช้งานหรือไม่โดยใช้
getSpatialCapabilities()
- การตั้งค่า contentType เป็น CONTENT_TYPE_MUSIC และการตั้งค่าการใช้งานเป็น USAGE_MEDIA จะช่วยให้ระบบถือว่าไฟล์เสียงนี้เป็นเสียงเซอร์ราวด์
เพิ่มฟิลด์เสียงแบบแอมบิโซนิกลงในแอป
วิธีที่ง่ายที่สุดในการเล่นเสียงแบบแอมบิโซนิกคือโหลดไฟล์ด้วย MediaPlayer
เนื่องจากเสียงแอมบิโซนิกใช้กับทั้งซาวด์สเปซ คุณจึงไม่จำเป็นต้องระบุ Entity
เพื่อระบุตำแหน่ง แต่ให้สร้างอินสแตนซ์ของ SoundFieldAttributes
ที่มีลําดับ Ambisonic ที่เหมาะสมซึ่งระบุจํานวนช่องแทน
ตัวอย่าง Ambionics
ตัวอย่างต่อไปนี้เล่นฟิลด์เสียงแบบแอมบิโซนิกโดยใช้ MediaPlayer
// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().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(
xrSession,
mediaPlayer,
soundFieldAttributes)
mediaPlayer.setAudioAttributes(audioAttributes)
mediaPlayer.prepare()
mediaPlayer.start()
} else {
// The session does not have spatial audio capabilities
}
ประเด็นสำคัญเกี่ยวกับรหัส
- เช่นเดียวกับข้อมูลโค้ดก่อนหน้า ขั้นตอนแรกคือตรวจสอบว่าขณะนี้มีความสามารถของเสียงรอบทิศทางให้ใช้งานหรือไม่โดยใช้
getSpatialCapabilities()
- contentType และการใช้งานมีไว้เพื่อแจ้งข้อมูลเท่านั้น
AMBISONICS_ORDER_FIRST_ORDER
จะส่งสัญญาณให้ SceneCore ทราบว่าไฟล์สนามเสียงกำหนดแชแนล 4 ช่อง