Âm thanh không gian là trải nghiệm âm thanh sống động, đặt người dùng vào trung tâm của hành động, giúp nội dung của bạn nghe chân thực hơn. Âm thanh được "tạo không gian" để tạo hiệu ứng đa loa, tương tự như 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 xe có thể bắt đầu từ phía sau người dùng, di chuyển về phía trước và dần biến mất ở phía xa. Trong một cuộc trò chuyện video, giọng nói có thể được tách biệt và đặt xung quanh người dùng, giúp dễ dàng xác định người nói.
Nếu nội dung của bạn sử dụng định dạng âm thanh được hỗ trợ, 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 (cấp độ API 33).
Truy vấn khả năng
Sử dụng lớp Spatializer để
truy vấn khả năng và hành vi tạo không gian của thiết bị. Bắt đầu bằng cách truy xuất
một thực thể 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 ra âm thanh được tạo không gian:
| Tiêu chí | Kiểm tra |
|---|---|
| Thiết bị có hỗ trợ tạo không gian không? |
getImmersiveAudioLevel() không phải là SPATIALIZER_IMMERSIVE_LEVEL_NONE
|
| Tính năng tạo không gian có dùng được không? Khả năng sử dụng phụ thuộc vào khả năng tương thích với định tuyến đầu ra âm thanh hiện tại. |
isAvailable() là true |
| Tính năng tạo không gian có được bật không? | isEnabled() là true |
| Bản âm thanh có các tham số đã cho có thể được tạo không gian không? | canBeSpatialized() là true |
Các điều kiện này có thể không được đáp ứng, ví dụ: nếu tính năng tạo không gian không dùng được cho bản âm thanh hiện tại hoặc bị tắt hoàn toàn trên thiết bị đầu ra âm thanh.
Theo dõi cử động đầu
Với tai nghe được hỗ trợ, nền tảng có thể điều chỉnh tính năng tạo không gian của âm thanh dựa trên vị trí đầu của người dùng. Để kiểm tra xem trình theo dõi chuyển động của đầu có
dùng được cho đị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 tạo không gian 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 AudioAttributes
và AudioFormat, cả hai đều được
mô tả chi tiết hơn bên dưới.
AudioAttributes
Đối tượng AudioAttributes mô tả việc sử dụng 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 của luồng âm thanh đó.
Khi gọi canBeSpatialized(), hãy sử dụng cùng một
AudioAttributes thực thể như đã đặt cho Player. Ví dụ: nếu
bạn đang sử dụng thư viện Jetpack Media3 và chưa tuỳ chỉnh
AudioAttributes, hãy sử dụng AudioAttributes.DEFAULT.
Tắt âm thanh không gian
Để cho biết rằng nội dung của bạn đã được tạo không gian, hãy gọi
setIsContentSpatialized(true)
để âm thanh không bị xử lý gấp đôi. Ngoài ra, hãy điều chỉnh hành vi tạo không gian
để tắt hoàn toàn tính năng tạo không gian 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 bản âm thanh.
Khi tạo thực thể AudioFormat để truyền vào canBeSpatialized(),
hãy đặt mã hoá
thành giống như định dạng đầu ra dự kiến từ bộ giải mã. Bạn cũng nên đặ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 tạo không gian mặc định để biết hướng dẫn về
các giá trị cụ thể cần sử dụng.
Theo dõi 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ề khả năng sử dụng của trình theo dõi chuyển động của đầ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 bản nhạc trong khi phát bằng lệnh gọi lại của trình 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 liệu hiệu ứng tạo không gian có dùng được cho định 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 cập nhật logic lựa chọn bản nhạc của trình phát để phù hợp với các khả năng mới của thiết bị. Để biết thông tin chi tiết về
hành vi lựa chọn bản nhạc 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 hơn. Nếu bạn sử dụng
thư viện ExoPlayer độc lập (tên gói com.google.android.exoplayer2),
phiên bản 2.17 sẽ định cấu hình nền tảng để xuất ra âm thanh được tạo không gian và phiên bản
2.18 sẽ giới thiệu các quy tắc ràng buộc về số lượng kênh âm thanh.
Nếu bạn sử dụng mô-đun ExoPlayer từ thư viện Media3 (tên gói
androidx.media3), thì các phiên bản 1.0.0-beta01
trở lên sẽ bao gồm các bản 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 bao gồm nội dung có thể được tạo không gian.
Quy tắc ràng buộc về số lượng kênh âm thanh
Khi đáp ứng cả 4 điều kiện cho âm thanh không gian, ExoPlayer sẽ chọn
một bản âm thanh nhiều 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 bản nhạc mới để chọn một bản âm thanh khớp với các thuộc tính hiện tại. Xin lưu ý rằng lựa chọn bản nhạc 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 quy tắ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 bản nhạc 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 quy tắc ràng buộc về số lượng kênh âm thanh bị tắt, nếu nội dung có nhiều bản âm thanh, ExoPlayer sẽ chọn bản nhạc có số lượng kênh cao nhất và có thể phát được từ thiết bị. Ví dụ: nếu nội dung chứa một bản âm thanh nhiều kênh và một bản âm thanh nổi, đồng thời thiết bị hỗ trợ phát cả hai, thì ExoPlayer sẽ chọn bản nhạc nhiều kênh. Hãy xem phần Lựa chọn bản âm thanh để biết thông tin chi tiết về cách tuỳ chỉnh hành vi này.
Lựa chọn bản âm thanh
Khi hành vi ràng buộc về số lượng kênh âm thanh của ExoPlayer bị tắt, ExoPlayer sẽ không tự động chọn một bản âm thanh khớp với các thuộc tính của bộ tạo không gian của thiết bị. Thay vào đó, bạn có thể tuỳ chỉnh logic lựa chọn bản nhạc của ExoPlayer bằng cách đặt các tham số lựa chọn bản nhạc trước hoặc trong khi phát. Theo mặc định, ExoPlayer chọn các bản âm thanh giống với bản nhạc ban đầu về loại MIME (mã hoá), số lượng kênh và tốc độ lấy mẫu.
Thay đổi các tham số lựa chọn bản nhạc
Để thay đổi các tham số lựa chọn bản nhạc của ExoPlayer, hãy sử dụng
Player.setTrackSelectionParameters().
Tương tự, bạn có thể nhận các tham 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:
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ố lựa chọn bản nhạc trong khi phát có thể gây gián đoạn quá trình phát. 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 tạo không gian mặc định
Hành vi tạo không gian mặc định trong Android bao gồm các hành vi sau mà OEM có thể tuỳ chỉnh:
Chỉ nội dung nhiều kênh được tạo không gian, không phải nội dung âm thanh nổi. Nếu bạn không sử dụng ExoPlayer, tuỳ thuộc vào định dạng của 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 thành 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 nhiều kênh để nền tảng tạo không gian.
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 tham khảo của ExoPlayer
MediaCodecAudioRenderer.java. Để tự tắt tính năng tạo không gian, bất kể việc 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 để tạo không gian nếuusageđược đặt thànhUSAGE_MEDIAhoặcUSAGE_GAME.AudioFormat: Sử dụng mặt nạ kênh chứa ít nhất các kênhAudioFormat.CHANNEL_OUT_QUAD(trái trước, phải trước, trái sau và phải sau) để âm thanh đủ điều kiện tạo không gian. Trong ví dụ bên dưới, chúng ta sử dụngAudioFormat.CHANNEL_OUT_5POINT1cho bản âm thanh 5.1. Đối với bản âm thanh nổi, hãy sử dụngAudioFormat.CHANNEL_OUT_STEREO.Nếu đang sử dụng Media3, bạn có thể sử 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 mã hoá thành
AudioFormat.ENCODING_PCM_16BITnếu bạn đã định cấu hình bộ giải mã để xuất ra 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();
Kiểm thử âm thanh không gian
Đảm bảo rằng tính năng âm thanh không gian được bật 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 bánh răng cho thiết bị không dây > Âm thanh không gian.
Để kiểm tra khả năng sử dụng tính năng Âm thanh không gian cho định tuyến hiện tại, hãy chạy lệnh adb shell dumpsys audio trên thiết bị. Bạn sẽ thấy các tham số sau trong kết quả khi quá trình phát đang hoạt động:
Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)