FreeCalypso > hg > gsm-codec-lib
view libtwamr/dec_amr.c @ 581:e2d5cad04cbf
libgsmhr1 RxFE: store CN R0+LPC separately from speech
In the original GSM 06.06 code the ECU for speech mode is entirely
separate from the CN generator, maintaining separate state. (The
main intertie between them is the speech vs CN state variable,
distinguishing between speech and CN BFIs, in addition to the
CN-specific function of distinguishing between initial and update
SIDs.)
In the present RxFE implementation I initially thought that we could
use the same saved_frame buffer for both ECU and CN, overwriting
just the first 4 params (R0 and LPC) when a valid SID comes in.
However, I now realize it was a bad idea: the original code has a
corner case (long sequence of speech-mode BFIs to put the ECU in
state 6, then SID and CN-mode BFIs, then a good speech frame) that
would be broken by that buffer reuse approach. We could eliminate
this corner case by resetting the ECU state when passing through
a CN insertion period, but doing so would needlessly increase
the behavioral diffs between GSM 06.06 and our version.
Solution: use a separate CN-specific buffer for CN R0+LPC parameters,
and match the behavior of GSM 06.06 code in this regard.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 13 Feb 2025 10:02:45 +0000 |
parents | 7bef001cd8b8 |
children |
line wrap: on
line source
/************************************************************************* * * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 * R99 Version 3.3.0 * REL-4 Version 4.1.0 * ***************************************************************************** * * File : dec_amr.c * Purpose : Decoding of one speech frame using given codec mode * ***************************************************************************** */ /* ***************************************************************************** * MODULE INCLUDE FILE AND VERSION ID ***************************************************************************** */ #include "namespace.h" #include "dec_amr.h" #include "typedef.h" #include "basic_op.h" #include "no_count.h" #include "cnst.h" #include "memops.h" #include "syn_filt.h" #include "d_plsf.h" #include "agc.h" #include "int_lpc.h" #include "dec_gain.h" #include "dec_lag3.h" #include "dec_lag6.h" #include "d2_9pf.h" #include "d2_11pf.h" #include "d3_14pf.h" #include "d4_17pf.h" #include "d8_31pf.h" #include "d1035pf.h" #include "pred_lt.h" #include "d_gain_p.h" #include "d_gain_c.h" #include "dec_gain.h" #include "ec_gains.h" #include "ph_disp.h" #include "c_g_aver.h" #include "int_lsf.h" #include "lsp_lsf.h" #include "lsp_avg.h" #include "bgnscd.h" #include "ex_ctrl.h" #include "sqrt_l.h" #include "lsp_tab.h" #include "bitno.h" #include "b_cn_cod.h" /* ***************************************************************************** * LOCAL VARIABLES AND TABLES ***************************************************************************** */ /*-----------------------------------------------------------------* * Decoder constant parameters (defined in "cnst.h") * *-----------------------------------------------------------------* * L_FRAME : Frame size. * * L_FRAME_BY2 : Half the frame size. * * L_SUBFR : Sub-frame size. * * M : LPC order. * * MP1 : LPC order+1 * * PIT_MIN : Minimum pitch lag. * * PIT_MIN_MR122 : Minimum pitch lag for the MR122 mode. * * PIT_MAX : Maximum pitch lag. * * L_INTERPOL : Length of filter for interpolation * * PRM_SIZE : size of vector containing analysis parameters * *-----------------------------------------------------------------*/ /* ***************************************************************************** * PUBLIC PROGRAM CODE ***************************************************************************** */ /* ************************************************************************** * * Function : Decoder_amr_reset * Purpose : Resets state memory * ************************************************************************** */ void Decoder_amr_reset (Decoder_amrState *state, Flag dtx_partial_reset) { Word16 i; /* Initialize static pointer */ state->exc = state->old_exc + PIT_MAX + L_INTERPOL; /* Static vectors to zero */ Set_zero (state->old_exc, PIT_MAX + L_INTERPOL); if (!dtx_partial_reset) Set_zero (state->mem_syn, M); /* initialize pitch sharpening */ state->sharp = SHARPMIN; state->old_T0 = 40; /* Initialize state->lsp_old [] */ if (!dtx_partial_reset) { Copy(lsp_init_data, &state->lsp_old[0], M); } /* Initialize memories of bad frame handling */ state->prev_bf = 0; state->prev_pdf = 0; state->state = 0; state->T0_lagBuff = 40; state->inBackgroundNoise = 0; state->voicedHangover = 0; if (!dtx_partial_reset) { for (i=0;i<9;i++) state->excEnergyHist[i] = 0; } for (i = 0; i < 9; i++) state->ltpGainHistory[i] = 0; Cb_gain_average_reset(&state->Cb_gain_averState); if (!dtx_partial_reset) lsp_avg_reset(&state->lsp_avg_st); D_plsf_reset(&state->lsfState); ec_gain_pitch_reset(&state->ec_gain_p_st); ec_gain_code_reset(&state->ec_gain_c_st); if (!dtx_partial_reset) gc_pred_reset(&state->pred_state); Bgn_scd_reset(&state->background_state); state->nodataSeed = 21845; ph_disp_reset(&state->ph_disp_st); if (!dtx_partial_reset) dtx_dec_reset(&state->dtxDecoderState); } /* ************************************************************************** * * 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); /* DTX actions */ if (sub(newDTXState, SPEECH) != 0 ) { Decoder_amr_reset (st, 1); 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 */ if ((sub(frame_type, RX_SPEECH_BAD) == 0) || (sub(frame_type, RX_NO_DATA) == 0) || (sub(frame_type, RX_ONSET) == 0)) { bfi = 1; 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; } 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 (); } 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) */ if (sub(st->dtxDecoderState.dtxGlobalState, DTX) == 0) { st->state = 5; st->prev_bf = 0; } else if (test (), sub(st->dtxDecoderState.dtxGlobalState, DTX_MUTE) == 0) { st->state = 5; st->prev_bf = 1; } /* 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 */ if (sub (mode, MR122) != 0) { D_plsf_3(&st->lsfState, mode, bfi, parm, lsp_new); /* 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); /* 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 (); } /*------------------------------------------------------------------------* * 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 (); } } 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 (); } Pred_lt_3or6 (st->exc, T0, T0_frac, L_SUBFR, 0); } /*-------------------------------------------------------* * - (MR122 only: Decode pitch gain.) * * - Decode innovative codebook. * * - set pitch sharpening factor * *-------------------------------------------------------*/ if (sub (mode, MR475) == 0 || sub (mode, MR515) == 0) { /* MR475, MR515 */ index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); decode_2i40_9bits (subfrNr, i, index, code); pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR59) == 0) { /* MR59 */ test (); index = *parm++; /* index of position */ move16 (); i = *parm++; /* signs */ move16 (); decode_2i40_11bits (i, index, code); 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 (); decode_3i40_14bits (i, index, code); 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 (); decode_4i40_17bits (i, index, code); pit_sharp = shl (st->sharp, 1); } else if (sub (mode, MR102) == 0) { /* MR102 */ test (); test (); test (); dec_8i40_31bits (parm, code); parm += 7; move16 (); 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); dec_10i40_35bits (parm, code); parm += 10; move16 (); /* 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 (); } /*------------------------------------------------------------* * - 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); 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); 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); 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); 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. * *-------------------------------------------------------*/ 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); /* 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. * *-------------------------------------------------------*/ 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); /* 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); the_end: st->dtxDecoderState.dtxGlobalState = newDTXState; return 0; }