📄 qgain475.cpp
字号:
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 + -