Audio Spasial

Audio Spasial adalah pengalaman audio imersif yang menempatkan pengguna di pusat aksi, sehingga konten Anda terdengar lebih realistis. Suara "di-spasialkan" untuk menciptakan efek multi-speaker, mirip dengan penyiapan suara surround, tetapi melalui headphone.

Misalnya, dalam film, suara dari mobil mungkin dimulai di belakang pengguna, bergerak ke depan, dan menghilang ke kejauhan. Dalam chat video, suara dapat dipisahkan dan ditempatkan di sekitar pengguna, sehingga memudahkan identifikasi pembicara.

Jika konten menggunakan format audio yang didukung, Anda dapat menambahkan audio spasial ke aplikasi mulai dari Android 13 (API level 33).

Mengkueri kemampuan

Gunakan class Spatializer untuk mengkueri kemampuan dan perilaku spasialisasi perangkat. Mulai dengan mengambil instance Spatializer dari AudioManager:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Setelah Anda mendapatkan Spatializer, periksa empat kondisi yang harus bernilai benar agar perangkat dapat menghasilkan audio spasial:

Kriteria Cek
Apakah perangkat mendukung spasialisasi? getImmersiveAudioLevel() bukan SPATIALIZER_IMMERSIVE_LEVEL_NONE
Apakah spatialisasi tersedia?
Ketersediaan bergantung pada kompatibilitas dengan pemilihan rute output audio saat ini.
isAvailable() adalah true
Apakah spasiisasi diaktifkan? isEnabled() adalah true
Dapatkah trek audio dengan parameter yang diberikan dispasialisasi? canBeSpatialized() adalah true

Kondisi ini mungkin tidak terpenuhi, misalnya, jika spasialisasi tidak tersedia untuk trek audio saat ini atau dinonaktifkan sepenuhnya di perangkat output audio.

Pelacakan gerak kepala

Dengan headset yang didukung, platform dapat menyesuaikan spasialisasi audio berdasarkan posisi kepala pengguna. Untuk memeriksa apakah pelacak kepala tersedia untuk pemilihan rute output audio saat ini, panggil isHeadTrackerAvailable().

Konten yang kompatibel

Spatializer.canBeSpatialized() menunjukkan apakah audio dengan properti yang diberikan dapat dispasialisasi dengan perutean perangkat output saat ini. Metode ini menggunakan AudioAttributes dan AudioFormat, yang keduanya dijelaskan secara lebih mendetail di bawah.

AudioAttributes

Objek AudioAttributes menjelaskan penggunaan streaming audio (misalnya, audio game atau media standar), beserta perilaku pemutarannya dan jenis konten.

Saat memanggil canBeSpatialized(), gunakan instance AudioAttributes yang sama seperti yang ditetapkan untuk Player Anda. Misalnya, jika Anda menggunakan library Jetpack Media3 dan belum menyesuaikan AudioAttributes, gunakan AudioAttributes.DEFAULT.

Menonaktifkan audio spasial

Untuk menunjukkan bahwa konten Anda telah di-spatialisasi, panggil setIsContentSpatialized(true) agar audio tidak diproses dua kali. Atau, sesuaikan perilaku spasialisasi untuk menonaktifkan spasial sepenuhnya dengan memanggil setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER).

AudioFormat

Objek AudioFormat menjelaskan detail tentang format dan konfigurasi saluran trek audio.

Saat membuat instance AudioFormat untuk diteruskan ke canBeSpatialized(), tetapkan encoding ke sama dengan format output yang diharapkan dari decoder. Anda juga harus menetapkan mask saluran yang cocok dengan konfigurasi saluran konten Anda. Lihat bagian Perilaku spasial default untuk mendapatkan panduan tentang nilai tertentu yang akan digunakan.

Memproses perubahan pada Spatializer

Untuk memproses perubahan status Spatializer, Anda dapat menambahkan pemroses dengan Spatializer.addOnSpatializerStateChangedListener(). Demikian pula, untuk memproses perubahan ketersediaan pelacak kepala, panggil Spatializer.addOnHeadTrackerAvailableListener().

Hal ini dapat berguna jika Anda ingin menyesuaikan pemilihan trek selama pemutaran menggunakan callback pemroses. Misalnya, saat pengguna menghubungkan atau memutuskan koneksi headset dari perangkat, callback onSpatializerAvailableChanged menunjukkan apakah efek spatializer tersedia untuk pemilihan rute output audio baru. Pada tahap ini, Anda dapat mempertimbangkan untuk memperbarui logika pemilihan trek pemutar agar sesuai dengan kemampuan baru perangkat. Untuk mengetahui detail tentang perilaku pemilihan trek ExoPlayer, lihat bagian ExoPlayer dan audio spasial.

ExoPlayer dan audio spasial

Rilis terbaru ExoPlayer memudahkan pengadopsian audio spasial. Jika Anda menggunakan library ExoPlayer mandiri (nama paket com.google.android.exoplayer2), versi 2.17 akan mengonfigurasi platform untuk menghasilkan audio yang dispasialisasi, dan versi 2.18 memperkenalkan batasan jumlah saluran audio. Jika Anda menggunakan modul ExoPlayer dari library Media3, (nama paket androidx.media3), versi 1.0.0-beta01 dan yang lebih baru akan menyertakan update yang sama ini.

Setelah mengupdate dependensi ExoPlayer ke rilis terbaru, aplikasi Anda hanya perlu menyertakan konten yang dapat di-spatialisasi.

Batasan jumlah saluran audio

Jika keempat kondisi untuk audio spasial terpenuhi, ExoPlayer akan memilih jalur audio multisaluran. Jika tidak, ExoPlayer akan memilih trek stereo. Jika properti Spatializer berubah, ExoPlayer akan memicu pemilihan trek baru untuk memilih trek audio yang cocok dengan properti saat ini. Perhatikan bahwa pemilihan trek baru ini dapat menyebabkan periode buffering ulang yang singkat.

Untuk menonaktifkan batasan jumlah saluran audio, tetapkan parameter pemilihan trek di pemutar seperti yang ditunjukkan di bawah ini:

Kotlin

exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context)
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  new DefaultTrackSelector.Parameters.Builder(context)
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Demikian pula, Anda dapat memperbarui parameter pemilih trek yang ada untuk menonaktifkan batasan jumlah saluran audio sebagai berikut:

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()
);

Dengan batasan jumlah saluran audio dinonaktifkan, jika konten memiliki beberapa trek audio, ExoPlayer awalnya akan memilih trek yang memiliki jumlah saluran tertinggi dan dapat diputar dari perangkat. Misalnya, jika konten berisi trek audio multisaluran dan trek audio stereo, dan perangkat mendukung pemutaran keduanya, ExoPlayer akan memilih trek multisaluran. Lihat Pemilihan trek audio untuk mengetahui detail tentang cara menyesuaikan perilaku ini.

Pilihan trek audio

Jika perilaku batasan jumlah saluran audio ExoPlayer dinonaktifkan, ExoPlayer tidak akan otomatis memilih trek audio yang cocok dengan properti spatializer perangkat. Sebagai gantinya, Anda dapat menyesuaikan logika pemilihan trek ExoPlayer dengan menetapkan parameter pemilihan trek sebelum atau selama pemutaran. Secara default, ExoPlayer memilih trek audio yang sama dengan trek awal sehubungan dengan jenis MIME (encoding), jumlah saluran, dan frekuensi sampel.

Mengubah parameter pemilihan lagu

Untuk mengubah parameter pemilihan trek ExoPlayer, gunakan Player.setTrackSelectionParameters(). Demikian pula, Anda bisa mendapatkan parameter ExoPlayer saat ini dengan Player.getTrackSelectionParameters(). Misalnya, untuk memilih trek audio stereo di tengah pemutaran:

Kotlin

exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
  .buildUpon()
  .setMaxAudioChannelCount(2)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  exoPlayer.getTrackSelectionParameters()
    .buildUpon()
    .setMaxAudioChannelCount(2)
    .build()
);

Perhatikan bahwa mengubah parameter pemilihan trek di tengah pemutaran dapat menyebabkan gangguan dalam pemutaran. Informasi selengkapnya tentang cara menyesuaikan parameter pemilihan jalur pemutar tersedia di bagian pemilihan jalur pada dokumentasi ExoPlayer.

Perilaku spasialisasi default

Perilaku spasialisasi default di Android mencakup perilaku berikut yang dapat disesuaikan oleh OEM:

  • Hanya konten multisaluran yang di-spatialisasi, bukan konten stereo. Jika tidak menggunakan ExoPlayer, bergantung pada format konten audio multi-saluran, Anda mungkin perlu mengonfigurasi jumlah maksimum saluran yang dapat dihasilkan oleh decoder audio ke jumlah besar. Hal ini memastikan bahwa decoder audio menghasilkan PCM multi-saluran untuk spasial platform.

    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);

    Untuk contoh cara kerjanya, lihat MediaCodecAudioRenderer.java ExoPlayer. Untuk menonaktifkan spasialisasi sendiri, terlepas dari penyesuaian OEM, lihat Menonaktifkan audio spasial.

  • AudioAttributes: Audio memenuhi syarat untuk spasialisasi jika usage ditetapkan ke USAGE_MEDIA atau USAGE_GAME.

  • AudioFormat: Gunakan mask saluran yang berisi setidaknya saluran AudioFormat.CHANNEL_OUT_QUAD (kiri depan, kanan depan, kiri belakang, dan kanan belakang) agar audio memenuhi syarat untuk spasialisasi. Pada contoh di bawah, kita menggunakan AudioFormat.CHANNEL_OUT_5POINT1 untuk trek audio 5.1. Untuk trek audio stereo, gunakan AudioFormat.CHANNEL_OUT_STEREO.

    Jika menggunakan Media3, Anda dapat menggunakan Util.getAudioTrackChannelConfig(int channelCount) untuk mengonversi jumlah saluran menjadi mask saluran.

    Selain itu, setel encoding ke AudioFormat.ENCODING_PCM_16BIT jika Anda telah mengonfigurasi decoder untuk menghasilkan PCM multi-saluran.

    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();

Menguji audio spasial

Pastikan audio spasial diaktifkan di perangkat pengujian Anda:

  • Untuk headset berkabel, buka Setelan sistem > Suara & getaran > Audio spasial.
  • Untuk headset nirkabel, buka Setelan sistem > Perangkat terhubung > ikon roda gigi untuk perangkat nirkabel Anda > Audio spasial.

Untuk memeriksa ketersediaan Audio Spasial untuk pemilihan rute saat ini, jalankan perintah adb shell dumpsys audio di perangkat Anda. Anda akan melihat parameter berikut dalam output saat pemutaran aktif:

Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)