A partire da Android 17 QPR1 (livello API 37.1 o
Build.VERSION_CODES_FULL.CINNAMON_BUN_1), Android introduce il supporto della piattaforma
per la codifica Extended High Efficiency Advanced Audio Coding (xHE-AAC).
Definito in ISO/IEC 23003-3 (MPEG-D USAC) e
ISO/IEC 23003-4 (MPEG-D DRC), xHE-AAC combina la codifica unificata di parlato e
audio con la normalizzazione obbligatoria del volume e il controllo della gamma dinamica
integrato. Sebbene la decodifica xHE-AAC sia stata supportata e resa obbligatoria dal
Compatibility Definition Document (CDD) di Android in più versioni della piattaforma, l'aggiunta di un encoder xHE-AAC
(implementazioni hardware c2.android.xheaac.encoder e OEM) consente di registrare
messaggi vocali e audio a basso bitrate, stream audio live e payload di comunicazione
con una chiarezza vocale superiore e un volume uniforme su tutti i dispositivi.
Vantaggi di xHE-AAC
La registrazione vocale tradizionale nelle app di messaggistica Android in genere utilizza la versione precedente AAC-LC (AAC Low Complexity) a 28 kbps. A velocità in bit basse (< 32 kbps), AAC-LC mostra artefatti di limitazione della banda evidenti, qualità del parlato sfocata ed efficienza di compressione non ottimale. Per gli utenti finali, l'audio risulta ovattato e metallico, le consonanti sono difficili da distinguere e gli ascoltatori devono riascoltare i messaggi o sforzarsi di capire il parlato in ambienti rumorosi. Inoltre, i livelli di volume incoerenti nei clip vocali costringono gli utenti a regolare frequentemente il volume del dispositivo.
xHE-AAC supera queste limitazioni applicando algoritmi di codifica audio più avanzati, ad esempio passando dinamicamente da strumenti di codifica vocale dedicati a strumenti di codifica audio generali, estendendo al contempo la gamma di frequenze con la replica della banda spettrale avanzata (eSBR) e fornendo la funzionalità di codifica stereo parametrica con un sovraccarico di codifica aggiuntivo molto ridotto.
La funzionalità MPEG-D DRC integrata fornisce il controllo obbligatorio del volume per xHE-AAC per riprodurre i contenuti a un volume costante e offre l'elaborazione del controllo della gamma dinamica per offrire la migliore esperienza utente possibile per l'ascolto su qualsiasi piattaforma e in qualsiasi ambiente.
Casi d'uso target
- Rich Communication Services (RCS) e messaggistica vocale: sono conformi a GSMA RCC.71 Universal Profile versione 3.1 e successive, che impongono xHE-AAC per la messaggistica audio a basso bitrate.
- Streaming audio live e podcast:offre una qualità audio resiliente su connessioni di rete mobile o satellitare degradate.
Disponibilità della piattaforma (livello API 37.1+)
Il supporto della codifica xHE-AAC della piattaforma richiede il livello API 37.1
(Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1/SDK 3700001 o versioni successive).
Query per il supporto del codificatore xHE-AAC
Non devi presupporre che la codifica xHE-AAC sia disponibile su ogni dispositivo
chiamando MediaCodec.createByCodecName(...)
con "c2.android.xheaac.encoder".
- Alcuni dispositivi potrebbero fornire un codificatore xHE-AAC con accelerazione hardware dal fornitore del chipset anziché dal codificatore software della piattaforma.
- Le versioni precedenti del sistema operativo o le ROM personalizzate non supportano la codifica xHE-AAC.
- Prima di codificare un allegato per la messaggistica peer-to-peer (ad esempio RCS o
chat), le app devono anche verificare se il client di ricezione annuncia
il supporto della decodifica USAC/xHE-AAC (ad esempio, utilizzando l'individuazione delle funzionalità SDP
profile-level-id=55/object=42) per evitare errori di interoperabilità sui ricevitori legacy.
Ispeziona le funzionalità di MediaCodecList
Per verificare se il dispositivo attuale supporta la codifica xHE-AAC, controlla profileLevels dei codificatori che supportano 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; }
Configura e crea un'istanza del codificatore xHE-AAC
Dopo aver verificato il supporto di xHE-AAC, configura MediaFormat con
KEY_AAC_PROFILE impostato su
MediaCodecInfo.CodecProfileLevel.AACObjectXHE
(valore 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; }
Limiti dei codificatori software supportati (c2.android.xheaac.encoder)
Quando utilizzi il codificatore software xHE-AAC fornito dal sistema
(c2.android.xheaac.encoder), il componente annuncia i seguenti
limiti di funzionalità:
- Numero di canali: fino a
2canali (mono / stereo). - Frequenze di campionamento:
44100 Hz,48000 Hz. - Intervallo velocità in bit:da
12,000 bpsa400,000 bps(da 12 kbps a 400 kbps). - Multiplexing del contenitore:compatibile con stream elementari MP4A non elaborati e
multiplexing del contenitore MP4/M4A della piattaforma
(
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4).