ضبط صدا با کیفیت بالا و بیت ریت پایین با xHE-AAC

با شروع از اندروید ۱۷ QPR1 (سطح API ۳۷.۱ یا Build.VERSION_CODES_FULL.CINNAMON_BUN_1 )، اندروید پشتیبانی پلتفرم را برای کدگذاری صوتی پیشرفته با راندمان بالا (xHE-AAC) معرفی می‌کند.

xHE-AAC که در ISO/IEC 23003-3 (MPEG-D USAC) و ISO/IEC 23003-4 (MPEG-D DRC) تعریف شده است، کدگذاری یکپارچه گفتار و صدا را با نرمال‌سازی اجباری بلندی صدا و کنترل داخلی محدوده دینامیکی ترکیب می‌کند. در حالی که رمزگشایی xHE-AAC توسط سند تعریف سازگاری اندروید (CDD) در نسخه‌های مختلف پلتفرم پشتیبانی و الزامی شده است، افزودن یک رمزگذار xHE-AAC ( c2.android.xheaac.encoder و پیاده‌سازی‌های سخت‌افزاری OEM) به شما امکان می‌دهد پیام‌های صوتی و تصویری با بیت‌ریت پایین، پخش‌های صوتی زنده و بارهای ارتباطی را با وضوح گفتار برتر و حجم صدای ثابت در بین دستگاه‌ها ضبط کنید.

مزایای xHE-AAC

ضبط صدای سنتی در برنامه‌های پیام‌رسان اندروید معمولاً از AAC-LC قدیمی‌تر (AAC Low Complexity) با سرعت ۲۸ کیلوبیت بر ثانیه استفاده می‌کند. در بیت‌ریت‌های پایین (کمتر از ۳۲ کیلوبیت بر ثانیه)، AAC-LC مصنوعات محدودکننده باند قابل توجه، کیفیت گفتار مبهم و راندمان فشرده‌سازی غیربهینه را نشان می‌دهد. برای کاربران نهایی، این امر منجر به صدای خفه و نامفهوم می‌شود که در آن تشخیص حروف صامت دشوار است و شنوندگان را مجبور می‌کند پیام‌ها را دوباره پخش کنند یا برای درک گفتار در محیط‌های پر سر و صدا تلاش کنند. علاوه بر این، سطوح صدای متناقض در کلیپ‌های صوتی، کاربران را مجبور می‌کند که مرتباً صدای دستگاه را تنظیم کنند.

xHE-AAC با اعمال الگوریتم‌های پیشرفته‌تر کدگذاری صوتی، به عنوان مثال، جابجایی پویا بین کدگذاری گفتار اختصاصی و ابزارهای کدگذاری صوتی عمومی، ضمن گسترش محدوده فرکانس با تکثیر باند طیفی بهبود یافته (eSBR) و ارائه قابلیت کدگذاری استریو پارامتری با سربار کدگذاری اضافی بسیار کم، بر این محدودیت‌ها غلبه می‌کند.

MPEG-D DRC داخلی، کنترل اجباری بلندی صدا را برای xHE-AAC فراهم می‌کند تا محتوا را با حجم صدای ثابت پخش کند و پردازش کنترل محدوده دینامیکی را ارائه می‌دهد تا بهترین تجربه کاربری ممکن را برای گوش دادن در هر پلتفرم و در هر محیطی فراهم کند.

موارد استفاده هدف

  • سرویس‌های ارتباطی غنی (RCS) و پیام‌رسانی صوتی: مطابق با نسخه ۳.۱ و بالاتر از پروفایل جهانی GSMA RCC.71 ، که xHE-AAC را برای پیام‌رسانی صوتی با بیت‌ریت پایین الزامی می‌کند.
  • پخش زنده صدا و پادکست: کیفیت صدای بی‌نظیری را نسبت به اتصالات ضعیف شبکه تلفن همراه یا ماهواره ارائه می‌دهد.

در دسترس بودن پلتفرم (سطح API 37.1+)

پشتیبانی از کدگذاری xHE-AAC پلتفرم به API سطح ۳۷.۱ نیاز دارد ( Build.VERSION.SDK_INT_FULL >= Build.VERSION_CODES_FULL.CINNAMON_BUN_1 / SDK 3700001 یا بالاتر).

درخواست پشتیبانی از رمزگذار xHE-AAC

شما نباید با فراخوانی MediaCodec.createByCodecName(...) به همراه "c2.android.xheaac.encoder" فرض کنید که کدگذاری xHE-AAC در هر دستگاهی موجود است.

  • برخی از دستگاه‌ها ممکن است به جای رمزگذار نرم‌افزاری پلتفرم، یک رمزگذار xHE-AAC با شتاب‌دهنده سخت‌افزاری را از فروشنده چیپست ارائه دهند.
  • نسخه‌های قدیمی‌تر سیستم‌عامل یا رام‌های سفارشی‌شده فاقد پشتیبانی از کدگذاری xHE-AAC هستند.
  • قبل از رمزگذاری یک پیوست برای پیام‌رسانی نظیر به نظیر (مانند RCS یا چت)، برنامه‌ها باید بررسی کنند که آیا کلاینت گیرنده، پشتیبانی از رمزگشایی USAC/xHE-AAC را تبلیغ می‌کند یا خیر (برای مثال، استفاده از SDP capability discovery profile-level-id=55 / object=42 ) تا از بروز مشکلات مربوط به قابلیت همکاری در گیرنده‌های قدیمی جلوگیری شود.

بررسی قابلیت‌های MediaCodecList

برای بررسی اینکه آیا دستگاه فعلی از کدگذاری xHE-AAC پشتیبانی می‌کند، profileLevels مربوط به کدگذاری‌هایی که از MediaFormat.MIMETYPE_AUDIO_AAC پشتیبانی می‌کنند را بررسی کنید:

کاتلین

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
}

جاوا

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

پس از تأیید پشتیبانی xHE-AAC، MediaFormat خود را با تنظیم KEY_AAC_PROFILE روی MediaCodecInfo.CodecProfileLevel.AACObjectXHE (مقدار 42 ) پیکربندی کنید.

کاتلین

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
}

جاوا

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

محدودیت‌های نرم‌افزاری پشتیبانی‌شده برای انکودر ( c2.android.xheaac.encoder )

هنگام استفاده از نرم‌افزار رمزگذار xHE-AAC ارائه شده توسط سیستم ( c2.android.xheaac.encoder )، این مؤلفه محدودیت‌های قابلیت زیر را اعلام می‌کند:

  • تعداد کانال: تا 2 کانال (مونو / استریو).
  • نرخ نمونه‌برداری: 44100 Hz ، 48000 Hz
  • محدوده بیت ریت: 12,000 bps تا 400,000 bps (۱۲ کیلوبیت بر ثانیه – ۴۰۰ کیلوبیت بر ثانیه).
  • مخلوط‌سازی کانتینر: سازگار با جریان‌های خام ابتدایی MP4A و مخلوط‌سازی کانتینر پلتفرم MP4/M4A ( MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4 ).