static Word16 MR795_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) */ const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr */ 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, (10 - exp_gcode0), 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_16((32767 - alpha), 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 = (Word16)(L_t1 >> 16); /* directly store in 32 bit variable because no further mult. required */ L_t1 = L_mult(tmp, g2_pitch, pOverflow); exp_coeff[1] = exp_en[1] - 15; tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16); coeff[2] = mult(tmp, gain_pit, pOverflow); exp = exp_gcode0 - 10; exp_coeff[2] = add_16(exp_en[2], exp, pOverflow); /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16); exp = shl(exp_gcode0, 1, pOverflow) - 7; exp_coeff[3] = add_16(exp_en[3], exp, pOverflow); coeff[4] = mult(one_alpha, frac_en[3], pOverflow); exp_coeff[4] = add_16(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 += 47; exp_coeff[0] = exp_en[0] - exp; /* * 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 = exp_coeff[0] + 31; 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 = e_max - exp_coeff[1]; 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 = e_max - exp_coeff[i]; L_tmp = ((Word32)coeff[i] << 16); 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 = e_max - 31; /* new exponent */ tmp = exp - exp_coeff[0]; 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_ptr[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_ptr[(index<<2) - index]; 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, 9 - exp_gcode0, pOverflow); *gain_cod = (Word16)(L_tmp >> 16); return index; }
/* ************************************************************************** * * Function : Decoder_amr * Purpose : Speech decoder routine. * ************************************************************************** */ int Decoder_amr ( Decoder_amrState *st, /* i/o : State variables */ enum Mode mode, /* i : AMR mode */ Word16 parm[], /* i : vector of synthesis parameters (PRM_SIZE) */ enum RXFrameType frame_type, /* i : received frame type */ Word16 synth[], /* o : synthesis speech (L_FRAME) */ Word16 A_t[] /* o : decoded LP filter in 4 subframes (AZ_SIZE) */ ) { /* LPC coefficients */ Word16 *Az; /* Pointer on A_t */ /* LSPs */ Word16 lsp_new[M]; Word16 lsp_mid[M]; /* LSFs */ Word16 prev_lsf[M]; Word16 lsf_i[M]; /* Algebraic codevector */ Word16 code[L_SUBFR]; /* excitation */ Word16 excp[L_SUBFR]; Word16 exc_enhanced[L_SUBFR]; /* Scalars */ Word16 i, i_subfr; Word16 T0, T0_frac, index, index_mr475 = 0; Word16 gain_pit, gain_code, gain_code_mix, pit_sharp, pit_flag, pitch_fac; Word16 t0_min, t0_max; Word16 delta_frc_low, delta_frc_range; Word16 tmp_shift; Word16 temp; Word32 L_temp; Word16 flag4; Word16 carefulFlag; Word16 excEnergy; Word16 subfrNr; Word16 evenSubfr = 0; Word16 bfi = 0; /* bad frame indication flag */ Word16 pdfi = 0; /* potential degraded bad frame flag */ enum DTXStateType newDTXState; /* SPEECH , DTX, DTX_MUTE */ /* find the new DTX state SPEECH OR DTX */ newDTXState = rx_dtx_handler(st->dtxDecoderState, frame_type); move16 (); /* function result */ /* DTX actions */ test(); if (sub(newDTXState, SPEECH) != 0 ) { Decoder_amr_reset (st, MRDTX); dtx_dec(st->dtxDecoderState, st->mem_syn, st->lsfState, st->pred_state, st->Cb_gain_averState, newDTXState, mode, parm, synth, A_t); /* update average lsp */ Lsf_lsp(st->lsfState->past_lsf_q, st->lsp_old, M); lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); goto the_end; } /* SPEECH action state machine */ test (); test (); test (); if ((sub(frame_type, RX_SPEECH_BAD) == 0) || (sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { bfi = 1; move16 (); test(); test(); if ((sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { build_CN_param(&st->nodataSeed, prmno[mode], bitno[mode], parm); } } else if (sub(frame_type, RX_SPEECH_DEGRADED) == 0) { pdfi = 1; move16 (); } test(); if (bfi != 0) { st->state = add (st->state, 1); } else if (sub (st->state, 6) == 0) { st->state = 5; move16 (); } else { st->state = 0; move16 (); } test (); if (sub (st->state, 6) > 0) { st->state = 6; move16 (); } /* If this frame is the first speech frame after CNI period, */ /* set the BFH state machine to an appropriate state depending */ /* on whether there was DTX muting before start of speech or not */ /* If there was DTX muting, the first speech frame is muted. */ /* If there was no DTX muting, the first speech frame is not */ /* muted. The BFH state machine starts from state 5, however, to */ /* keep the audible noise resulting from a SID frame which is */ /* erroneously interpreted as a good speech frame as small as */ /* possible (the decoder output in this case is quickly muted) */ test(); if (sub(st->dtxDecoderState->dtxGlobalState, DTX) == 0) { st->state = 5; move16 (); st->prev_bf = 0; move16 (); } else if (test (), sub(st->dtxDecoderState->dtxGlobalState, DTX_MUTE) == 0) { st->state = 5; move16 (); st->prev_bf = 1; move16 (); } /* save old LSFs for CB gain smoothing */ Copy (st->lsfState->past_lsf_q, prev_lsf, M); /* decode LSF parameters and generate interpolated lpc coefficients for the 4 subframes */ test (); if (sub (mode, MR122) != 0) { D_plsf_3(st->lsfState, mode, bfi, parm, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 3; move16 (); Int_lpc_1to3(st->lsp_old, lsp_new, A_t); } else { D_plsf_5 (st->lsfState, bfi, parm, lsp_mid, lsp_new); fwc (); /* function worst case */ /* Advance synthesis parameters pointer */ parm += 5; move16 (); Int_lpc_1and3 (st->lsp_old, lsp_mid, lsp_new, A_t); } /* update the LSPs for the next frame */ for (i = 0; i < M; i++) { st->lsp_old[i] = lsp_new[i]; move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------------------* * Loop for every subframe in the analysis frame * *------------------------------------------------------------------------* * The subframe size is L_SUBFR and the loop is repeated L_FRAME/L_SUBFR * * times * * - decode the pitch delay * * - decode algebraic code * * - decode pitch and codebook gains * * - find the excitation and compute synthesis speech * *------------------------------------------------------------------------*/ /* pointer to interpolated LPC parameters */ Az = A_t; move16 (); evenSubfr = 0; move16(); subfrNr = -1; move16(); for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR) { subfrNr = add(subfrNr, 1); evenSubfr = sub(1, evenSubfr); /* flag for first and 3th subframe */ pit_flag = i_subfr; move16 (); test(); if (sub (i_subfr, L_FRAME_BY2) == 0) { test(); test(); if (sub(mode, MR475) != 0 && sub(mode, MR515) != 0) { pit_flag = 0; move16 (); } } /* pitch index */ index = *parm++; move16 (); /*-------------------------------------------------------* * - decode pitch lag and find adaptive codebook vector. * *-------------------------------------------------------*/ test (); if (sub(mode, MR122) != 0) { /* flag4 indicates encoding with 4 bit resolution; */ /* this is needed for mode MR475, MR515, MR59 and MR67 */ flag4 = 0; move16 (); test (); test (); test (); test (); if ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0) || (sub (mode, MR67) == 0) ) { flag4 = 1; move16 (); } /*-------------------------------------------------------* * - get ranges for the t0_min and t0_max * * - only needed in delta decoding * *-------------------------------------------------------*/ delta_frc_low = 5; move16(); delta_frc_range = 9; move16(); test (); if ( sub(mode, MR795) == 0 ) { delta_frc_low = 10; move16(); delta_frc_range = 19; move16(); } t0_min = sub(st->old_T0, delta_frc_low); test (); if (sub(t0_min, PIT_MIN) < 0) { t0_min = PIT_MIN; move16(); } t0_max = add(t0_min, delta_frc_range); test (); if (sub(t0_max, PIT_MAX) > 0) { t0_max = PIT_MAX; move16(); t0_min = sub(t0_max, delta_frc_range); } Dec_lag3 (index, t0_min, t0_max, pit_flag, st->old_T0, &T0, &T0_frac, flag4); st->T0_lagBuff = T0; move16 (); test (); if (bfi != 0) { test (); if (sub (st->old_T0, PIT_MAX) < 0) { /* Graceful pitch */ st->old_T0 = add(st->old_T0, 1); /* degradation */ } T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); test (); test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && sub(st->voicedHangover, 4) > 0 && ((sub(mode, MR475) == 0 ) || (sub(mode, MR515) == 0 ) || (sub(mode, MR59) == 0) ) ) { T0 = st->T0_lagBuff; move16 (); } } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 1); } else { Dec_lag6 (index, PIT_MIN_MR122, PIT_MAX, pit_flag, &T0, &T0_frac); test (); test (); test (); if ( bfi == 0 && (pit_flag == 0 || sub (index, 61) < 0)) { } else { st->T0_lagBuff = T0; move16 (); T0 = st->old_T0; move16 (); T0_frac = 0; move16 (); } fwc (); /* function worst case */ Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); } fwc (); /* function worst case */ /*-------------------------------------------------------* * - (MR122 only: Decode pitch gain.) * * - Decode innovative codebook. * * - set pitch sharpening factor * *-------------------------------------------------------*/ test (); test (); if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) { /* MR475, MR515 */ index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_9bits (subfrNr, i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR59) == 0) { /* MR59 */ test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_2i40_11bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR67) == 0) { /* MR67 */ test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_3i40_14bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR795) <= 0) { /* MR74, MR795 */ test (); test (); test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); fwc (); /* function worst case */ decode_4i40_17bits (i, index, code); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR102) == 0) { /* MR102 */ test (); test (); test (); fwc (); /* function worst case */ dec_8i40_31bits (parm, code); parm += 7; move16 (); fwc (); /* function worst case */ pit_sharp = shl (st->sharp, 1); } else { /* MR122 */ test (); test (); test (); index = *parm++; move16 (); test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); fwc (); /* function worst case */ dec_10i40_35bits (parm, code); parm += 10; move16 (); fwc (); /* function worst case */ /* pit_sharp = gain_pit; */ /* if (pit_sharp > 1.0) pit_sharp = 1.0; */ pit_sharp = shl (gain_pit, 1); } /*-------------------------------------------------------* * - Add the pitch contribution to code[]. * *-------------------------------------------------------*/ for (i = T0; i < L_SUBFR; i++) { temp = mult (code[i - T0], pit_sharp); code[i] = add (code[i], temp); move16 (); } fwc (); /* function worst case */ /*------------------------------------------------------------* * - Decode codebook gain (MR122) or both pitch * * gain and codebook gain (all others) * * - Update pitch sharpening "sharp" with quantized gain_pit * *------------------------------------------------------------*/ if (test(), sub (mode, MR475) == 0) { /* read and decode pitch and code gain */ test(); if (evenSubfr != 0) { index_mr475 = *parm++; move16 (); /* index of gain(s) */ } test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index_mr475, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else if (test(), test(), (sub (mode, MR74) <= 0) || (sub (mode, MR102) == 0)) { /* read and decode pitch and code gain */ index = *parm++; move16 (); /* index of gain(s) */ test(); if (bfi == 0) { Dec_gain(st->pred_state, mode, index, code, evenSubfr, &gain_pit, &gain_code); } else { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } if (sub (mode, MR102) == 0) { if (sub (st->old_T0, add(L_SUBFR, 5)) > 0) { pit_sharp = shr(pit_sharp, 2); } } } else { /* read and decode pitch gain */ index = *parm++; move16 (); /* index of gain(s) */ test (); if (sub (mode, MR795) == 0) { /* decode pitch gain */ test(); if (bfi != 0) { ec_gain_pitch (st->ec_gain_p_st, st->state, &gain_pit); } else { gain_pit = d_gain_pitch (mode, index); move16 (); } ec_gain_pitch_update (st->ec_gain_p_st, bfi, st->prev_bf, &gain_pit); /* read and decode code gain */ index = *parm++; move16 (); test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); test (); if (sub (pit_sharp, SHARPMAX) > 0) { pit_sharp = SHARPMAX; move16 (); } } else { /* MR122 */ test(); if (bfi == 0) { d_gain_code (st->pred_state, mode, index, code, &gain_code); } else { ec_gain_code (st->ec_gain_c_st, st->pred_state, st->state, &gain_code); } ec_gain_code_update (st->ec_gain_c_st, bfi, st->prev_bf, &gain_code); fwc (); /* function worst case */ pit_sharp = gain_pit; move16 (); } } /* store pitch sharpening for next subframe */ /* (for modes which use the previous pitch gain for pitch sharpening in the search phase) */ /* do not update sharpening in even subframes for MR475 */ test(); test(); if (sub(mode, MR475) != 0 || evenSubfr == 0) { st->sharp = gain_pit; move16 (); test (); if (sub (st->sharp, SHARPMAX) > 0) { st->sharp = SHARPMAX; move16 (); } } pit_sharp = shl (pit_sharp, 1); test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { temp = mult (st->exc[i], pit_sharp); L_temp = L_mult (temp, gain_pit); test (); if (sub(mode, MR122)==0) { L_temp = L_shr (L_temp, 1); } excp[i] = round (L_temp); move16 (); } } /*-------------------------------------------------------* * - Store list of LTP gains needed in the source * * characteristic detector (SCD) * *-------------------------------------------------------*/ test (); if ( bfi == 0 ) { for (i = 0; i < 8; i++) { st->ltpGainHistory[i] = st->ltpGainHistory[i+1]; move16 (); } st->ltpGainHistory[8] = gain_pit; move16 (); } /*-------------------------------------------------------* * - Limit gain_pit if in background noise and BFI * * for MR475, MR515, MR59 * *-------------------------------------------------------*/ test (); test (); test (); test (); test (); test (); if ( (st->prev_bf != 0 || bfi != 0) && st->inBackgroundNoise != 0 && ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) ) { test (); if ( sub (gain_pit, 12288) > 0) /* if (gain_pit > 0.75) in Q14*/ gain_pit = add( shr( sub(gain_pit, 12288), 1 ), 12288 ); /* gain_pit = (gain_pit-0.75)/2.0 + 0.75; */ test (); if ( sub (gain_pit, 14745) > 0) /* if (gain_pit > 0.90) in Q14*/ { gain_pit = 14745; move16 (); } } /*-------------------------------------------------------* * Calculate CB mixed gain * *-------------------------------------------------------*/ Int_lsf(prev_lsf, st->lsfState->past_lsf_q, i_subfr, lsf_i); gain_code_mix = Cb_gain_average( st->Cb_gain_averState, mode, gain_code, lsf_i, st->lsp_avg_st->lsp_meanSave, bfi, st->prev_bf, pdfi, st->prev_pdf, st->inBackgroundNoise, st->voicedHangover); move16 (); /* make sure that MR74, MR795, MR122 have original code_gain*/ test(); if ((sub(mode, MR67) > 0) && (sub(mode, MR102) != 0) ) /* MR74, MR795, MR122 */ { gain_code_mix = gain_code; move16 (); } /*-------------------------------------------------------* * - Find the total excitation. * * - Find synthesis speech corresponding to st->exc[]. * *-------------------------------------------------------*/ test (); if (sub(mode, MR102) <= 0) /* MR475, MR515, MR59, MR67, MR74, MR795, MR102*/ { pitch_fac = gain_pit; move16 (); tmp_shift = 1; move16 (); } else /* MR122 */ { pitch_fac = shr (gain_pit, 1); move16 (); tmp_shift = 2; move16 (); } /* copy unscaled LTP excitation to exc_enhanced (used in phase * dispersion below) and compute total excitation for LTP feedback */ for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = st->exc[i]; move16 (); /* st->exc[i] = gain_pit*st->exc[i] + gain_code*code[i]; */ L_temp = L_mult (st->exc[i], pitch_fac); /* 12.2: Q0 * Q13 */ /* 7.4: Q0 * Q14 */ L_temp = L_mac (L_temp, code[i], gain_code); /* 12.2: Q12 * Q1 */ /* 7.4: Q13 * Q1 */ L_temp = L_shl (L_temp, tmp_shift); /* Q16 */ st->exc[i] = round (L_temp); move16 (); } /*-------------------------------------------------------* * - Adaptive phase dispersion * *-------------------------------------------------------*/ ph_disp_release(st->ph_disp_st); /* free phase dispersion adaption */ test (); test (); test (); test (); test (); test (); if ( ((sub(mode, MR475) == 0) || (sub(mode, MR515) == 0) || (sub(mode, MR59) == 0)) && sub(st->voicedHangover, 3) > 0 && st->inBackgroundNoise != 0 && bfi != 0 ) { ph_disp_lock(st->ph_disp_st); /* Always Use full Phase Disp. */ } /* if error in bg noise */ /* apply phase dispersion to innovation (if enabled) and compute total excitation for synthesis part */ ph_disp(st->ph_disp_st, mode, exc_enhanced, gain_code_mix, gain_pit, code, pitch_fac, tmp_shift); /*-------------------------------------------------------* * - The Excitation control module are active during BFI.* * - Conceal drops in signal energy if in bg noise. * *-------------------------------------------------------*/ L_temp = 0; move32 (); for (i = 0; i < L_SUBFR; i++) { L_temp = L_mac (L_temp, exc_enhanced[i], exc_enhanced[i] ); } L_temp = L_shr (L_temp, 1); /* excEnergy = sqrt(L_temp) in Q0 */ L_temp = sqrt_l_exp(L_temp, &temp); move32 (); /* function result */ L_temp = L_shr(L_temp, add( shr(temp, 1), 15)); L_temp = L_shr(L_temp, 2); /* To cope with 16-bit and */ excEnergy = extract_l(L_temp); /* scaling in ex_ctrl() */ test (); test (); test (); test (); test (); test (); test (); test (); test (); test (); if ( ((sub (mode, MR475) == 0) || (sub (mode, MR515) == 0) || (sub (mode, MR59) == 0)) && sub(st->voicedHangover, 5) > 0 && st->inBackgroundNoise != 0 && sub(st->state, 4) < 0 && ( (pdfi != 0 && st->prev_pdf != 0) || bfi != 0 || st->prev_bf != 0) ) { carefulFlag = 0; move32 (); test (); test (); if ( pdfi != 0 && bfi == 0 ) { carefulFlag = 1; move16 (); } Ex_ctrl(exc_enhanced, excEnergy, st->excEnergyHist, st->voicedHangover, st->prev_bf, carefulFlag); } test (); test (); test (); test (); if ( st->inBackgroundNoise != 0 && ( bfi != 0 || st->prev_bf != 0 ) && sub(st->state, 4) < 0 ) { ; /* do nothing! */ } else { /* Update energy history for all modes */ for (i = 0; i < 8; i++) { st->excEnergyHist[i] = st->excEnergyHist[i+1]; move16 (); } st->excEnergyHist[8] = excEnergy; move16 (); } /*-------------------------------------------------------* * Excitation control module end. * *-------------------------------------------------------*/ fwc (); /* function worst case */ test (); if (sub (pit_sharp, 16384) > 0) { for (i = 0; i < L_SUBFR; i++) { excp[i] = add (excp[i], exc_enhanced[i]); move16 (); } agc2 (exc_enhanced, excp, L_SUBFR); Overflow = 0; move16 (); Syn_filt (Az, excp, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } else { Overflow = 0; move16 (); Syn_filt (Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 0); } test (); if (Overflow != 0) /* Test for overflow */ { for (i = 0; i < PIT_MAX + L_INTERPOL + L_SUBFR; i++) { st->old_exc[i] = shr(st->old_exc[i], 2); move16 (); } for (i = 0; i < L_SUBFR; i++) { exc_enhanced[i] = shr(exc_enhanced[i], 2); move16 (); } Syn_filt(Az, exc_enhanced, &synth[i_subfr], L_SUBFR, st->mem_syn, 1); } else { Copy(&synth[i_subfr+L_SUBFR-M], st->mem_syn, M); } /*--------------------------------------------------* * Update signal for next frame. * * -> shift to the left by L_SUBFR st->exc[] * *--------------------------------------------------*/ Copy (&st->old_exc[L_SUBFR], &st->old_exc[0], PIT_MAX + L_INTERPOL); fwc (); /* function worst case */ /* interpolated LPC parameters for next subframe */ Az += MP1; move16 (); /* store T0 for next subframe */ st->old_T0 = T0; move16 (); } /*-------------------------------------------------------* * Call the Source Characteristic Detector which updates * * st->inBackgroundNoise and st->voicedHangover. * *-------------------------------------------------------*/ move16 (); /* function result */ st->inBackgroundNoise = Bgn_scd(st->background_state, &(st->ltpGainHistory[0]), &(synth[0]), &(st->voicedHangover) ); dtx_dec_activity_update(st->dtxDecoderState, st->lsfState->past_lsf_q, synth); fwc (); /* function worst case */ /* store bfi for next subframe */ st->prev_bf = bfi; move16 (); st->prev_pdf = pdfi; move16 (); /*--------------------------------------------------* * Calculate the LSF averages on the eight * * previous frames * *--------------------------------------------------*/ lsp_avg(st->lsp_avg_st, st->lsfState->past_lsf_q); fwc (); /* function worst case */ the_end: st->dtxDecoderState->dtxGlobalState = newDTXState; move16(); return 0; }