/*==================================================================================== EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0 ====================================================================================*/ #include #include #include "options.h" #include "cnst.h" #include "prot.h" #include "rom_com.h" namespace evs { /*---------------------------------------------------------------------* * Local constants *---------------------------------------------------------------------*/ #define A2 0.2f #define GAIN_VAR 0.000011f /*-------------------------------------------------------* * CNG_exc() * * Comfort noise generation routine *-------------------------------------------------------*/ void CNG_exc( const long core_brate, /* i : core bitrate */ const short L_frame, /* i : length of the frame */ float *Enew, /* i/o: decoded SID energy */ short *seed, /* i/o: random generator seed */ float exc[], /* o : current non-enhanced excitation */ float exc2[], /* o : current enhanced excitation */ float *lp_ener, /* i/o: LP filtered E */ const long last_core_brate, /* i : previous frame core bitrate */ short *first_CNG, /* i/o: first CNG frame flag for energy init. */ short *cng_ener_seed, /* i/o: random generator seed for CNG energy */ float bwe_exc[], /* o : excitation for SWB TBE */ const short allow_cn_step, /* i : allow CN step */ short *last_allow_cn_step, /* i/o: last allow step */ const short num_ho, /* i : number of selected hangover frames */ float q_env[], float *lp_env, float *old_env, float *exc_mem, float *exc_mem1, short *sid_bw, short *cng_ener_seed1, float exc3[], short Opt_AMR_WB ) { float enr; short i; float ener_lp; short i_subfr; short pit_max; float ftmp; float *ptR,*ptI; float fft_io[L_FRAME16k]; float itmp[129]; float env[NUM_ENV_CNG]; float enr1; float denv[NUM_ENV_CNG]; /*------------------------------------------------------------------* * Initializations *------------------------------------------------------------------*/ if( L_frame == L_FRAME ) { pit_max = PIT_MAX; } else /* L_frame == L_FRAME16k */ { pit_max = PIT16k_MAX; } /*---------------------------------------------------------------------* * Initialization of CNG energy for the first CNG frame *---------------------------------------------------------------------*/ if( *first_CNG == 0 ) { if( core_brate == FRAME__NO_DATA ) { /* needed only in decoder when the very first SID frame was erased and this frame is FRAME__NO_DATA frame */ *Enew = dotp( exc-pit_max, exc-pit_max, pit_max ) / pit_max; } *lp_ener = *Enew; } /*---------------------------------------------------------------------* * Update CNG energy *---------------------------------------------------------------------*/ if( last_core_brate != SID_1k75 && last_core_brate != FRAME__NO_DATA && last_core_brate != SID_2k40 ) { /* Partially reset CNG energy after active speech period */ if ( allow_cn_step == 0 && *last_allow_cn_step == 0 ) { if( num_ho < 3 || *Enew < 1.5f * *lp_ener ) { *lp_ener = 0.8f * *lp_ener + 0.2f * *Enew; } else { *lp_ener = 0.95f * *lp_ener + 0.05f * *Enew; } } else { *lp_ener = *Enew; *last_allow_cn_step = 0; } } else { /* normal CNG update */ if ( *last_allow_cn_step == 0 ) { *lp_ener = (float)(A2 **Enew + (1-A2) **lp_ener); } else { if ( core_brate == SID_1k75 || core_brate == SID_2k40 ) { *last_allow_cn_step = 0; } *lp_ener = *Enew; } } if ( allow_cn_step == 1 ) { *last_allow_cn_step = 1; } /*---------------------------------------------------------------------* * Generate white noise vector *---------------------------------------------------------------------*/ for ( i=0; i 1 ) { enr = 1; } } for ( i=0; i 1 ) { enr = 1; } ftmp = sqrt(enr); for (i=0; i ACELP_13k20 ) { CNG_mode = 4; } else if( last_active_brate > ACELP_9k60 ) { CNG_mode = 3; } else if( last_active_brate > ACELP_8k00 ) { CNG_mode = 2; } else if( last_active_brate > ACELP_7k20 ) { CNG_mode = 1; } else { CNG_mode = 0; } att = 1/pow(2,ENR_ATT[CNG_mode]); for ( i=0; i HO_HIST_SIZE) { *cng_buf_cnt = HO_HIST_SIZE; } mvr2r( exc2, &(cng_exc2_buf[(*ho_circ_ptr)*L_FFT]), L_FFT ); cng_brate_buf[*ho_circ_ptr] = last_active_brate; } else { /* calculate the spectrum of residual signal */ mvr2r(exc2, fft_io, L_frame); fft_rel(fft_io, L_FFT, LOG2_L_FFT); ptR = &fft_io[1]; ptI = &fft_io[L_FFT-1]; for (i=0; i ACELP_13k20 ) { CNG_mode = 4; } else if( last_active_brate > ACELP_9k60 ) { CNG_mode = 3; } else if( last_active_brate > ACELP_8k00 ) { CNG_mode = 2; } else if( last_active_brate > ACELP_7k20 ) { CNG_mode = 1; } else { CNG_mode = 0; } att = 1/pow(2,ENR_ATT[CNG_mode]); for ( i=0; i HO_HIST_SIZE ) { *ho_circ_size = HO_HIST_SIZE; } return; } } // end of namespace