• [原创]桓泽学音频编解码(4):MP3 和 AAC 中反量化原理,优化设计与参考代码中实现


    标准11172-3(MP3)的量化原理

    11172-3即mpeg-1 audio(以下称11172-3)中层1层2和层3的量化算法是不同的,层1层2使用的是均匀量化,层3使用的是非均匀量化。

    层1和层2的反量化公式如下。

    层1和层2的rescaler公式如下。

    S´´ 输入反量化数据

    层3的反量化公式

    (1)    long block:

    (2)    short block:

    标准13818-7(AAC)的量化原理

    13818-7即AAC标准中所采用的非均匀量化公式

     

     

    其中int为取整操作.mdct_line是mdct输出频率谱线,scalefactor是各子带的缩放因子,common_scalefac是全局缩放因子,MAGIC_NUMBER是调整偏差,其值为60。

     

    非线性反量化公式如下所示:

     

     

    非线性量化的主要优点是内置有一个取决于系数幅度的噪声整形。对于给定的频谱样值,在一定的范围内增加scalefactor或减小全局缩放因子嘟可以放大量化器输出值的幅度,同时迅速降

    低量化失真的程度。

     

    反量化模块优化设计

    对与反量化模块的实现有以下几种方式

    1. 直接计算法

    2. 查表法

    3. 泰勒展开式法

    4. 线性差值法

    5. 综合法

    直接计算的话使用的是超越函数计算,运算量很大,不适合应用。查表法是算法最简单,计算量最小,但它属于一种用空间换时间的方法,即制作一张对于所有范围的输入数据,都能直接得到输出结果的表。但是若输入数据的范围为较大,如果全部制成表格,则需存储表格的空间也很大,浪费空间。泰勒展开式法是一种用普通计算代替超越函数计算的方法,但随着精度的提高泰勒展开的级数也增加较大。运算量也是相当的大。不适合实现。所以一般都用线性差值加查表法的综合结构实现反量化解码。

     

    在11172-3和13818-7中,反量化的主要部分是

     

    计算xiquant的值是反量化的主要工作,常规的方法是采用查表法,即制作一张对于所有范围的输入数据,都能直接得到输出结果的表。但是由于x的范围为08191,如果全部制成表格,则需8192字存储空间,在存储空间紧张的系统中这样做非常不经济。因此,为了降低存储空间,同时也保证运算的正确性。制作长度为256的查找表,每项以4字节表示,其它数值可以通过线性插值运算得到:

    1)对于x= 1--256之间的值,可以直接查表得到。

     

    2)对于x在257-2048之间的值,使用公式:

    3)对于x在2049-8192之间的值,使用公式:

     

    式中int()表示取整,rem()表示取余,f()对系数表进行查找操作。使用这种方法在节省了存储空间的同时,计算也只是简单的乘加运算。在定点处理器中式3-6或式3-7的运算只要一次乘法,3次加法和3次移位操作。虽然这种简化运算与实际值有误差,但是在实际解码时量化后的频谱系数超过256的往往所占比例并不是很大,经过统计发现, x的取值小于256的占了99%,这说明使用这种插值和查找表方法是能够得到满意的解码音质。

     

    反量化模块在不同参考软件中的实现方法

    13818-7 参考代码上的iquant实现

    MAX_IQ_TBL = 128

    在128以下的值用查表法

    在128以上的值用直接计算法

    以下来自esc_iquant函数

        if (q < MAX_IQ_TBL) {

          return((Float)iq_exp_tbl[q]);

        }

        else {

          return(pow(q, 4./3.));

    }

    Faad参考代码上iquant实现

    以下iquant不含负数变正书处理

    #ifdef FIXED_POINT

    /* For FIXED_POINT the iq_table is prescaled by 3 bits (iq_table[]/8) */

    #ifndef BIG_IQ_TABLE

     Faad的处理提供两种方法,使用宏定义区别开来

    方法1

    全部查表法,

          // IQ_TABLE_SIZE = 8192

    if (q < IQ_TABLE_SIZE)

        {

            return sgn * tab[q];

    }

    注faad的表是静态表,在全局数据段中

    方法2

    部分查表加线性差值法

    #define COEF_BITS 28

    #define COEF_PRECISION (1 << COEF_BITS)

    #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR

    #define REAL_PRECISION (1 << REAL_BITS)

    #define REAL_CONST(A) \

    (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5)))

    static const real_t errcorr[] =

    {

            REAL_CONST(0)     , REAL_CONST(1.0/8.0),

    REAL_CONST(2.0/8.0) , REAL_CONST(3.0/8.0),

            REAL_CONST(4.0/8.0) , REAL_CONST(5.0/8.0),

    REAL_CONST(6.0/8.0) , REAL_CONST(7.0/8.0),

            REAL_CONST(0)

        };

        real_t x1, x2;

    // IQ_TABLE_SIZE = 1026

        if (q < IQ_TABLE_SIZE)

        {

            return sgn * tab[q];

        }

       if (q >= 8192)

        {

            *error = 17;

            return 0;

        }

        /* 线性差值部分 */

        x1 = tab[q>>3];

        x2 = tab[(q>>3) + 1];

        return sgn * 16 * (MUL_R(errcorr[q&7],(x2-x1)) + x1);

    faad使用的公式和前面提出的不大一样

    只要q>1026就用公式

    Libmp3dec的iquant实现

    Libmp3dec使用函数l3_unscale完成反量化和rescale 两个功能

    l3_unscale反量化使用全部查表法实现反量化

    e = table_4_3_exp[value];

    但与faad的全查表不同的是,libmp3dec的表是动态表,在堆栈中,初始化时申请的。Faad的表在全局数据段中。是静态的。

    MPEG1 参考代码的iquant实现

    态的MPEG1参考代码的iquant在III_dequantize_sample函数中实现,完全使用exp指数运算。

  • 相关阅读:
    假期周总结报告(五)
    java 原码反码及补码 总结
    java ==与equals()方法的总结
    java String 类型总结
    java 全局变量 的小结
    java static语句的总结
    ATM开学测试(未完成)
    第七周学习进度总结
    第六周学习进度总结
    第五周学习进度总结
  • 原文地址:https://www.cnblogs.com/gaozehua/p/2482087.html
Copyright © 2020-2023  润新知