/*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ void d_gain_code( gc_predState *pred_state, /* i/o : MA predictor state */ enum Mode mode, /* i : AMR mode (MR795 or MR122) */ Word16 index, /* i : received quantization index */ Word16 code[], /* i : innovation codevector */ Word16 *gain_code, /* o : decoded innovation gain */ Flag *pOverflow ) { Word16 gcode0, exp, frac; const Word16 *p; Word16 qua_ener_MR122, qua_ener; Word16 exp_inn_en; Word16 frac_inn_en; Word32 L_tmp; Word16 tbl_tmp; Word16 temp; /*-------------- Decode codebook gain ---------------*/ /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, &exp_inn_en, &frac_inn_en, pOverflow); tbl_tmp = add(add(index, index, pOverflow), index, pOverflow); p = &qua_gain_code[tbl_tmp]; /* Different scalings between MR122 and the other modes */ temp = sub((Word16)mode, (Word16)MR122, pOverflow); if (temp == 0) { gcode0 = (Word16)(Pow2(exp, frac, pOverflow)); /* predicted gain */ gcode0 = shl(gcode0, 4, pOverflow); *gain_code = shl(mult(gcode0, *p++, pOverflow), 1, pOverflow); } else { gcode0 = (Word16)(Pow2(14, frac, pOverflow)); L_tmp = L_mult(*p++, gcode0, pOverflow); L_tmp = L_shr(L_tmp, sub(9, exp, pOverflow), pOverflow); *gain_code = extract_h(L_tmp); /* Q1 */ } /*-------------------------------------------------------------------* * update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *-------------------------------------------------------------------*/ qua_ener_MR122 = *p++; qua_ener = *p++; gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
/************************************************************************* * * FUNCTION: Dec_gain() * * PURPOSE: Decode the pitch and codebook gains * ************************************************************************/ void Dec_gain( gc_predState *pred_state, /* i/o: MA predictor state */ enum Mode mode, /* i : AMR mode */ Word16 index, /* i : index of quantization. */ Word16 code[], /* i : Innovative vector. */ Word16 evenSubfr, /* i : Flag for even subframes */ Word16 * gain_pit, /* o : Pitch gain. */ Word16 * gain_cod /* o : Code gain. */ ) { const Word16 *p; Word16 frac, gcode0, exp, qua_ener, qua_ener_MR122; Word16 g_code; Word32 L_tmp; /* Read the quantized gains (table depends on mode) */ index = shl (index, 2); test(); test(); test(); if ( sub (mode, MR102) == 0 || sub (mode, MR74) == 0 || sub (mode, MR67) == 0) { p = &table_gain_highrates[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); qua_ener_MR122 = *p++; move16 (); qua_ener = *p; move16 (); } else { test(); if (sub (mode, MR475) == 0) { index = add (index, shl(sub(1, evenSubfr), 1)); p = &table_gain_MR475[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); /*---------------------------------------------------------* * calculate predictor update values (not stored in 4.75 * * quantizer table to save space): * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * qua_ener = log2(g) * * qua_ener_MR122 = 20*log10(g) * *---------------------------------------------------------*/ /* Log2(x Q12) = log2(x) + 12 */ Log2 (L_deposit_l (g_code), &exp, &frac); exp = sub(exp, 12); qua_ener_MR122 = add (shr_r (frac, 5), shl (exp, 10)); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ L_tmp = Mpy_32_16(exp, frac, 24660); qua_ener = round (L_shl (L_tmp, 13)); /* Q12 * Q0 = Q13 -> Q10 */ } else { p = &table_gain_lowrates[index]; move16 (); *gain_pit = *p++; move16 (); g_code = *p++; move16 (); qua_ener_MR122 = *p++; move16 (); qua_ener = *p; move16 (); } } /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL); gcode0 = extract_l(Pow2(14, frac)); /*------------------------------------------------------------------* * read quantized gains, update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * * = Log2(g_fac) * * = qua_ener * * constant = 20*Log10(2) * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0); L_tmp = L_shr(L_tmp, sub(10, exp)); *gain_cod = extract_h(L_tmp); /* update table of past quantized energies */ gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
//============================================================================= //函数名称:Dec_gain //函数功能:解码的音调和码书增益 //============================================================================= void Dec_gain( gc_predState *pred_state, /* i/o: MA predictor state */ enum Mode mode, /* i : AMR mode */ Word16 index, /* i : index of quantization. */ Word16 code[], /* i : Innovative vector. */ Word16 evenSubfr, /* i : Flag for even subframes */ Word16 * gain_pit, /* o : Pitch gain. */ Word16 * gain_cod, /* o : Code gain. */ Flag * pOverflow ) { const Word16 *p; Word16 frac; Word16 gcode0; Word16 exp; Word16 qua_ener; Word16 qua_ener_MR122; Word16 g_code; Word32 L_tmp; Word16 temp1; Word16 temp2; /* Read the quantized gains (table depends on mode) */ //阅读量化收益(表取决于模式) index = shl(index, 2, pOverflow); if (mode == MR102 || mode == MR74 || mode == MR67) { p = &table_gain_highrates[index]; *gain_pit = *p++; g_code = *p++; qua_ener_MR122 = *p++; qua_ener = *p; } else { if (mode == MR475) { index += (1 ^ evenSubfr) << 1; /* evenSubfr is 0 or 1 */ if (index > (MR475_VQ_SIZE*4 - 2)) { index = (MR475_VQ_SIZE * 4 - 2); /* avoid possible buffer overflow */ } p = &table_gain_MR475[index]; *gain_pit = *p++; g_code = *p++; /*---------------------------------------------------------* * calculate predictor update values (not stored in 4.75 * * quantizer table to save space): * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * * * qua_ener = log2(g) * * qua_ener_MR122 = 20*log10(g) * *---------------------------------------------------------*/ //计算预测更新值(不存储在4.75量化表,以节省空间) /* Log2(x Q12) = log2(x) + 12 */ temp1 = (Word16) L_deposit_l(g_code); Log2(temp1, &exp, &frac, pOverflow); exp = sub(exp, 12, pOverflow); temp1 = shr_r(frac, 5, pOverflow); temp2 = shl(exp, 10, pOverflow); qua_ener_MR122 = add(temp1, temp2, pOverflow); /* 24660 Q12 ~= 6.0206 = 20*log10(2) */ L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow); L_tmp = L_shl(L_tmp, 13, pOverflow); qua_ener = pv_round(L_tmp, pOverflow); /* Q12 * Q0 = Q13 -> Q10 */ } else { p = &table_gain_lowrates[index]; *gain_pit = *p++; g_code = *p++; qua_ener_MR122 = *p++; qua_ener = *p; } } /*-------------------------------------------------------------------* * predict codebook gain * * ~~~~~~~~~~~~~~~~~~~~~ * * gc0 = Pow2(int(d)+frac(d)) * * = 2^exp + 2^frac * * * * gcode0 (Q14) = 2^14*2^frac = gc0 * 2^(14-exp) * *-------------------------------------------------------------------*/ gc_pred(pred_state, mode, code, &exp, &frac, NULL, NULL, pOverflow); gcode0 = (Word16) Pow2(14, frac, pOverflow); /*------------------------------------------------------------------* * read quantized gains, update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * st->past_qua_en(Q10) = 20 * Log10(g_fac) / constant * * = Log2(g_fac) * * = qua_ener * * constant = 20*Log10(2) * *------------------------------------------------------------------*/ L_tmp = L_mult(g_code, gcode0, pOverflow); temp1 = sub(10, exp, pOverflow); L_tmp = L_shr(L_tmp, temp1, pOverflow); *gain_cod = extract_h(L_tmp); /* update table of past quantized energies */ //过去的量化能量表更新 gc_pred_update(pred_state, qua_ener_MR122, qua_ener); return; }
int gainQuant( gainQuantState *st, /* i/o : State struct */ enum Mode mode, /* i : coder mode */ Word16 res[], /* i : LP residual, Q0 */ Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ Word16 code[], /* i : CB innovation (unfiltered), Q13 */ /* (unsharpened for MR475) */ Word16 xn[], /* i : Target vector. */ Word16 xn2[], /* i : Target vector. */ Word16 y1[], /* i : Adaptive codebook. */ Word16 Y2[], /* i : Filtered innovative vector. */ Word16 g_coeff[], /* i : Correlations <xn y1> <y1 y1> */ /* Compute in G_pitch(). */ Word16 even_subframe, /* i : even subframe indicator flag */ Word16 gp_limit, /* i : pitch gain limit */ Word16 *sf0_gain_pit, /* o : Pitch gain sf 0. MR475 */ Word16 *sf0_gain_cod, /* o : Code gain sf 0. MR475 */ Word16 *gain_pit, /* i/o : Pitch gain. */ Word16 *gain_cod, /* o : Code gain. */ /* MR475: gain_* unquantized in even */ /* subframes, quantized otherwise */ Word16 **anap /* o : Index of quantization */ ) { Word16 exp_gcode0; Word16 frac_gcode0; Word16 qua_ener_MR122; Word16 qua_ener; Word16 frac_coeff[5]; Word16 exp_coeff[5]; Word16 exp_en, frac_en; Word16 cod_gain_exp, cod_gain_frac; test (); if (sub (mode, MR475) == 0) { test (); if (even_subframe != 0) { /* save position in output parameter stream and current state of codebook gain predictor */ st->gain_idx_ptr = (*anap)++; gc_pred_copy(st->gc_predSt, st->gc_predUnqSt); /* predict codebook gain (using "unquantized" predictor)*/ /* (note that code[] is unsharpened in MR475) */ gc_pred(st->gc_predUnqSt, mode, code, &st->sf0_exp_gcode0, &st->sf0_frac_gcode0, &exp_en, &frac_en); /* calculate energy coefficients for quantization and store them in state structure (will be used in next subframe when real quantizer is run) */ calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff, st->sf0_frac_coeff, st->sf0_exp_coeff, &cod_gain_frac, &cod_gain_exp); /* store optimum codebook gain (Q1) */ *gain_cod = shl (cod_gain_frac, add (cod_gain_exp, 1)); move16 (); calc_target_energy(xn, &st->sf0_exp_target_en, &st->sf0_frac_target_en); /* calculate optimum codebook gain and update "unquantized" predictor */ MR475_update_unq_pred(st->gc_predUnqSt, st->sf0_exp_gcode0, st->sf0_frac_gcode0, cod_gain_exp, cod_gain_frac); /* the real quantizer is not run here... */ } else { /* predict codebook gain (using "unquantized" predictor) */ /* (note that code[] is unsharpened in MR475) */ gc_pred(st->gc_predUnqSt, mode, code, &exp_gcode0, &frac_gcode0, &exp_en, &frac_en); /* calculate energy coefficients for quantization */ calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff, frac_coeff, exp_coeff, &cod_gain_frac, &cod_gain_exp); calc_target_energy(xn, &exp_en, &frac_en); /* run real (4-dim) quantizer and update real gain predictor */ *st->gain_idx_ptr = MR475_gain_quant( st->gc_predSt, st->sf0_exp_gcode0, st->sf0_frac_gcode0, st->sf0_exp_coeff, st->sf0_frac_coeff, st->sf0_exp_target_en, st->sf0_frac_target_en, code, exp_gcode0, frac_gcode0, exp_coeff, frac_coeff, exp_en, frac_en, gp_limit, sf0_gain_pit, sf0_gain_cod, gain_pit, gain_cod); } } else { /*-------------------------------------------------------------------* * predict codebook gain and quantize * * (also compute normalized CB innovation energy for MR795) * *-------------------------------------------------------------------*/ gc_pred(st->gc_predSt, mode, code, &exp_gcode0, &frac_gcode0, &exp_en, &frac_en); test (); if (sub(mode, MR122) == 0) { *gain_cod = G_code (xn2, Y2); move16 (); *(*anap)++ = q_gain_code (mode, exp_gcode0, frac_gcode0, gain_cod, &qua_ener_MR122, &qua_ener); move16 (); } else { /* calculate energy coefficients for quantization */ calc_filt_energies(mode, xn, xn2, y1, Y2, g_coeff, frac_coeff, exp_coeff, &cod_gain_frac, &cod_gain_exp); test (); if (sub (mode, MR795) == 0) { MR795_gain_quant(st->adaptSt, res, exc, code, frac_coeff, exp_coeff, exp_en, frac_en, exp_gcode0, frac_gcode0, L_SUBFR, cod_gain_frac, cod_gain_exp, gp_limit, gain_pit, gain_cod, &qua_ener_MR122, &qua_ener, anap); } else { *(*anap)++ = Qua_gain(mode, exp_gcode0, frac_gcode0, frac_coeff, exp_coeff, gp_limit, gain_pit, gain_cod, &qua_ener_MR122, &qua_ener); move16 (); } } /*------------------------------------------------------------------* * update table of past quantized energies * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * st->past_qua_en(Q10) = 20 * Log10(qua_gain_code) / constant * * = Log2(qua_gain_code) * * = qua_ener * * constant = 20*Log10(2) * *------------------------------------------------------------------*/ gc_pred_update(st->gc_predSt, qua_ener_MR122, qua_ener); } return 0; }