📄 qgain795.cpp
字号:
* Codebook search: * * ~~~~~~~~~~~~~~~~ * * * * For each of the candiates LTP gains in g_pitch_cand[], the terms * * t[0..4] are calculated from the values in the table (and the * * pitch gain candidate) and summed up; the result is the mean * * squared error for the LPT/CB gain pair. The index for the mini- * * mum MSE is stored and finally used to retrieve the quantized CB * * gain * *-------------------------------------------------------------------*/ /* start with "infinite" MSE */ dist_min = MAX_32; cod_ind = 0; pit_ind = 0; /* loop through LTP gain candidates */ for (j = 0; j < 3; j++) { /* pre-calculate terms only dependent on pitch gain */ g_pitch = g_pitch_cand[j]; g2_pitch = mult(g_pitch, g_pitch, pOverflow); L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow); L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow); p = &qua_gain_code[0]; for (i = 0; i < NB_QUA_CODE; i++) { g_code = *p++; /* this is g_fac Q11 */ p++; /* skip log2(g_fac) */ p++; /* skip 20*log10(g_fac) */ g_code = mult(g_code, gcode0, pOverflow); L_tmp = L_mult(g_code, g_code, pOverflow); L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); L_tmp = L_mult(g_code, g_pitch, pOverflow); L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow); L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2], g2_code_h, g2_code_l, pOverflow); L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code, pOverflow); L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], g_pit_cod_h, g_pit_cod_l, pOverflow); /* store table index if MSE for this index is lower than the minimum MSE seen so far; also store the pitch gain for this (so far) lowest MSE */ if (L_tmp < dist_min) { dist_min = L_tmp; cod_ind = i; pit_ind = j; } } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &qua_gain_code[ add(add(cod_ind, cod_ind, pOverflow), cod_ind, pOverflow)]; g_code = *p++; *qua_ener_MR122 = *p++; *qua_ener = *p; /*------------------------------------------------------------------* * calculate final fixed codebook gain: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * gc = gc0 * g * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); L_tmp = L_shr(L_tmp, sub(9, exp_gcode0, pOverflow), pOverflow); *gain_cod = extract_h(L_tmp); *gain_cod_ind = cod_ind; *gain_pit = g_pitch_cand[pit_ind]; *gain_pit_ind = g_pitch_cind[pit_ind];}/*------------------------------------------------------------------------------ FUNCTION NAME: MR795_gain_code_quant_mod------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: gain_pit -- Word16 -- pitch gain, Q14 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 gcode0 -- Word16 -- predicted CB gain (norm.), Q14 frac_en[] -- Word16 array -- energy coefficients (4), fraction part, Q15 exp_en[] -- Word16 array -- energy coefficients (4), exponent part, Q0 alpha -- Word16 -- gain adaptor factor (>0), Q15 gain_cod_unq -- Word16 -- Code gain (unquantized) (scaling: Q10 - exp_gcode0) gain_cod -- Pointer to Word16 -- Code gain (pre-/quantized), Q1 Outputs: qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10 (for MR122 MA predictor update) qua_ener -- Pointer to Word16 -- quantized energy error, Q10 (for other MA predictor update) pOverflow -- Pointer to Flag -- overflow indicator Returns: index of quantization (Word16) Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION PURPOSE: Modified quantization of the MR795 codebook gain Uses pre-computed energy coefficients in frac_en[]/exp_en[] frac_en[0]*2^exp_en[0] = <res res> // LP residual energy frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy------------------------------------------------------------------------------ REQUIREMENTS None------------------------------------------------------------------------------ REFERENCES qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODE------------------------------------------------------------------------------ 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]------------------------------------------------------------------------------*/static Word16MR795_gain_code_quant_mod( /* o : index of quantization. */ Word16 gain_pit, /* i : pitch gain, Q14 */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ Word16 frac_en[], /* i : energy coefficients (4), fraction part, Q15 */ Word16 exp_en[], /* i : energy coefficients (4), eponent part, Q0 */ Word16 alpha, /* i : gain adaptor factor (>0), Q15 */ Word16 gain_cod_unq, /* i : Code gain (unquantized) */ /* (scaling: Q10 - exp_gcode0) */ Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */ Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ /* (for MR122 MA predictor update) */ Word16 *qua_ener, /* o : quantized energy error, Q10 */ /* (for other MA predictor update) */ Flag *pOverflow /* o : overflow indicator */){ const Word16 *p; Word16 i; Word16 index; Word16 tmp; Word16 one_alpha; Word16 exp; Word16 e_max; Word16 g2_pitch; Word16 g_code; Word16 g2_code_h; Word16 g2_code_l; Word16 d2_code_h; Word16 d2_code_l; Word16 coeff[5]; Word16 coeff_lo[5]; Word16 exp_coeff[5]; Word32 L_tmp; Word32 L_t0; Word32 L_t1; Word32 dist_min; Word16 gain_code; /* Steps in calculation of the error criterion (dist): --------------------------------------------------- underlined = constant; alp = FLP value of alpha, alpha = FIP ---------- ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn; ------------ ------ -- ----- aExEn= alp * ExEn = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2 -------------- ------------- --------- = t[1] + t[2] + t[3] dist = d1 + d2; d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4] ------------------- --- d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn); --- ----- --- ----- = alp * (sqrt(ExEn) - sqrt(ResEn))^2 --- ----------- = (sqrt(aExEn) - sqrt(alp*ResEn))^2 --------------- = (sqrt(aExEn) - t[0] )^2 ---- */ /* * calculate scalings of the constant terms */ gain_code = shl(*gain_cod, sub(10, exp_gcode0, pOverflow), pOverflow); /* Q1 -> Q11 (-ec0) */ g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */ /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */ one_alpha = add(sub(32767, alpha, pOverflow), 1, pOverflow); /* 32768 - alpha */ /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ L_t1 = L_mult(alpha, frac_en[1], pOverflow); L_t1 = L_shl(L_t1, 1, pOverflow); tmp = extract_h(L_t1); /* directly store in 32 bit variable because no further mult. required */ L_t1 = L_mult(tmp, g2_pitch, pOverflow); exp_coeff[1] = sub(exp_en[1], 15, pOverflow); tmp = extract_h(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow)); coeff[2] = mult(tmp, gain_pit, pOverflow); exp = sub(exp_gcode0, 10, pOverflow); exp_coeff[2] = add(exp_en[2], exp, pOverflow); /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ coeff[3] = extract_h(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow)); exp = sub(shl(exp_gcode0, 1, pOverflow), 7, pOverflow); exp_coeff[3] = add(exp_en[3], exp, pOverflow); coeff[4] = mult(one_alpha, frac_en[3], pOverflow); exp_coeff[4] = add(exp_coeff[3], 1, pOverflow); L_tmp = L_mult(alpha, frac_en[0], pOverflow); /* sqrt_l returns normalized value and 2*exponent -> result = val >> (exp/2) exp_coeff holds 2*exponent for c[0] */ /* directly store in 32 bit variable because no further mult. required */ L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */ exp = add(exp, 47, pOverflow); exp_coeff[0] = sub(exp_en[0], exp, pOverflow); /* * Determine the maximum exponent occuring in the distance calculation * and adjust all fractions accordingly (including a safety margin) * */ /* find max(e[1..4],e[0]+31) */ e_max = add(exp_coeff[0], 31, pOverflow);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -