xHE-AAC ile yüksek kaliteli ve düşük bit hızlı ses kaydı yapma

Android 17 QPR1'den (API düzeyi 37.1 veya Build.VERSION_CODES_FULL.CINNAMON_BUN_1) itibaren Android, Genişletilmiş Yüksek Verimli Gelişmiş Ses Kodlama (xHE-AAC) kodlaması için platform desteği sunar.

ISO/IEC 23003-3 (MPEG-D USAC) ve ISO/IEC 23003-4 (MPEG-D DRC)'de tanımlanan xHE-AAC, birleşik konuşma ve ses kodlamasını zorunlu ses yüksekliği normalleştirme ve yerleşik dinamik aralık kontrolü ile birleştirir. xHE-AAC kod çözme özelliği, Android Uyumluluk Tanım Belgesi (CDD) tarafından desteklenip zorunlu kılınarak birden fazla platform sürümünde kullanıma sunulmuştu. xHE-AAC kodlayıcı (c2.android.xheaac.encoder ve OEM donanım uygulamaları) eklenmesiyle düşük bit hızlı ses ve sesli mesajlar, canlı ses akışları ve iletişim yükleri kaydedebilirsiniz. Bu sayede, cihazlar arasında üstün konuşma netliği ve tutarlı ses seviyesi elde edebilirsiniz.

xHE-AAC'nin avantajları

Android mesajlaşma uygulamalarındaki geleneksel ses kaydı genellikle 28 kbps hızında eski AAC-LC (AAC Low Complexity) biçimini kullanır. Düşük bit hızlarında (<32 kbps) AAC-LC, belirgin bant sınırlama artefaktları, bulanık konuşma kalitesi ve optimum olmayan sıkıştırma verimliliği gösterir. Bu durum, son kullanıcılar için sessiz harflerin ayırt edilmesinin zor olduğu, boğuk ve cızırtılı bir sesle sonuçlanır. Dinleyicilerin mesajları tekrar oynatması veya gürültülü ortamlarda konuşmayı anlamak için zorlanması gerekir. Ayrıca, ses kliplerindeki tutarsız ses seviyeleri, kullanıcıları cihazın ses seviyesini sık sık ayarlamaya zorlar.

xHE-AAC, daha gelişmiş ses kodlama algoritmaları uygulayarak bu sınırlamaların üstesinden gelir. Örneğin, özel konuşma kodlama ve genel ses kodlama araçları arasında dinamik olarak geçiş yaparken frekans aralığını gelişmiş Spektral Bant Çoğaltma (eSBR) ile genişletir ve çok az ek kodlama yüküyle parametrik stereo kodlama özelliği sağlar.

Dahili MPEG-D DRC, xHE-AAC'nin içerikleri tutarlı bir ses seviyesinde oynatması için zorunlu ses yüksekliği kontrolü sağlar. Ayrıca, herhangi bir platformda ve ortamda dinleme için mümkün olan en iyi kullanıcı deneyimini sunmak üzere dinamik aralık kontrolü işleme özelliği sunar.

Hedef kullanım alanları

  • Rich Communication Services (RCS) ve sesli mesajlaşma: Düşük bit hızlı sesli mesajlaşma için xHE-AAC'yi zorunlu kılan GSMA RCC.71 Universal Profile sürüm 3.1 ve sonraki sürümlerine uygundur.
  • Canlı ses yayını ve podcast'ler: Bozulmuş mobil veya uydu ağı bağlantılarında dayanıklı ses kalitesi sunar.

Platform kullanılabilirliği (API düzeyi 37.1 ve üzeri)

Platform xHE-AAC kodlama desteği için API düzeyi 37.1 (Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1 / SDK 3700001 veya daha yüksek) gerekir.

xHE-AAC kodlayıcı desteği için sorgu

"c2.android.xheaac.encoder" ile MediaCodec.createByCodecName(...) işlevini çağırarak xHE-AAC kodlamanın her cihazda kullanılabildiğini varsaymamalısınız.

  • Bazı cihazlar, platform yazılımı kodlayıcısı yerine yonga seti satıcısından donanım hızlandırmalı xHE-AAC kodlayıcı sağlayabilir.
  • Eski işletim sistemi sürümlerinde veya özelleştirilmiş ROM'larda xHE-AAC kodlama desteği yoktur.
  • Uygulamalar, eşler arası mesajlaşma (ör. RCS veya sohbet) için bir eki kodlamadan önce, alıcı istemcinin eski alıcılarda birlikte çalışabilirlik hatalarını önlemek için USAC/xHE-AAC kod çözme desteğini (ör. SDP özelliği keşfini kullanarak profile-level-id=55 / object=42) duyurup duyurmadığını da kontrol etmelidir.

MediaCodecList özelliklerini inceleme

Mevcut cihazın xHE-AAC kodlamayı destekleyip desteklemediğini kontrol etmek için profileLevels destekleyen kodlayıcıların MediaFormat.MIMETYPE_AUDIO_AAC bölümünü inceleyin:

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

xHE-AAC kodlayıcıyı yapılandırma ve başlatma

xHE-AAC desteğini doğruladıktan sonra MediaFormat öğesini KEY_AAC_PROFILE değeri MediaCodecInfo.CodecProfileLevel.AACObjectXHE olarak ayarlanmış şekilde yapılandırın (değer 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;
}

Desteklenen yazılım kodlayıcı sınırları (c2.android.xheaac.encoder)

Sistem tarafından sağlanan xHE-AAC kodlayıcı yazılımı (c2.android.xheaac.encoder) kullanılırken bileşen aşağıdaki özellik sınırlarını duyurur:

  • Kanal sayısı: 2 adede kadar kanal (Mono / Stereo).
  • Örnekleme hızları: 44100 Hz, 48000 Hz.
  • Bit hızı aralığı: 12,000 bps ila 400,000 bps (12 Kb/sn - 400 Kb/sn).
  • Kapsayıcı çoklama: Ham MP4A temel akışları ve platform MP4/M4A kapsayıcı çoklama ile uyumludur (MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4).