📄 qgain795.cpp
字号:
for (i = 1; i <= 4; i++) { if (exp_coeff[i] > e_max) { e_max = exp_coeff[i]; } } /* scale c[1] (requires no further multiplication) */ tmp = sub(e_max, exp_coeff[1], pOverflow); L_t1 = L_shr(L_t1, tmp, pOverflow); /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */ for (i = 2; i <= 4; i++) { tmp = sub(e_max, exp_coeff[i], pOverflow); L_tmp = L_deposit_h(coeff[i]); L_tmp = L_shr(L_tmp, tmp, pOverflow); L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow); } /* scale c[0] (requires no further multiplication) */ exp = sub(e_max, 31, pOverflow); /* new exponent */ tmp = sub(exp, exp_coeff[0], pOverflow); L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow); /* perform correction by 1/sqrt(2) if exponent difference is odd */ if ((tmp & 0x1) != 0) { L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow); L_t0 = Mpy_32_16(coeff[0], coeff_lo[0], 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/ } /* search the quantizer table for the lowest value of the search criterion */ dist_min = MAX_32; index = 0; 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); /* only continue if gc[i] < 2.0*gc which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */ if (g_code >= gain_code) { break; } L_tmp = L_mult(g_code, g_code, pOverflow); L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow); tmp = sub(g_code, gain_cod_unq, pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow); /* t2, t3, t4 */ L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow); L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow); L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow); L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow); /* d2 */ tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow); L_tmp = L_mult(tmp, tmp, pOverflow); /* dist */ L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow); /* store table index if distance measure for this index is lower than the minimum seen so far */ if (L_tmp < dist_min) { dist_min = L_tmp; index = i; } } /*------------------------------------------------------------------* * read quantized gains and new values for MA predictor memories * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *------------------------------------------------------------------*/ /* Read the quantized gains */ p = &qua_gain_code[add(add(index, index, pOverflow), index, 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); return index;}/*------------------------------------------------------------------------------ FUNCTION NAME: MR795_gain_quant------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONSMR795_gain_quant( Inputs: adapt_st -- Pointer to GainAdaptState -- gain adapter state structure res -- Word16 array -- LP residual, Q0 exc -- Word16 array -- LTP excitation (unfiltered), Q0 code -- Word16 array -- CB innovation (unfiltered), Q13 frac_coeff -- Word16 array -- coefficients (5), Q15 exp_coeff -- Word16 array -- energy coefficients (5), Q0 coefficients from calc_filt_ener() exp_code_en -- Word16 -- innovation energy (exponent), Q0 frac_code_en -- Word16 -- innovation energy (fraction), Q15 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15 L_subfr -- Word16 -- Subframe length cod_gain_frac -- Word16 -- opt. codebook gain (fraction),Q15 cod_gain_exp -- Word16 -- opt. codebook gain (exponent), Q0 gp_limit -- Word16 -- pitch gain limit gain_pit -- Pointer to Word16 -- Pitch gain, Q14 Output adapt_st -- Pointer to GainAdaptState -- gain adapter state structure gain_pit -- Pointer to Word16 -- Pitch gain, Q14 gain_pit -- Pointer to Word16 -- Pitch gain, Q14 gain_cod -- Pointer to Word16 -- Code gain, Q1 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) anap -- Double Pointer to Word16 -- Index of quantization (first gain pitch, then code pitch) pOverflow -- Pointer to Flag -- overflow indicator Returns: None Global Variables Used: None Local Variables Needed: None------------------------------------------------------------------------------ FUNCTION DESCRIPTION pitch and codebook quantization for MR795------------------------------------------------------------------------------ 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]------------------------------------------------------------------------------*/voidMR795_gain_quant( GainAdaptState *adapt_st, /* i/o: gain adapter state structure */ Word16 res[], /* i : LP residual, Q0 */ Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ Word16 code[], /* i : CB innovation (unfiltered), Q13 */ Word16 frac_coeff[], /* i : coefficients (5), Q15 */ Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ /* coefficients from calc_filt_ener() */ Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */ Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */ Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ Word16 L_subfr, /* i : Subframe length */ Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */ Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */ Word16 gp_limit, /* i : pitch gain limit */ Word16 *gain_pit, /* i/o: Pitch gain, Q14 */ Word16 *gain_cod, /* o : Code gain, 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) */ Word16 **anap, /* o : Index of quantization */ /* (first gain pitch, then code pitch)*/ Flag *pOverflow /* o : overflow indicator */){ Word16 frac_en[4]; Word16 exp_en[4]; Word16 ltpg, alpha, gcode0; Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */ Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */ Word16 gain_pit_index; Word16 gain_cod_index; Word16 exp; Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */ /* get list of candidate quantized pitch gain values * and corresponding quantization indices */ gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit, g_pitch_cand, g_pitch_cind, pOverflow); /*-------------------------------------------------------------------* * predicted codebook gain * * ~~~~~~~~~~~~~~~~~~~~~~~ * * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * * * * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * *-------------------------------------------------------------------*/ gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */ /* pre-quantization of codebook gain * (using three pitch gain candidates); * result: best guess of pitch gain and code gain */ MR795_gain_code_quant3( exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind, frac_coeff, exp_coeff, gain_pit, &gain_pit_index, gain_cod, &gain_cod_index, qua_ener_MR122, qua_ener, pOverflow); /* calculation of energy coefficients and LTP coding gain */ calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr, frac_en, exp_en, <pg, pOverflow); /* run gain adaptor, calculate alpha factor to balance LTP/CB gain * (this includes the gain adaptor update) * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case */ gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow); /* if this is a very low energy signal (threshold: see * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer */ if (frac_en[0] != 0 && alpha > 0) { /* innovation energy <cod cod> was already computed in gc_pred() */ /* (this overwrites the LtpResEn which is no longer needed) */ frac_en[3] = frac_code_en; exp_en[3] = exp_code_en; /* store optimum codebook gain in Q(10-exp_gcode0) */ exp = add(sub(cod_gain_exp, exp_gcode0, pOverflow), 10, pOverflow); gain_cod_unq = shl(cod_gain_frac, exp, pOverflow); /* run quantization with modified criterion */ gain_cod_index = MR795_gain_code_quant_mod( *gain_pit, exp_gcode0, gcode0, frac_en, exp_en, alpha, gain_cod_unq, gain_cod, qua_ener_MR122, qua_ener, pOverflow); /* function result */ } *(*anap)++ = gain_pit_index; *(*anap)++ = gain_cod_index;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -