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

📄 calc_en.cpp

📁 实现3GPP的GSM中AMR语音的CODECS。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------ FUNCTION NAME: calc_filt_energies------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs:    mode = coder mode, type Mode    xn = LTP target vector, buffer type Word16    xn2 = CB target vector,  buffer type Word16    y1 = Adaptive codebook,  buffer type Word16    Y2 = Filtered innovative vector,  buffer type Word16    g_coeff = Correlations <xn y1> <y1 y1>    computed in G_pitch()  buffer type Word16    frac_coeff = energy coefficients (5), fraction part, buffer type Word16    exp_coeff = energy coefficients (5), exponent part, buffer type Word16    cod_gain_frac = optimum codebook gain (fraction part), pointer type Word16    cod_gain_exp = optimum codebook gain (exponent part), pointer type Word16    pOverflow    = pointer to overflow indicator (Flag) Outputs:    frac_coeff contains new fraction part energy coefficients    exp_coeff contains new exponent part energy coefficients    cod_gain_frac points to the new optimum codebook gain (fraction part)    cod_gain_exp points to the new optimum codebook gain (exponent part)    pOverflow = 1 if there is an overflow else it is zero. Returns:    None. Global Variables Used:    None Local Variables Needed:    None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function calculates several energy coefficients for filtered excitation signals Compute coefficients need for the quantization and the optimum codebook gain gcu (for MR475 only).    coeff[0] =    y1 y1    coeff[1] = -2 xn y1    coeff[2] =    y2 y2    coeff[3] = -2 xn y2    coeff[4] =  2 y1 y2    gcu = <xn2, y2> / <y2, y2> (0 if <xn2, y2> <= 0) Product <y1 y1> and <xn y1> have been computed in G_pitch() and are in vector g_coeff[].------------------------------------------------------------------------------ REQUIREMENTS None.------------------------------------------------------------------------------ REFERENCES calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoidcalc_filt_energies(    enum Mode mode,     // i  : coder mode    Word16 xn[],        // i  : LTP target vector,                       Q0    Word16 xn2[],       // i  : CB target vector,                        Q0    Word16 y1[],        // i  : Adaptive codebook,                       Q0    Word16 Y2[],        // i  : Filtered innovative vector,              Q12    Word16 g_coeff[],   // i  : Correlations <xn y1> <y1 y1>                        //      computed in G_pitch()    Word16 frac_coeff[],// o  : energy coefficients (5), fraction part,  Q15    Word16 exp_coeff[], // o  : energy coefficients (5), exponent part,  Q0    Word16 *cod_gain_frac,// o: optimum codebook gain (fraction part),   Q15    Word16 *cod_gain_exp  // o: optimum codebook gain (exponent part),   Q0){    Word32 s, ener_init;    Word16 i, exp, frac;    Word16 y2[L_SUBFR];    if (sub(mode, MR795) == 0 || sub(mode, MR475) == 0)    {        ener_init = 0L;    }    else    {        ener_init = 1L;    }    for (i = 0; i < L_SUBFR; i++) {        y2[i] = shr(Y2[i], 3);    }    frac_coeff[0] = g_coeff[0];    exp_coeff[0] = g_coeff[1];    frac_coeff[1] = negate(g_coeff[2]); // coeff[1] = -2 xn y1    exp_coeff[1] = add(g_coeff[3], 1);    // Compute scalar product <y2[],y2[]>    s = L_mac(ener_init, y2[0], y2[0]);    for (i = 1; i < L_SUBFR; i++)        s = L_mac(s, y2[i], y2[i]);    exp = norm_l(s);    frac_coeff[2] = extract_h(L_shl(s, exp));    exp_coeff[2] = sub(15 - 18, exp);    // Compute scalar product -2*<xn[],y2[]>    s = L_mac(ener_init, xn[0], y2[0]);    for (i = 1; i < L_SUBFR; i++)        s = L_mac(s, xn[i], y2[i]);    exp = norm_l(s);    frac_coeff[3] = negate(extract_h(L_shl(s, exp)));    exp_coeff[3] = sub(15 - 9 + 1, exp);    // Compute scalar product 2*<y1[],y2[]>    s = L_mac(ener_init, y1[0], y2[0]);    for (i = 1; i < L_SUBFR; i++)        s = L_mac(s, y1[i], y2[i]);    exp = norm_l(s);    frac_coeff[4] = extract_h(L_shl(s, exp));    exp_coeff[4] = sub(15 - 9 + 1, exp);    if (sub(mode, MR475) == 0 || sub(mode, MR795) == 0)    {        // Compute scalar product <xn2[],y2[]>        s = L_mac(ener_init, xn2[0], y2[0]);        for (i = 1; i < L_SUBFR; i++)            s = L_mac(s, xn2[i], y2[i]);        exp = norm_l(s);        frac = extract_h(L_shl(s, exp));        exp = sub(15 - 9, exp);        if (frac <= 0)        {            *cod_gain_frac = 0;            *cod_gain_exp = 0;        }        else        {            //              gcu = <xn2, y2> / c[2]                  = (frac>>1)/frac[2]             * 2^(exp+1-exp[2])                  = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2])                  = div_s * 2^(exp-exp[2]-14)            *cod_gain_frac = div_s (shr (frac,1), frac_coeff[2]);            *cod_gain_exp = sub (sub (exp, exp_coeff[2]), 14);        }    }}------------------------------------------------------------------------------ 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 calc_filt_energies(    enum Mode mode,     /* i  : coder mode                                   */    Word16 xn[],        /* i  : LTP target vector,                       Q0  */    Word16 xn2[],       /* i  : CB target vector,                        Q0  */    Word16 y1[],        /* i  : Adaptive codebook,                       Q0  */    Word16 Y2[],        /* i  : Filtered innovative vector,              Q12 */    Word16 g_coeff[],   /* i  : Correlations <xn y1> <y1 y1>                 */    /*      computed in G_pitch()                        */    Word16 frac_coeff[], /* o  : energy coefficients (5), fraction part, Q15 */    Word16 exp_coeff[], /* o  : energy coefficients (5), exponent part,  Q0  */    Word16 *cod_gain_frac, /* o  : optimum codebook gain (fraction part),Q15 */    Word16 *cod_gain_exp, /* o  : optimum codebook gain (exponent part), Q0  */    Flag   *pOverflow){    Word32 s1;      /* Intermediate energy accumulator  */    Word32 s2;      /* Intermediate energy accumulator  */    Word32 s3;      /* Intermediate energy accumulator  */    Word16 i;       /* index used in all loops  */    Word16 exp;     /* number of '0's or '1's before MSB != 0   */    Word16 frac;        /* fractional part  */    Word16 tmp;     /* temporal storage */    Word16 scaled_y2[L_SUBFR];    frac_coeff[0] = g_coeff[0];    exp_coeff[0]  = g_coeff[1];    frac_coeff[1] = negate(g_coeff[2]);    /* coeff[1] = -2 xn y1 */    exp_coeff[1]  = add(g_coeff[3], 1, pOverflow);    if ((mode == MR795) || (mode == MR475))    {        s1 = 0L;        s2 = 0L;        s3 = 0L;    }    else    {        s1 = 1L;        s2 = 1L;        s3 = 1L;    }    for (i = 0; i < L_SUBFR; i++)    {        /* avoid multiple accesses to memory  */        tmp   = (Y2[i] >> 3);        scaled_y2[i] = tmp;        /* Compute scalar product <scaled_y2[],scaled_y2[]> */        s1 = L_mac(s1, tmp, tmp, pOverflow);        /* Compute scalar product -2*<xn[],scaled_y2[]> */        s2 = L_mac(s2, xn[i], tmp, pOverflow);        /* Compute scalar product 2*<y1[],scaled_y2[]> */        s3 = L_mac(s3, y1[i], tmp, pOverflow);    }    exp = norm_l(s1);    frac_coeff[2] = (Word16)(L_shl(s1, exp, pOverflow) >> 16);    exp_coeff[2] = (-3 - exp);    exp = norm_l(s2);    frac_coeff[3] = negate((Word16)(L_shl(s2, exp, pOverflow) >> 16));    exp_coeff[3] = (7 - exp);    exp = norm_l(s3);    frac_coeff[4] = (Word16)(L_shl(s3, exp, pOverflow) >> 16);    exp_coeff[4] = sub(7, exp, pOverflow);    if ((mode == MR795) || (mode == MR475))    {        /* Compute scalar product <xn2[],scaled_y2[]> */        s1 = 0L;        for (i = 0; i < L_SUBFR; i++)        {            s1 = amrnb_fxp_mac_16_by_16bb((Word32) xn2[i], (Word32)scaled_y2[i], s1);        }        s1 = s1 << 1;        exp = norm_l(s1);        frac = (Word16)(L_shl(s1, exp, pOverflow) >> 16);        exp = (6 - exp);        if (frac <= 0)        {            *cod_gain_frac = 0;            *cod_gain_exp = 0;        }        else        {            /*            gcu = <xn2, scaled_y2> / c[2]                = (frac>>1)/frac[2]             * 2^(exp+1-exp[2])                = div_s(frac>>1, frac[2])*2^-15 * 2^(exp+1-exp[2])                = div_s * 2^(exp-exp[2]-14)            */            *cod_gain_frac = div_s(shr(frac, 1, pOverflow), frac_coeff[2]);            *cod_gain_exp = ((exp - exp_coeff[2]) - 14);        }    }    return;}/****************************************************************************//*------------------------------------------------------------------------------ FUNCTION NAME: calc_target_energy------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs:    xn =  LTP target vector, buffer to type Word16  Q0    en_exp = optimum codebook gain (exponent part) pointer to type Word16    en_frac = optimum codebook gain (fraction part) pointer to type Word16    pOverflow = pointer to overflow indicator (Flag) Outputs:    en_exp points to new optimum codebook gain (exponent part)    en_frac points to new optimum codebook gain (fraction part)    pOverflow = 1 if there is an overflow else it is zero. Returns:    None. Global Variables Used:    None Local Variables Needed:    None------------------------------------------------------------------------------ FUNCTION DESCRIPTION This function calculates the target energy using the formula, en = <xn, xn>------------------------------------------------------------------------------ REQUIREMENTS None.------------------------------------------------------------------------------ REFERENCES calc_en.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoidcalc_target_energy(    Word16 xn[],     // i: LTP target vector,                       Q0    Word16 *en_exp,  // o: optimum codebook gain (exponent part),   Q0    Word16 *en_frac  // o: optimum codebook gain (fraction part),   Q15){    Word32 s;    Word16 i, exp;    // Compute scalar product <xn[], xn[]>    s = L_mac(0L, xn[0], xn[0]);    for (i = 1; i < L_SUBFR; i++)        s = L_mac(s, xn[i], xn[i]);    // s = SUM 2*xn(i) * xn(i) = <xn xn> * 2    exp = norm_l(s);    *en_frac = extract_h(L_shl(s, exp));    *en_exp = sub(16, exp);}------------------------------------------------------------------------------ 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 calc_target_energy(    Word16 xn[],     /* i: LTP target vector,                       Q0  */    Word16 *en_exp,  /* o: optimum codebook gain (exponent part),   Q0  */    Word16 *en_frac, /* o: optimum codebook gain (fraction part),   Q15 */    Flag   *pOverflow){    Word32 s;       /* Intermediate energy accumulator  */    Word16 i;       /* index used in all loops  */    Word16 exp;    /* Compute scalar product <xn[], xn[]> */    s = 0;    for (i = 0; i < L_SUBFR; i++)    {        s = amrnb_fxp_mac_16_by_16bb((Word32) xn[i], (Word32) xn[i], s);    }    if (s < 0)    {        *pOverflow = 1;        s = MAX_32;    }    /* s = SUM 2*xn(i) * xn(i) = <xn xn> * 2 */    exp = norm_l(s);    *en_frac = (Word16)(L_shl(s, exp, pOverflow) >> 16);    *en_exp = (16 - exp);    return;}

⌨️ 快捷键说明

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