เสียงรอบทิศทางคือประสบการณ์เสียงสมจริงที่ให้ผู้ใช้ได้ดื่มด่ำ ซึ่งทำให้เนื้อหาดูสมจริงมากขึ้น เสียงคือ "เชิงพื้นที่" เพื่อสร้างเอฟเฟกต์ลำโพงหลายตัว ซึ่งคล้ายกับเสียงเซอร์ราวด์ การตั้งค่า แต่เปลี่ยนผ่านหูฟังแทน
ตัวอย่างเช่น ในภาพยนตร์ เสียงจากรถอาจดังขึ้นหลังผู้ใช้ เคลื่อนที่ ไปข้างหน้า และไต่ไปอีกระดับ ในวิดีโอแชท ระบบอาจแสดงเสียง และวางไว้รอบๆ ตัวผู้ใช้ เพื่อให้ระบุผู้พูดได้ง่ายขึ้น
หากเนื้อหาของคุณใช้รูปแบบเสียงที่รองรับ คุณสามารถเพิ่มเสียงรอบทิศทางลงใน แอปที่ขึ้นต้นด้วย Android 13 (API ระดับ 33)
การค้นหาความสามารถ
ใช้ชั้นเรียน Spatializer
เพื่อ
ค้นหาความสามารถในการทำงานและลักษณะการทำงานของตำแหน่งต่างๆ ของอุปกรณ์ เริ่มด้วยการดึงข้อมูล
อินสแตนซ์ของ Spatializer
จาก
AudioManager
:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
หลังจากได้รับ Spatializer
แล้ว ให้ตรวจสอบเงื่อนไข 4 ข้อที่ต้องระงับ
เป็นจริงสำหรับอุปกรณ์ที่จะเอาต์พุตเสียงรอบทิศทาง
เกณฑ์ | ตรวจสอบ |
---|---|
อุปกรณ์รองรับการแบ่งพื้นที่หรือไม่ |
getImmersiveAudioLevel() ไม่ใช่ SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
สามารถใช้ระบบกระจายข้อมูลได้หรือไม่ ความพร้อมใช้งานขึ้นอยู่กับความเข้ากันได้กับการกำหนดเส้นทางเอาต์พุตเสียงปัจจุบัน |
isAvailable() คือ true |
มีการเปิดใช้งานเชิงพื้นที่ไหม | isEnabled() คือ true |
แทร็กเสียงที่มีพารามิเตอร์ที่ระบุสามารถทำให้เสียงรอบทิศทางได้ไหม | canBeSpatialized() คือ true |
ระบบอาจไม่ตรงตามเงื่อนไขเหล่านี้ เช่น ในกรณีที่ไม่มีข้อมูลเชิงพื้นที่ สำหรับแทร็กเสียงปัจจุบันหรือปิดการใช้งานบนอุปกรณ์เอาต์พุตเสียงทั้งหมด
การติดตามการเคลื่อนไหวของศีรษะ
สำหรับชุดหูฟังที่รองรับ แพลตฟอร์มจะสามารถปรับคุณภาพเสียง
การกระจายพื้นที่ตามตำแหน่งศีรษะของผู้ใช้ วิธีตรวจสอบว่าอุปกรณ์ติดตามการเคลื่อนไหวศีรษะ
ใช้ได้กับการกำหนดเส้นทางเอาต์พุตเสียงปัจจุบัน โทร
isHeadTrackerAvailable()
เนื้อหาที่เข้ากันได้
Spatializer.canBeSpatialized()
ระบุว่าเสียงที่มีคุณสมบัติดังต่อไปนี้ สามารถทำให้เสียงรอบทิศทางโดยใช้
การกำหนดเส้นทางอุปกรณ์เอาต์พุตปัจจุบัน เมธอดนี้ใช้ AudioAttributes
และ AudioFormat
ที่
ตามที่อธิบายไว้โดยละเอียดด้านล่าง
AudioAttributes
ออบเจ็กต์ AudioAttributes
อธิบายการใช้งานของ
สตรีมเสียง (เช่น เสียงในเกม
หรือสื่อมาตรฐาน)
รวมถึงพฤติกรรมการเล่นและประเภทเนื้อหา
เมื่อโทรหา canBeSpatialized()
ให้ใช้
AudioAttributes
อินสแตนซ์ที่ตั้งไว้สำหรับ Player
ตัวอย่างเช่น หาก
คุณกำลังใช้ไลบรารี Jetpack Media3 และไม่ได้ปรับแต่ง
AudioAttributes
ให้ใช้ AudioAttributes.DEFAULT
การปิดใช้เสียงรอบทิศทาง
หากต้องการระบุว่าเนื้อหามีการแบ่งพื้นที่แล้ว ให้เรียก
setIsContentSpatialized(true)
เพื่อให้เสียงไม่ได้รับการประมวลผล 2 ครั้ง หรือปรับ
ลักษณะการทำงานของการแบ่งพื้นที่ทางภูมิศาสตร์เพื่อปิดใช้งานการระบุตำแหน่งด้วยการเรียกใช้
setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)
AudioFormat
ออบเจ็กต์ AudioFormat
อธิบาย
รายละเอียดเกี่ยวกับรูปแบบและการกำหนดค่าช่องของแทร็กเสียง
เมื่อสร้างอินสแตนซ์ AudioFormat
เพื่อส่งผ่านไปยัง canBeSpatialized()
ตั้งค่าการเข้ารหัส
ให้เหมือนกับรูปแบบเอาต์พุตที่คาดไว้จากตัวถอดรหัส คุณควรตั้งค่า
มาสก์ของช่อง
ที่ตรงกับการกำหนดค่าช่องของเนื้อหาของคุณ โปรดดู
ส่วนลักษณะการทำงานเริ่มต้นในการแบ่งพื้นที่สำหรับแนวทางใน
ค่าที่เจาะจงที่จะใช้
ฟังการเปลี่ยนแปลงของ Spatializer
หากต้องการฟังการเปลี่ยนแปลงในสถานะของ Spatializer
คุณก็เพิ่ม Listener ได้
ด้วย Spatializer.addOnSpatializerStateChangedListener()
ในทำนองเดียวกัน หากต้องการฟังการเปลี่ยนแปลงความพร้อมให้บริการของอุปกรณ์ติดตามการเคลื่อนไหวศีรษะ
โทรหา Spatializer.addOnHeadTrackerAvailableListener()
ซึ่งจะเป็นประโยชน์หากคุณต้องการปรับการเลือกแทร็กในระหว่างการเล่น
โดยใช้ Callback ของผู้ฟัง เช่น เมื่อผู้ใช้เชื่อมต่อหรือยกเลิกการเชื่อมต่อ
ชุดหูฟังจากอุปกรณ์ onSpatializerAvailableChanged
Callback จะระบุว่ามีเอฟเฟกต์กระจายแสงสำหรับตัวแปรใหม่หรือไม่
การกำหนดเส้นทางเอาต์พุตเสียง ถึงตอนนี้ คุณอาจลองอัปเดต
ติดตามตรรกะการเลือก ให้ตรงกับความสามารถใหม่ของอุปกรณ์ สำหรับรายละเอียดเกี่ยวกับ
พฤติกรรมการเลือกแทร็กของ ExoPlayer โปรดดู ExoPlayer และเสียงรอบทิศทาง
ExoPlayer และเสียงรอบทิศทาง
ExoPlayer รุ่นล่าสุดทำให้การใช้เสียงรอบทิศทางเป็นเรื่องง่ายขึ้น หากคุณใช้
ไลบรารี ExoPlayer แบบสแตนด์อโลน (ชื่อแพ็กเกจ com.google.android.exoplayer2
)
เวอร์ชัน 2.17 จะกำหนดค่าแพลตฟอร์มให้เอาต์พุตเสียงรอบทิศทาง
2.18 เริ่มใช้ข้อจำกัดจำนวนช่องสัญญาณเสียง
หากคุณใช้โมดูล ExoPlayer จากไลบรารี Media3 (ชื่อแพ็กเกจ)
androidx.media3
) เวอร์ชัน 1.0.0-beta01
และเวอร์ชันใหม่กว่าจะมีการอัปเดตเดียวกันนี้
หลังจากอัปเดตทรัพยากร Dependency ของ ExoPlayer เป็นรุ่นล่าสุดแล้ว แอปของคุณ ต้องรวมเนื้อหาที่สามารถวางพื้นที่ได้
ข้อจำกัดจำนวนช่องสัญญาณเสียง
เมื่อตรงกับเงื่อนไขทั้ง 4 ข้อของเสียงรอบทิศทาง ExoPlayer จะเลือก
แทร็กเสียงหลายแชแนล หากไม่เลือก ExoPlayer จะเลือกแทร็กสเตอริโอแทน
หากคุณสมบัติ Spatializer
เปลี่ยนแปลง ExoPlayer
จะเรียกการเลือกแทร็กใหม่เพื่อเลือกแทร็กเสียงที่ตรงกับ
พร็อพเพอร์ตี้ปัจจุบัน โปรดทราบว่าการเลือกแทร็กใหม่นี้อาจทําให้
ระยะเวลาการบัฟเฟอร์ซ้ำ
หากต้องการปิดใช้ข้อจำกัดจำนวนช่องสัญญาณเสียง ให้ตั้งค่าพารามิเตอร์การเลือกแทร็ก ในโปรแกรมเล่นวิดีโอดังที่แสดงด้านล่าง
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
ในทำนองเดียวกัน คุณสามารถอัปเดตพารามิเตอร์ของตัวเลือกแทร็กที่มีอยู่เพื่อปิดใช้ ข้อจำกัดจำนวนช่องสัญญาณเสียงมีดังนี้
Kotlin
val trackSelector = DefaultTrackSelector(context) ... trackSelector.parameters = trackSelector.buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context); ... trackSelector.setParameters( trackSelector .buildUponParameters() .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
เมื่อปิดใช้ข้อจำกัดจำนวนช่องเสียง หากเนื้อหามีเสียงหลายรายการ แทร็ก โดย ExoPlayer จะเลือกแทร็กที่มีจำนวนช่องสูงสุดและ เล่นได้จากอุปกรณ์ ตัวอย่างเช่น หากเนื้อหามี แทร็กเสียงแบบหลายช่องและแทร็กเสียงสเตอริโอ และอุปกรณ์ที่รองรับ เล่นทั้งสองช่อง ExoPlayer จะเลือกแทร็กแบบหลายช่อง โปรดดู การเลือกแทร็กเสียงเพื่อดูรายละเอียดเกี่ยวกับวิธีปรับแต่งลักษณะการทำงานนี้
การเลือกแทร็กเสียง
เมื่อข้อจำกัดจำนวนช่องสัญญาณเสียงของ ExoPlayer การทำงานถูกปิดใช้ ExoPlayer จะไม่เลือกแทร็กเสียงให้โดยอัตโนมัติ ที่ตรงกับคุณสมบัติของตัวกระจายพื้นที่ของอุปกรณ์ อย่างไรก็ตาม คุณสามารถ ปรับแต่งตรรกะการเลือกแทร็กของ ExoPlayer โดยตั้งค่าการเลือกแทร็ก ก่อนหรือระหว่างการเล่นได้ โดยค่าเริ่มต้น ExoPlayer จะเลือกเสียง แทร็กที่เหมือนกับแทร็กเริ่มต้นที่เกี่ยวกับประเภท MIME (การเข้ารหัส) จำนวนช่อง และอัตราการสุ่มตัวอย่าง
การเปลี่ยนพารามิเตอร์การเลือกแทร็ก
หากต้องการเปลี่ยนพารามิเตอร์การเลือกแทร็กของ ExoPlayer ให้ใช้
Player.setTrackSelectionParameters()
ในทำนองเดียวกัน คุณสามารถดูพารามิเตอร์ปัจจุบันของ ExoPlayer ได้ด้วย
Player.getTrackSelectionParameters()
เช่น หากต้องการเลือกไม่ให้เล่นแทร็กเสียงสเตอริโอขณะเล่น ให้ทำดังนี้
Kotlin
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
โปรดทราบว่าการเปลี่ยนพารามิเตอร์การเลือกแทร็กกลางคันอาจทำให้ ขัดจังหวะการเล่น ข้อมูลเพิ่มเติมเกี่ยวกับการปรับแต่งแทร็กของผู้เล่น จะอยู่ใน การเลือกแทร็ก ในเอกสาร ExoPlayer
ลักษณะการทำงานเริ่มต้นของการแบ่งพื้นที่
ลักษณะการทำงานเริ่มต้นของการจัดสรรพื้นที่ใน Android มีลักษณะการทำงานดังต่อไปนี้ ที่ OEM อาจปรับแต่งได้ดังนี้
เฉพาะเนื้อหาแบบหลายช่องเท่านั้นที่มีการแบ่งพื้นที่ ไม่ใช่เนื้อหาสเตอริโอ หากคุณไม่ได้ใช้ ExoPlayer ขึ้นอยู่กับรูปแบบของหลายช่องทาง เนื้อหาเสียง คุณอาจต้องกำหนดค่าจำนวนช่องสูงสุด ซึ่งสามารถเอาต์พุตจากตัวถอดรหัสเสียงเป็นปริมาณมากได้ ซึ่งช่วยให้มั่นใจว่า ตัวถอดรหัสเสียงจะเอาต์พุต PCM แบบหลายช่องเพื่อให้แพลตฟอร์มแยกพื้นที่ได้
Kotlin
val mediaFormat = MediaFormat() mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)
Java
MediaFormat mediaFormat = new MediaFormat(); mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
ดูตัวอย่างการทำงานได้ที่
MediaCodecAudioRenderer.java
ของ ExoPlayer หากต้องการปิดการจัดเตรียมพื้นที่ด้วยตนเอง ไม่ว่า OEM จะเป็นแบบใดก็ตาม ดูการปิดใช้เสียงรอบทิศทางAudioAttributes
: เสียงมีสิทธิ์สำหรับการแบ่งพื้นที่เสียง หากusage
ตั้งค่าเป็นUSAGE_MEDIA
หรือUSAGE_GAME
AudioFormat
: ใช้มาสก์ช่องทางที่มีอย่างน้อยAudioFormat.CHANNEL_OUT_QUAD
(ด้านหน้าซ้าย ด้านหน้าขวา ด้านหลังซ้าย และด้านหลังขวา) เพื่อให้เสียง ก็มีสิทธิ์แสดงในพื้นที่ได้ ในตัวอย่างด้านล่าง เราใช้AudioFormat.CHANNEL_OUT_5POINT1
สำหรับแทร็กเสียง 5.1 สําหรับแทร็กเสียงสเตอริโอ ให้ใช้AudioFormat.CHANNEL_OUT_STEREO
หากใช้ Media3 ให้ใช้
Util.getAudioTrackChannelConfig(int channelCount)
เพื่อแปลงจำนวนช่องเป็นมาสก์ช่องทางนอกจากนี้ ให้ตั้งค่าการเข้ารหัสเป็น
AudioFormat.ENCODING_PCM_16BIT
หากคุณกำหนดค่าตัวถอดรหัสให้เอาต์พุต PCM แบบหลายช่องทางKotlin
val audioFormat = AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1) .build()
Java
AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(AudioFormat.ENCODING_PCM_16BIT) .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1) .build();
ทดสอบเสียงรอบทิศทาง
ตรวจสอบว่าได้เปิดใช้เสียงรอบทิศทางในอุปกรณ์ทดสอบโดยทำดังนี้
- สำหรับชุดหูฟังแบบมีสาย ให้ไปที่การตั้งค่าระบบ > เสียงและ การสั่น > รอบด้าน เสียง
- สำหรับชุดหูฟังไร้สาย ให้ไปที่การตั้งค่าระบบ > อุปกรณ์ที่เชื่อมต่อ > ไอคอนรูปเฟือง สำหรับอุปกรณ์ไร้สายของคุณ > เสียงรอบทิศทาง
หากต้องการตรวจสอบความพร้อมใช้งานของเสียงรอบทิศทางสำหรับการกำหนดเส้นทางปัจจุบัน ให้เรียกใช้
คำสั่ง adb shell dumpsys audio
ในอุปกรณ์ คุณควรจะเห็นสิ่งต่อไปนี้
ในเอาต์พุตขณะเล่นอยู่ ดังนี้
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)