⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gc_pred.cpp

📁 实现3GPP的GSM中AMR语音的CODECS。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
         *  ~~~~~~~~~~~~~~~~~                                                *         *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant           *         *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])              *         *                                           constant = 20*Log10(2)  *         *-------------------------------------------------------------------*        ener = MEAN_ENER_MR122;                      // Q24 (Q17)        for (i = 0; i < NPRED; i++)        {            ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);                                                     // Q10 * Q13 -> Q24                                                     // Q10 * Q6  -> Q17        }         *-------------------------------------------------------------------*         *  predicted codebook gain                                          *         *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *         *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 )     *         *          = Pow2(ener-ener_code)                                   *         *          = Pow2(int(d)+frac(d))                                   *         *                                                                   *         *  (store exp and frac for pow2())                                  *         *-------------------------------------------------------------------*        ener = L_shr (L_sub (ener, ener_code), 1);                // Q16        L_Extract(ener, exp_gcode0, frac_gcode0);    }    else // all modes except 12.2    {        Word32 L_tmp;        Word16 exp_code, gcode0;         *-----------------------------------------------------------------*         *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *         *-----------------------------------------------------------------*        exp_code = norm_l (ener_code);        ener_code = L_shl (ener_code, exp_code);        // Log2 = log2 + 27        Log2_norm (ener_code, exp_code, &exp, &frac);        // fact = 10/log2(10) = 3.01 = 24660 Q13        L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14         *   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)         *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)         *         = K - fact * Log2(ener_code)         *         = K - fact * log2(ener_code) - fact*27         *         *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)         *         *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)         *   means_ener =       28.75 =  471040    Q14  (MR67)         *   means_ener =       30    =  491520    Q14  (MR74)         *   means_ener =       36    =  589824    Q14  (MR795)         *   means_ener =       33    =  540672    Q14  (MR102)         *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14         *   fact * 27                = 1331640    Q14         *   -----------------------------------------         *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2         *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2         *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2         *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2         *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2        if (sub (mode, MR102) == 0)        {            // mean = 33 dB            L_tmp = L_mac(L_tmp, 16678, 64);     // Q14        }        else if (sub (mode, MR795) == 0)        {            // ener_code  = <xn xn> * 2^27*2^exp_code            // frac_en    = ener_code / 2^16            //            = <xn xn> * 2^11*2^exp_code            // <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en            //           := frac_en            * 2^exp_en            // ==> exp_en = -11-exp_code;            *frac_en = extract_h (ener_code);            *exp_en = sub (-11, exp_code);            // mean = 36 dB            L_tmp = L_mac(L_tmp, 17062, 64);     // Q14        }        else if (sub (mode, MR74) == 0)        {            // mean = 30 dB            L_tmp = L_mac(L_tmp, 32588, 32);     // Q14        }        else if (sub (mode, MR67) == 0)        {            // mean = 28.75 dB            L_tmp = L_mac(L_tmp, 32268, 32);     // Q14        }        else // MR59, MR515, MR475        {            // mean = 33 dB            L_tmp = L_mac(L_tmp, 16678, 64);     // Q14        }         *-----------------------------------------------------------------*         * Compute gcode0.                                                 *         *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *         *-----------------------------------------------------------------*        L_tmp = L_shl(L_tmp, 10);                // Q24        for (i = 0; i < 4; i++)            L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);                                                 // Q13 * Q10 -> Q24        gcode0 = extract_h(L_tmp);               // Q8         *-----------------------------------------------------------------*         * gcode0 = pow(10.0, gcode0/20)                                   *         *        = pow(2, 3.3219*gcode0/20)                               *         *        = pow(2, 0.166*gcode0)                                   *         *-----------------------------------------------------------------*        // 5439 Q15 = 0.165985        // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)        if (sub (mode, MR74) == 0) // For IS641 bitexactness            L_tmp = L_mult(gcode0, 5439);  // Q8 * Q15 -> Q24        else            L_tmp = L_mult(gcode0, 5443);  // Q8 * Q15 -> Q24        L_tmp = L_shr(L_tmp, 8);                   //          -> Q16        L_Extract(L_tmp, exp_gcode0, frac_gcode0); //       -> Q0.Q15    }}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable                used to represent cycle count for each subroutine                called)     where: (cycle count variable) = cycle count for [subroutine                                     name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void gc_pred(    gc_predState *st,   /* i/o: State struct                           */    enum Mode mode,     /* i  : AMR mode                               */    Word16 *code,       /* i  : innovative codebook vector (L_SUBFR)   */    /*      MR122: Q12, other modes: Q13           */    Word16 *exp_gcode0, /* o  : exponent of predicted gain factor, Q0  */    Word16 *frac_gcode0,/* o  : fraction of predicted gain factor  Q15 */    Word16 *exp_en,     /* o  : exponent of innovation energy,     Q0  */    /*      (only calculated for MR795)            */    Word16 *frac_en,    /* o  : fraction of innovation energy,     Q15 */    /*      (only calculated for MR795)            */    Flag   *pOverflow){    register Word16 i;    register Word32 L_temp1, L_temp2;    register Word32 L_tmp;    Word32 ener_code;    Word32 ener;    Word16 exp, frac;    Word16 exp_code, gcode0;    Word16 tmp;    Word16 *p_code = &code[0];    /*-------------------------------------------------------------------*     *  energy of code:                                                  *     *  ~~~~~~~~~~~~~~~                                                  *     *  ener_code = sum(code[i]^2)                                       *     *-------------------------------------------------------------------*/    ener_code = 0;    /* MR122:  Q12*Q12 -> Q25 */    /* others: Q13*Q13 -> Q27 */    for (i = L_SUBFR >> 2; i != 0; i--)    {        tmp = *(p_code++);        ener_code += ((Word32) tmp * tmp) >> 3;        tmp = *(p_code++);        ener_code += ((Word32) tmp * tmp) >> 3;        tmp = *(p_code++);        ener_code += ((Word32) tmp * tmp) >> 3;        tmp = *(p_code++);        ener_code += ((Word32) tmp * tmp) >> 3;    }    ener_code <<= 4;    if (ener_code < 0)      /*  Check for saturation */    {        ener_code = MAX_32;    }    if (mode == MR122)    {        /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */        /* Q9  * Q20 -> Q30 */        ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;        /*-------------------------------------------------------------*         *  energy of code:                                            *         *  ~~~~~~~~~~~~~~~                                            *         *  ener_code(Q17) = 10 * Log10(energy) / constant             *         *                 = 1/2 * Log2(energy)                        *         *  constant = 20*Log10(2)                                     *         *-------------------------------------------------------------*/        /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */        Log2(ener_code, &exp, &frac, pOverflow);        /* Q16 for log()    */        /* ->Q17 for 1/2 log()*/        L_temp1 = (Word32)(exp - 30) << 16;        ener_code = L_temp1 + ((Word32)frac << 1);        /*-------------------------------------------------------------*         *  predicted energy:                                          *         *  ~~~~~~~~~~~~~~~~~                                          *         *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant     *         *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])        *         *  constant = 20*Log10(2)                                     *         *-------------------------------------------------------------*/        ener = MEAN_ENER_MR122;                   /* Q24 (Q17) */        for (i = 0; i < NPRED; i++)        {            L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *                       pred_MR122[i]) << 1;            ener = L_add(ener, L_temp1, pOverflow);            /* Q10 * Q13 -> Q24 */            /* Q10 * Q6  -> Q17 */        }        /*---------------------------------------------------------------*         *  predicted codebook gain                                      *         *  ~~~~~~~~~~~~~~~~~~~~~~~                                      *         *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 ) *         *          = Pow2(ener-ener_code)                               *         *          = Pow2(int(d)+frac(d))                               *         *                                                               *         *  (store exp and frac for pow2())                              *         *---------------------------------------------------------------*/        /* Q16 */        L_temp1 = L_sub(ener, ener_code, pOverflow);        *exp_gcode0 = (Word16)(L_temp1 >> 17);        L_temp2 = (Word32) * exp_gcode0 << 15;        L_temp1 >>= 2;        *frac_gcode0 = (Word16)(L_temp1 - L_temp2);    }    else /* all modes except 12.2 */    {        /*-----------------------------------------------------------------*         *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *         *-----------------------------------------------------------------*/        exp_code = norm_l(ener_code);        ener_code = L_shl(ener_code, exp_code, pOverflow);        /* Log2 = log2 + 27 */        Log2_norm(ener_code, exp_code, &exp, &frac);        /* fact = 10/log2(10) = 3.01 = 24660 Q13 */        /* Q0.Q15 * Q13 -> Q14 */        L_temp2 = (((Word32) exp) * -24660) << 1;        L_tmp = (((Word32) frac) * -24660) >> 15;        /* Sign-extend resulting product */        if (L_tmp & (Word32) 0x00010000L)        {            L_tmp = L_tmp | (Word32) 0xffff0000L;        }        L_tmp = L_tmp << 1;        L_tmp = L_add(L_tmp, L_temp2, pOverflow);        /*   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)         *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)         *         = K - fact * Log2(ener_code)         *         = K - fact * log2(ener_code) - fact*27         *         *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)         *         *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)         *   means_ener =       28.75 =  471040    Q14  (MR67)         *   means_ener =       30    =  491520    Q14  (MR74)         *   means_ener =       36    =  589824    Q14  (MR795)         *   means_ener =       33    =  540672    Q14  (MR102)         *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14         *   fact * 27                = 1331640    Q14         *   -----------------------------------------         *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2         *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2         *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2         *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2         *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2         */        if (mode == MR102)        {            /* mean = 33 dB */            L_temp2 = (Word32) 16678 << 7;            L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */        }        else if (mode == MR795)        {            /* ener_code  = <xn xn> * 2^27*2^exp_code               frac_en    = ener_code / 2^16                          = <xn xn> * 2^11*2^exp_code               <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en            :                 = frac_en            * 2^exp_en                          ==> exp_en = -11-exp_code;      */            *frac_en = (Word16)(ener_code >> 16);            *exp_en = sub(-11, exp_code, pOverflow);            /* mean = 36 dB */            L_temp2 = (Word32) 17062 << 7;            L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */        }        else if (mode == MR74)        {            /* mean = 30 dB */            L_temp2 = (Word32) 32588 << 6;            L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */        }        else if (mode == MR67)        {            /* mean = 28.75 dB */            L_temp2 = (Word32) 32268 << 6;            L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */        }        else /* MR59, MR515, MR475 */        {            /* mean = 33 dB */            L_temp2 = (Word32) 16678 << 7;            L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */        }        /*-------------------------------------------------------------*         * Compute gcode0.                                              *         *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *         *--------------------------------------------------------------*/        /* Q24 */        if (L_tmp > (Word32) 0X001fffffL)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -