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

📄 qgain475.cpp

📁 实现3GPP的GSM中AMR语音的CODECS。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            L_tmp = Mac_32_16(L_tmp, coeff[9], coeff_lo[9], g_pit_cod);            // store table index if MSE for this index is lower               than the minimum MSE seen so far            if (L_sub(L_tmp, dist_min) < (Word32) 0)            {                dist_min = L_tmp;                index = i;            }        }    }     *------------------------------------------------------------------*     *  read quantized gains and update MA predictor memories           *     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           *     *------------------------------------------------------------------*    // for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same    // as those calculated from the "real" predictor using quantized gains    tmp = shl(index, 2);    MR475_quant_store_results(pred_st,                              &table_gain_MR475[tmp],                              sf0_gcode0,                              sf0_exp_gcode0,                              sf0_gain_pit,                              sf0_gain_cod);    // calculate new predicted gain for subframe 1 (this time using    // the real, quantized gains)    gc_pred(pred_st, MR475, sf1_code_nosharp,            &sf1_exp_gcode0, &sf1_frac_gcode0,            &sf0_exp_gcode0, &sf0_gcode0); // last two args are dummy    sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));    tmp = add (tmp, 2);    MR475_quant_store_results(pred_st,                              &table_gain_MR475[tmp],                              sf1_gcode0,                              sf1_exp_gcode0,                              sf1_gain_pit,                              sf1_gain_cod);    return index;}------------------------------------------------------------------------------ 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]------------------------------------------------------------------------------*/Word16 MR475_gain_quant(       /* o  : index of quantization.                 */    gc_predState *pred_st,     /* i/o: gain predictor state struct            */    /* data from subframe 0 (or 2) */    Word16 sf0_exp_gcode0,     /* i  : predicted CB gain (exponent),      Q0  */    Word16 sf0_frac_gcode0,    /* i  : predicted CB gain (fraction),      Q15 */    Word16 sf0_exp_coeff[],    /* i  : energy coeff. (5), exponent part,  Q0  */    Word16 sf0_frac_coeff[],   /* i  : energy coeff. (5), fraction part,  Q15 */    /*      (frac_coeff and exp_coeff computed in  */    /*       calc_filt_energies())                 */    Word16 sf0_exp_target_en,  /* i  : exponent of target energy,         Q0  */    Word16 sf0_frac_target_en, /* i  : fraction of target energy,         Q15 */    /* data from subframe 1 (or 3) */    Word16 sf1_code_nosharp[], /* i  : innovative codebook vector (L_SUBFR)   */    /*      (whithout pitch sharpening)            */    Word16 sf1_exp_gcode0,     /* i  : predicted CB gain (exponent),      Q0  */    Word16 sf1_frac_gcode0,    /* i  : predicted CB gain (fraction),      Q15 */    Word16 sf1_exp_coeff[],    /* i  : energy coeff. (5), exponent part,  Q0  */    Word16 sf1_frac_coeff[],   /* i  : energy coeff. (5), fraction part,  Q15 */    /*      (frac_coeff and exp_coeff computed in  */    /*       calc_filt_energies())                 */    Word16 sf1_exp_target_en,  /* i  : exponent of target energy,         Q0  */    Word16 sf1_frac_target_en, /* i  : fraction of target energy,         Q15 */    Word16 gp_limit,           /* i  : pitch gain limit                       */    Word16 *sf0_gain_pit,      /* o  : Pitch gain,                        Q14 */    Word16 *sf0_gain_cod,      /* o  : Code gain,                         Q1  */    Word16 *sf1_gain_pit,      /* o  : Pitch gain,                        Q14 */    Word16 *sf1_gain_cod,      /* o  : Code gain,                         Q1  */    Flag   *pOverflow          /* o  : overflow indicator                     */){    const Word16 *p;    Word16 i;    Word16 index = 0;    Word16 tmp;    Word16 exp;    Word16 sf0_gcode0;    Word16 sf1_gcode0;    Word16 g_pitch;    Word16 g2_pitch;    Word16 g_code;    Word16 g2_code;    Word16 g_pit_cod;    Word16 coeff[10];    Word16 coeff_lo[10];    Word16 exp_max[10];  /* 0..4: sf0; 5..9: sf1 */    Word32 L_tmp;    Word32 dist_min;    /*-------------------------------------------------------------------*     *  predicted codebook gain                                          *     *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *     *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *     *                                                                   *     *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *     *-------------------------------------------------------------------*/    sf0_gcode0 = (Word16)(Pow2(14, sf0_frac_gcode0, pOverflow));    sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));    /*     * For each subframe, the error energy (sum) to be minimized consists     * of five terms, t[0..4].     *     *                      t[0] =    gp^2  * <y1 y1>     *                      t[1] = -2*gp    * <xn y1>     *                      t[2] =    gc^2  * <y2 y2>     *                      t[3] = -2*gc    * <xn y2>     *                      t[4] =  2*gp*gc * <y1 y2>     *     */    /* sf 0 */    /* determine the scaling exponent for g_code: ec = ec0 - 11 */    exp = sf0_exp_gcode0 - 11;    /* calculate exp_max[i] = s[i]-1 */    exp_max[0] = (sf0_exp_coeff[0] - 13);    exp_max[1] = (sf0_exp_coeff[1] - 14);    exp_max[2] = (sf0_exp_coeff[2] + (15 + (exp << 1)));    exp_max[3] = (sf0_exp_coeff[3] + exp);    exp_max[4] = (sf0_exp_coeff[4] + (1 + exp));    /* sf 1 */    /* determine the scaling exponent for g_code: ec = ec0 - 11 */    exp = sf1_exp_gcode0 - 11;    /* calculate exp_max[i] = s[i]-1 */    exp_max[5] = (sf1_exp_coeff[0] - 13);    exp_max[6] = (sf1_exp_coeff[1] - 14);    exp_max[7] = (sf1_exp_coeff[2] + (15 + (exp << 1)));    exp_max[8] = (sf1_exp_coeff[3] + exp);    exp_max[9] = (sf1_exp_coeff[4] + (1 + exp));    /*-------------------------------------------------------------------*     *  Gain search equalisation:                                        *     *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                        *     *  The MSE for the two subframes is weighted differently if there   *     *  is a big difference in the corresponding target energies         *     *-------------------------------------------------------------------*/    /* make the target energy exponents the same by de-normalizing the       fraction of the smaller one. This is necessary to be able to compare       them     */    exp = sf0_exp_target_en - sf1_exp_target_en;    if (exp > 0)    {        sf1_frac_target_en >>= exp;    }    else    {        sf0_frac_target_en >>= (-exp);    }    /* assume no change of exponents */    exp = 0;    /* test for target energy difference; set exp to +1 or -1 to scale     * up/down coefficients for sf 1     */    tmp = shr_r(sf1_frac_target_en, 1, pOverflow);  /* tmp = ceil(0.5*en(sf1)) */    if (tmp > sf0_frac_target_en)          /* tmp > en(sf0)? */    {        /*         * target_energy(sf1) > 2*target_energy(sf0)         *   -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4         */        exp = 1;    }    else    {        tmp = ((sf0_frac_target_en + 3) >> 2); /* tmp=ceil(0.25*en(sf0)) */        if (tmp > sf1_frac_target_en)      /* tmp > en(sf1)? */        {            /*             * target_energy(sf1) < 0.25*target_energy(sf0)             *   -> scale down MSE(sf0) by 0.5 by subtracting 1 from             *      coefficients 0..4             */            exp = -1;        }    }    for (i = 0; i < 5; i++)    {        exp_max[i] += exp;    }    /*-------------------------------------------------------------------*     *  Find maximum exponent:                                           *     *  ~~~~~~~~~~~~~~~~~~~~~~                                           *     *                                                                   *     *  For the sum operation, all terms must have the same scaling;     *     *  that scaling should be low enough to prevent overflow. There-    *     *  fore, the maximum scale is determined and all coefficients are   *     *  re-scaled:                                                       *     *                                                                   *     *    exp = max(exp_max[i]) + 1;                                     *     *    e = exp_max[i]-exp;         e <= 0!                            *     *    c[i] = c[i]*2^e                                                *     *-------------------------------------------------------------------*/    exp = exp_max[0];    for (i = 9; i > 0; i--)    {        if (exp_max[i] > exp)        {            exp = exp_max[i];        }    }    exp++;      /* To avoid overflow */    p = &sf0_frac_coeff[0];    for (i = 0; i < 5; i++)    {        tmp = (exp - exp_max[i]);        L_tmp = ((Word32)(*p++) << 16);        L_tmp = L_shr(L_tmp, tmp, pOverflow);        coeff[i] = (Word16)(L_tmp >> 16);        coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15));    }    p = &sf1_frac_coeff[0];    for (; i < 10; i++)    {        tmp = exp - exp_max[i];        L_tmp = ((Word32)(*p++) << 16);        L_tmp = L_shr(L_tmp, tmp, pOverflow);        coeff[i] = (Word16)(L_tmp >> 16);        coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15));    }    /*-------------------------------------------------------------------*     *  Codebook search:                                                 *     *  ~~~~~~~~~~~~~~~~                                                 *     *                                                                   *     *  For each pair (g_pitch, g_fac) in the table calculate the        *     *  terms t[0..4] and sum them up; the result is the mean squared    *     *  error for the quantized gains from the table. The index for the  *     *  minimum MSE is stored and finally used to retrieve the quantized *     *  gains                                                            *     *-------------------------------------------------------------------*/    /* start with "infinite" MSE */    dist_min = MAX_32;    p = &table_gain_MR475[0];    for (i = 0; i < MR475_VQ_SIZE; i++)    {        /* subframe 0 (and 2) calculations */        g_pitch = *p++;        g_code = *p++;        /* Need to be there OKA */        g_code    = (Word16)(((Word32) g_code * sf0_gcode0) >> 15);        g2_pitch  = (Word16)(((Word32) g_pitch * g_pitch) >> 15);        g2_code   = (Word16)(((Word32) g_code * g_code) >> 15);        g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15);        L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow) +                Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow) +                Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow) +                Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow) +                Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow);        tmp = (g_pitch - gp_limit);        /* subframe 1 (and 3) calculations */        g_pitch = *p++;        g_code = *p++;        if ((tmp <= 0) && (g_pitch <= gp_limit))        {            g_code = (Word16)(((Word32) g_code * sf1_gcode0) >> 15);            g2_pitch  = (Word16)(((Word32) g_pitch * g_pitch) >> 15);            g2_code   = (Word16)(((Word32) g_code * g_code) >> 15);            g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15);            L_tmp += (Mpy_32_16(coeff[5], coeff_lo[5], g2_pitch, pOverflow) +                      Mpy_32_16(coeff[6], coeff_lo[6], g_pitch, pOverflow) +                      Mpy_32_16(coeff[7], coeff_lo[7], g2_code, pOverflow) +                      Mpy_32_16(coeff[8], coeff_lo[8], g_code, pOverflow) +                      Mpy_32_16(coeff[9], coeff_lo[9], g_pit_cod, pOverflow));            /* store table index if MSE for this index is lower               than the minimum MSE seen so far */            if (L_tmp < dist_min)            {                dist_min = L_tmp;                index = i;            }        }    }    /*------------------------------------------------------------------*     *  read quantized gains and update MA predictor memories           *     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           *     *------------------------------------------------------------------*/    /* for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same       as those calculated from the "real" predictor using quantized gains */    tmp = index << 2;    MR475_quant_store_results(pred_st,                              &table_gain_MR475[tmp],                              sf0_gcode0,                              sf0_exp_gcode0,                              sf0_gain_pit,                              sf0_gain_cod,                              pOverflow);    /* calculate new predicted gain for subframe 1 (this time using       the real, quantized gains)                                   */    gc_pred(pred_st, MR475, sf1_code_nosharp,            &sf1_exp_gcode0, &sf1_frac_gcode0,            &sf0_exp_gcode0, &sf0_gcode0, /* dummy args */            pOverflow);    sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));    tmp += 2;    MR475_quant_store_results(        pred_st,        &table_gain_MR475[tmp],        sf1_gcode0,        sf1_exp_gcode0,        sf1_gain_pit,        sf1_gain_cod,        pOverflow);    return(index);}

⌨️ 快捷键说明

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