Mulai Android 17 QPR1 (level API 37.1 atau
Build.VERSION_CODES_FULL.CINNAMON_BUN_1), Android memperkenalkan dukungan platform
untuk encoding Extended High Efficiency Advanced Audio Coding (xHE-AAC).
Ditentukan dalam ISO/IEC 23003-3 (MPEG-D USAC) dan
ISO/IEC 23003-4 (MPEG-D DRC), xHE-AAC menggabungkan Unified Speech and
Audio Coding dengan normalisasi keras suara wajib dan kontrol rentang dinamis
bawaan. Meskipun dekode xHE-AAC telah didukung dan diwajibkan oleh
Dokumen Definisi Kompatibilitas (CDD) Android di beberapa
versi platform, penambahan encoder xHE-AAC
(implementasi hardware OEM dan c2.android.xheaac.encoder) memungkinkan Anda merekam
pesan suara dan audio bitrate rendah, streaming audio live, dan payload
komunikasi dengan kejelasan ucapan yang lebih baik dan volume yang konsisten di seluruh perangkat.
Manfaat xHE-AAC
Perekaman suara tradisional di aplikasi pesan Android biasanya menggunakan AAC-LC (AAC Low Complexity) yang lebih lama pada 28 kbps. Pada bitrate rendah (<32 kbps), AAC-LC menunjukkan artefak pembatasan band yang terlihat jelas, kualitas ucapan yang tidak jelas, dan efisiensi kompresi yang kurang optimal. Bagi pengguna akhir, hal ini menghasilkan audio yang teredam dan tipis, dengan konsonan yang sulit dibedakan, sehingga pendengar harus memutar ulang pesan atau berusaha keras untuk memahami ucapan di lingkungan yang bising. Selain itu, tingkat volume yang tidak konsisten di seluruh klip suara memaksa pengguna untuk sering menyesuaikan volume perangkat.
xHE-AAC mengatasi batasan ini dengan menerapkan algoritma coding audio yang lebih canggih, misalnya, beralih secara dinamis antara alat coding ucapan khusus dan alat coding audio umum sambil memperluas rentang frekuensi dengan Spectral Band Replication (SBR) yang ditingkatkan dan menyediakan kemampuan coding stereo parametrik dengan overhead coding tambahan yang sangat kecil.
DRC MPEG-D bawaan menyediakan kontrol keras suara wajib untuk xHE-AAC agar dapat memutar kembali konten pada volume yang konsisten dan menawarkan pemrosesan kontrol rentang dinamis untuk memberikan pengalaman pengguna terbaik saat mendengarkan di platform dan lingkungan apa pun.
Kasus penggunaan target
- Rich Communication Services (RCS) dan pesan suara: Mematuhi GSMA RCC.71 Universal Profile versi 3.1 dan yang lebih baru, yang mewajibkan xHE-AAC untuk pesan audio bitrate rendah.
- Streaming audio dan podcast live: Menghadirkan kualitas audio yang andal melalui koneksi jaringan seluler atau satelit yang terdegradasi.
Ketersediaan platform (level API 37.1+)
Dukungan encoding xHE-AAC platform memerlukan level API 37.1
(Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1 /
SDK 3700001 atau yang lebih tinggi).
Kueri untuk dukungan encoder xHE-AAC
Anda tidak boleh mengasumsikan bahwa encoding xHE-AAC tersedia di setiap perangkat
dengan memanggil MediaCodec.createByCodecName(...)
dengan "c2.android.xheaac.encoder".
- Beberapa perangkat dapat menyediakan encoder xHE-AAC yang diakselerasi hardware dari vendor chipset, bukan encoder software platform.
- Rilis OS lama atau ROM yang disesuaikan tidak memiliki dukungan encoding xHE-AAC.
- Sebelum mengenkode lampiran untuk pengiriman pesan peer-to-peer (seperti RCS atau
chat), aplikasi juga harus memeriksa apakah klien penerima mengiklankan
dukungan decoding USAC/xHE-AAC (misalnya, menggunakan penemuan kemampuan SDP
profile-level-id=55/object=42) untuk mencegah kegagalan interoperabilitas pada penerima lama.
Memeriksa kemampuan MediaCodecList
Untuk memeriksa apakah perangkat saat ini mendukung encoding xHE-AAC, periksa profileLevels encoder yang mendukung MediaFormat.MIMETYPE_AUDIO_AAC:
Kotlin
import android.media.MediaCodecInfo.CodecProfileLevel import android.media.MediaCodecList import android.media.MediaFormat import android.os.Build /** * Checks if the current device supports xHE-AAC audio encoding. */ fun isXheAacEncodingSupported(): Boolean { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false } val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) for (codecInfo in codecList.codecInfos) { if (!codecInfo.isEncoder) continue if (MediaFormat.MIMETYPE_AUDIO_AAC in codecInfo.supportedTypes) { val capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC) // Check if AACObjectXHE (42) is present in profileLevels val supportsXhe = capabilities.profileLevels.any { profileLevel -> profileLevel.profile == CodecProfileLevel.AACObjectXHE } if (supportsXhe) { return true } } } return false }
Java
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo.CodecProfileLevel; import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; /** * Checks if the current device supports xHE-AAC audio encoding. */ public boolean isXheAacEncodingSupported() { // Verify API Level >= 37.1 (CINNAMON_BUN_1 / SDK 3700001) if (Build.VERSION.SDK_INT_FULL < Build.VERSION_CODES_FULL.CINNAMON_BUN_1) { return false; } MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) { if (!codecInfo.isEncoder()) continue; for (String type : codecInfo.getSupportedTypes()) { if (MediaFormat.MIMETYPE_AUDIO_AAC.equals(type)) { MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_AUDIO_AAC); for (CodecProfileLevel profileLevel : capabilities.profileLevels) { if (profileLevel.profile == CodecProfileLevel.AACObjectXHE) { return true; } } } } } return false; }
Mengonfigurasi dan membuat instance encoder xHE-AAC
Setelah memverifikasi dukungan xHE-AAC, konfigurasikan MediaFormat dengan
KEY_AAC_PROFILE ditetapkan ke
MediaCodecInfo.CodecProfileLevel.AACObjectXHE
(nilai 42).
Kotlin
fun setupXheAacEncoder(): MediaCodec? { if (!isXheAacEncodingSupported()) { return null } val mimeType = MediaFormat.MIMETYPE_AUDIO_AAC val sampleRate = 48000 val channelCount = 1 // Mono voice recording val bitRate = 20000 // 20 kbps delivers superior speech clarity val format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount).apply { setInteger(MediaFormat.KEY_BIT_RATE, bitRate) setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE) } // Find the hardware or software encoder supporting this format and profile val codecList = MediaCodecList(MediaCodecList.REGULAR_CODECS) val encoderName = codecList.findEncoderForFormat(format) ?: return null val encoder = MediaCodec.createByCodecName(encoderName) encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) return encoder }
Java
public MediaCodec setupXheAacEncoder() throws IOException { if (!isXheAacEncodingSupported()) { return null; } String mimeType = MediaFormat.MIMETYPE_AUDIO_AAC; int sampleRate = 48000; int channelCount = 1; // Mono voice recording int bitRate = 20000; // 20 kbps delivers superior speech clarity MediaFormat format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount); format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); format.setInteger(MediaFormat.KEY_AAC_PROFILE, CodecProfileLevel.AACObjectXHE); // Find the hardware or software encoder supporting this format and profile MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); String encoderName = codecList.findEncoderForFormat(format); if (encoderName == null) { return null; } MediaCodec encoder = MediaCodec.createByCodecName(encoderName); encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); return encoder; }
Batas encoder software yang didukung (c2.android.xheaac.encoder)
Saat menggunakan encoder xHE-AAC software yang disediakan sistem
(c2.android.xheaac.encoder), komponen akan mengiklankan batas kemampuan berikut:
- Jumlah saluran: Hingga
2saluran (Mono / Stereo). - Frekuensi sampel:
44100 Hz,48000 Hz. - Rentang kecepatan bit:
12,000 bpshingga400,000 bps(12 kbps – 400 kbps). - Penggabungan penampung: Kompatibel dengan penggabungan penampung MP4/M4A platform dan streaming elemen MP4A mentah
(
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4).