Âm thanh không gian là một trải nghiệm âm thanh sống động, đưa người dùng vào trung tâm của hành động, giúp nội dung của bạn có âm thanh chân thực hơn. Âm thanh được "không gian hoá" để tạo hiệu ứng đa loa, tương tự như chế độ thiết lập âm thanh vòm, nhưng thông qua tai nghe.
Ví dụ: trong một bộ phim, âm thanh của một chiếc ô tô có thể bắt đầu từ phía sau người dùng, di chuyển về phía trước và biến mất ở phía xa. Trong cuộc trò chuyện video, giọng nói có thể được tách riêng và đặt xung quanh người dùng, giúp người dùng dễ dàng xác định người nói.
Nếu nội dung của bạn sử dụng một định dạng âm thanh được hỗ trợ, thì bạn có thể thêm âm thanh không gian vào ứng dụng của mình bắt đầu từ Android 13 (API cấp 33).
Truy vấn về các chức năng
Sử dụng lớp Spatializer để truy vấn hành vi và khả năng tạo hiệu ứng âm thanh không gian của thiết bị. Bắt đầu bằng cách truy xuất một phiên bản của Spatializer từ AudioManager:
Kotlin
val spatializer = audioManager.spatializer
Java
Spatializer spatializer = AudioManager.getSpatializer();
Sau khi bạn nhận được Spatializer, hãy kiểm tra 4 điều kiện phải đúng để thiết bị xuất âm thanh được mở rộng không gian:
| Tiêu chí | Kiểm tra | 
|---|---|
| Thiết bị có hỗ trợ tính năng không gian hoá không? | getImmersiveAudioLevel()không phải làSPATIALIZER_IMMERSIVE_LEVEL_NONE | 
| Có hiệu ứng âm thanh lập thể không? Phạm vi cung cấp phụ thuộc vào khả năng tương thích với chế độ định tuyến đầu ra âm thanh hiện tại. | isAvailable()làtrue | 
| Bạn có bật tính năng tạo không gian lập thể không? | isEnabled()làtrue | 
| Bản âm thanh có các thông số đã cho có thể được không gian hoá không? | canBeSpatialized()làtrue | 
Những điều kiện này có thể không được đáp ứng, chẳng hạn như nếu bản âm thanh hiện tại không có tính năng không gian hoá hoặc tính năng này bị tắt hoàn toàn trên thiết bị đầu ra âm thanh.
Theo dõi chuyển động của đầu
Với tai nghe được hỗ trợ, nền tảng này có thể điều chỉnh hiệu ứng âm thanh không gian dựa trên vị trí đầu của người dùng. Để kiểm tra xem có thiết bị theo dõi đầu nào cho chế độ định tuyến đầu ra âm thanh hiện tại hay không, hãy gọi isHeadTrackerAvailable().
Nội dung tương thích
Spatializer.canBeSpatialized()
cho biết liệu âm thanh có các thuộc tính đã cho có thể được không gian hoá bằng định tuyến thiết bị đầu ra hiện tại hay không. Phương thức này sử dụng một AudioAttributes và một AudioFormat. Cả hai đều được mô tả chi tiết hơn bên dưới.
AudioAttributes
Đối tượng AudioAttributes mô tả mục đích sử dụng của một luồng âm thanh (ví dụ: âm thanh trò chơi hoặc nội dung nghe nhìn tiêu chuẩn), cùng với hành vi phát và loại nội dung.
Khi gọi canBeSpatialized(), hãy sử dụng cùng một thực thể AudioAttributes như đã đặt cho Player của bạn. Ví dụ: nếu bạn đang dùng thư viện Jetpack Media3 và chưa tuỳ chỉnh AudioAttributes, hãy dùng AudioAttributes.DEFAULT.
Tắt âm thanh không gian
Để cho biết rằng nội dung của bạn đã được không gian hoá, hãy gọi setIsContentSpatialized(true) để âm thanh không bị xử lý hai lần. Ngoài ra, hãy điều chỉnh hành vi không gian hoá để tắt hoàn toàn không gian hoá bằng cách gọi setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER).
AudioFormat
Đối tượng AudioFormat mô tả thông tin chi tiết về định dạng và cấu hình kênh của một bản âm thanh.
Khi khởi tạo AudioFormat để truyền vào canBeSpatialized(), hãy đặt encoding thành giá trị giống như định dạng đầu ra dự kiến của bộ giải mã. Bạn cũng nên đặt một mặt nạ kênh khớp với cấu hình kênh của nội dung. Hãy tham khảo phần Hành vi mặc định của hiệu ứng không gian hoá để biết hướng dẫn về các giá trị cụ thể cần sử dụng.
Lắng nghe các thay đổi đối với Spatializer
Để theo dõi các thay đổi về trạng thái của Spatializer, bạn có thể thêm một trình nghe bằng Spatializer.addOnSpatializerStateChangedListener().
Tương tự, để theo dõi các thay đổi về trạng thái có sẵn của một thiết bị theo dõi đầu, hãy gọi Spatializer.addOnHeadTrackerAvailableListener().
Điều này có thể hữu ích nếu bạn muốn điều chỉnh lựa chọn phụ đề trong khi phát bằng các lệnh gọi lại của người nghe. Ví dụ: khi người dùng kết nối hoặc ngắt kết nối tai nghe với thiết bị, lệnh gọi lại onSpatializerAvailableChanged sẽ cho biết hiệu ứng không gian có dùng được cho tuyến đầu ra âm thanh mới hay không. Tại thời điểm này, bạn có thể cân nhắc việc cập nhật logic chọn bản phụ đề của trình phát để phù hợp với các chức năng mới của thiết bị. Để biết thông tin chi tiết về hành vi chọn lựa chọn phụ đề của ExoPlayer, hãy tham khảo phần ExoPlayer và âm thanh không gian.
ExoPlayer và âm thanh không gian
Các bản phát hành gần đây của ExoPlayer giúp bạn dễ dàng áp dụng âm thanh không gian. Nếu bạn sử dụng thư viện ExoPlayer độc lập (tên gói com.google.android.exoplayer2), thì phiên bản 2.17 sẽ định cấu hình nền tảng để xuất âm thanh được không gian hoá và phiên bản 2.18 sẽ giới thiệu các ràng buộc về số lượng kênh âm thanh.
Nếu bạn sử dụng mô-đun ExoPlayer trong thư viện Media3 (tên gói androidx.media3), thì các phiên bản 1.0.0-beta01 trở lên cũng có những nội dung cập nhật tương tự.
Sau khi cập nhật phần phụ thuộc ExoPlayer lên bản phát hành mới nhất, ứng dụng của bạn chỉ cần có nội dung có thể được không gian hoá.
Các quy tắc ràng buộc về số lượng kênh âm thanh
Khi cả 4 điều kiện đối với âm thanh không gian đều được đáp ứng, ExoPlayer sẽ chọn một bản âm thanh đa kênh. Nếu không, ExoPlayer sẽ chọn một bản âm thanh nổi.
Nếu các thuộc tính Spatializer thay đổi, ExoPlayer sẽ kích hoạt một lựa chọn mới cho bản nhạc để chọn một bản âm thanh phù hợp với các thuộc tính hiện tại. Xin lưu ý rằng lựa chọn phụ đề mới này có thể gây ra một khoảng thời gian đệm lại ngắn.
Để tắt các ràng buộc về số lượng kênh âm thanh, hãy đặt các tham số lựa chọn bản nhạc trên trình phát như minh hoạ bên dưới:
Kotlin
exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build()
Java
exoPlayer.setTrackSelectionParameters( new DefaultTrackSelector.Parameters.Builder(context) .setConstrainAudioChannelCountToDeviceCapabilities(false) .build() );
Tương tự, bạn có thể cập nhật các tham số của bộ chọn phụ đề hiện có để tắt các quy tắc ràng buộc về số lượng kênh âm thanh như sau:
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() );
Khi các ràng buộc về số lượng kênh âm thanh bị vô hiệu hoá, nếu nội dung có nhiều bản âm thanh, ExoPlayer ban đầu sẽ chọn bản có số lượng kênh cao nhất và có thể phát trên thiết bị. Ví dụ: nếu nội dung có một bản âm thanh đa kênh và một bản âm thanh nổi, đồng thời thiết bị hỗ trợ cả hai, thì ExoPlayer sẽ chọn bản đa kênh. Hãy xem phần Lựa chọn phụ đề để biết thông tin chi tiết về cách tuỳ chỉnh hành vi này.
Chọn bản âm thanh
Khi hành vi giới hạn số kênh âm thanh của ExoPlayer bị vô hiệu hoá, ExoPlayer sẽ không tự động chọn một bản âm thanh phù hợp với các thuộc tính của bộ không gian hoá trên thiết bị. Thay vào đó, bạn có thể tuỳ chỉnh logic chọn bản nhạc của ExoPlayer bằng cách đặt các tham số chọn bản nhạc trước hoặc trong khi phát. Theo mặc định, ExoPlayer sẽ chọn các bản âm thanh giống với bản âm thanh ban đầu về loại MIME (mã hoá), số lượng kênh và tốc độ lấy mẫu.
Thay đổi các thông số lựa chọn phụ đề
Để thay đổi các tham số lựa chọn phụ đề của ExoPlayer, hãy sử dụng Player.setTrackSelectionParameters().
Tương tự, bạn có thể nhận các thông số hiện tại của ExoPlayer bằng Player.getTrackSelectionParameters().
Ví dụ: để chọn một bản âm thanh nổi trong khi phát, hãy làm như sau:
Kotlin
exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters .buildUpon() .setMaxAudioChannelCount(2) .build()
Java
exoPlayer.setTrackSelectionParameters( exoPlayer.getTrackSelectionParameters() .buildUpon() .setMaxAudioChannelCount(2) .build() );
Xin lưu ý rằng việc thay đổi các tham số chọn phụ đề/âm thanh trong quá trình phát có thể khiến quá trình phát bị gián đoạn. Bạn có thể xem thêm thông tin về cách điều chỉnh các tham số lựa chọn bản nhạc của trình phát trong phần lựa chọn bản nhạc của tài liệu ExoPlayer.
Hành vi mặc định của hiệu ứng không gian hoá
Hành vi không gian hoá mặc định trong Android bao gồm những hành vi sau đây mà các OEM có thể tuỳ chỉnh:
- Chỉ nội dung đa kênh được không gian hoá, chứ không phải nội dung âm thanh nổi. Nếu không dùng ExoPlayer, tuỳ thuộc vào định dạng nội dung âm thanh nhiều kênh, bạn có thể cần định cấu hình số lượng kênh tối đa mà bộ giải mã âm thanh có thể xuất ra một số lượng lớn. Điều này đảm bảo rằng bộ giải mã âm thanh xuất ra PCM đa kênh để nền tảng có thể không gian hoá. - 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); - Để xem ví dụ thực tế, hãy xem - MediaCodecAudioRenderer.javacủa ExoPlayer. Để tự tắt tính năng không gian hoá, bất kể chế độ tuỳ chỉnh của OEM, hãy xem phần Tắt âm thanh không gian.
- AudioAttributes: Âm thanh đủ điều kiện để được chuyển đổi thành âm thanh không gian nếu- usageđược đặt thành- USAGE_MEDIAhoặc- USAGE_GAME.
- AudioFormat: Sử dụng mặt nạ kênh chứa ít nhất- AudioFormat.CHANNEL_OUT_QUADkênh (trái trước, phải trước, trái sau và phải sau) để âm thanh đủ điều kiện được không gian hoá. Trong ví dụ bên dưới, chúng tôi sử dụng- AudioFormat.CHANNEL_OUT_5POINT1cho bản âm thanh 5.1. Đối với một bản âm thanh nổi, hãy sử dụng- AudioFormat.CHANNEL_OUT_STEREO.- Nếu đang dùng Media3, bạn có thể dùng - Util.getAudioTrackChannelConfig(int channelCount)để chuyển đổi số lượng kênh thành mặt nạ kênh.- Ngoài ra, hãy đặt chế độ mã hoá thành - AudioFormat.ENCODING_PCM_16BITnếu bạn đã định cấu hình bộ giải mã để xuất PCM nhiều kênh.- 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(); 
Thử âm thanh không gian
Đảm bảo bạn đã bật tính năng âm thanh không gian trên thiết bị thử nghiệm:
- Đối với tai nghe có dây, hãy chuyển đến phần Cài đặt hệ thống > Âm thanh và rung > Âm thanh không gian.
- Đối với tai nghe không dây, hãy chuyển đến phần Cài đặt hệ thống > Thiết bị đã kết nối > Biểu tượng Cài đặt cho thiết bị không dây > Âm thanh không gian.
Để kiểm tra xem chế độ Âm thanh không gian có dùng được cho tuyến đường hiện tại hay không, hãy chạy lệnh adb shell dumpsys audio trên thiết bị của bạn. Bạn sẽ thấy các thông số sau trong kết quả khi quá trình phát đang diễn ra:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)
