/*==================================================================================== EVS Codec 3GPP TS26.443 Jun 30, 2015. Version CR 26.443-0006 ====================================================================================*/ #include "options.h" #include "cnst.h" #include "prot.h" /*-------------------------------------------------------------------* * Local constants *-------------------------------------------------------------------*/ #define GAIN_PIT_MAX 1.2f #define ACELP_GAINS_CONST 0.8f /* adaptive codebook gain constraint */ /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ static float adpt_enr( const short codec_mode, const float *exc, const float *h1, float *y1, const short L_subfr, float *gain, float *g_corr, const short clip_gain, const float *xn, float *xn2, short use_prev_sf_pit_gain ); /*-------------------------------------------------------------------* * lp_filt_exc_enc() * * Low-pass filtering of the adaptive excitation * Innovation target construction * Gain quantization limitation *-------------------------------------------------------------------*/ short lp_filt_exc_enc( const short codec_mode, /* i : codec mode */ const long core_brate, /* i : core bitrate */ const short Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ const short coder_type, /* i : coding type */ const short i_subfr, /* i : subframe index */ float *exc, /* i/o: pointer to excitation signal frame */ const float *h1, /* i : weighted filter input response */ const float *xn, /* i : target vector */ float *y1, /* o : zero-memory filtered adaptive excitation */ float *xn2, /* o : target vector for innovation search */ const short L_subfr, /* i : length of vectors for gain quantization */ const short L_frame, /* i : frame size */ float *g_corr, /* o : ACELP correlation values */ const short clip_gain, /* i : adaptive gain clipping flag */ float *gain_pit, /* o : adaptive excitation gain */ short *lp_flag /* i/o : mode selection */ ) { float ener, ener_tmp, gain1, gain2, g_corr2[2], exc_tmp[L_FRAME16k], xn2_tmp[L_FRAME16k]; float y1_tmp[L_FRAME16k]; short select, i; short use_prev_sf_pit_gain; gain1 = 0.0f; gain2 = 0.0f; ener = 0.0f; ener_tmp = 0.0f; use_prev_sf_pit_gain = 0; /*-----------------------------------------------------------------* * Select LP filtering flag *-----------------------------------------------------------------*/ if( codec_mode == MODE1 ) { if ( ( Opt_AMR_WB || coder_type == GENERIC || coder_type == TRANSITION ) && core_brate < ACELP_11k60 ) { *lp_flag = LOW_PASS; } else if ( core_brate >= ACELP_11k60 && coder_type != AUDIO ) { *lp_flag = NORMAL_OPERATION; } else { *lp_flag = FULL_BAND; } } /*----------------------------------------------------------------* * Find energy of the fixed cb. target with respect to adaptive * exc. filtering * Find flag about splitting the gain quantizer in half * - find the target energy if adaptive exc. is not filtered * - filter the adaptive excitation and find the target energy * if the exc. is filtered. *----------------------------------------------------------------*/ if( codec_mode == MODE2 && coder_type == 100 ) { use_prev_sf_pit_gain = 1; } if( *lp_flag == FULL_BAND || *lp_flag == NORMAL_OPERATION ) { if( use_prev_sf_pit_gain == 1 ) { ener = adpt_enr( codec_mode, &exc[i_subfr], h1, y1, L_subfr, gain_pit, g_corr, clip_gain, xn, xn2, use_prev_sf_pit_gain ); } else { ener = adpt_enr( codec_mode, &exc[i_subfr], h1, y1, L_subfr, &gain1, g_corr, clip_gain, xn, xn2, use_prev_sf_pit_gain ); } } /*----------------------------------------------------------------* * Find energy of the fixed cb. target with respect to adaptive * exc. filtering * filter the adaptive excitation and find the target energy * if the exc. is filtered. *----------------------------------------------------------------*/ if( *lp_flag == LOW_PASS || *lp_flag == NORMAL_OPERATION ) { if( codec_mode == MODE2 && L_frame == L_FRAME16k ) { for (i=0; i 0.95f ) { *gain = 0.95f; } if( clip_gain == 2 && *gain > 0.65f ) { *gain = 0.65f; } } /* find energy of new target xn2[] */ updt_tar( xn, xn2, y1, *gain, L_subfr ); ener = dotp( xn2, xn2, L_subfr ); return ener; } /*-------------------------------------------------------------------* * corr_xy1() * * Find the correlations between the target xn[] and the filtered adaptive * codebook excitation y1[]. ( and -2 ) *-------------------------------------------------------------------*/ float corr_xy1( /* o : pitch gain (0..GAIN_PIT_MAX) */ const float xn[], /* i : target signal */ const float y1[], /* i : filtered adaptive codebook excitation */ float g_corr[], /* o : correlations and -2 */ const short L_subfr, /* i : vector length */ const short norm_flag /* i : flag for constraining pitch contribution */ ) { float temp1, temp2, gain,gain_p_snr; /*-----------------------------------------------------------------* * Find the ACELP correlations and the pitch gain * (for current subframe) *-----------------------------------------------------------------*/ /* Compute scalar product */ temp1 = dotp(xn, y1, L_subfr); /* Compute scalar product */ temp2 = dotp(y1, y1, L_subfr) + 0.01f; g_corr[0] = temp2; g_corr[1] = -2.0f*temp1 + 0.01f; /* find pitch gain and bound it by [0,GAIN_PIT_MAX] */ if( norm_flag ) { gain = (temp1 + 0.01f)/temp2; } else { gain = temp1/temp2; } if( gain < 0.0f ) { gain = 0.0f; } if( gain > GAIN_PIT_MAX ) { gain = GAIN_PIT_MAX; } /*Limit the energy of pitch contribution*/ if( norm_flag ) { /* Compute scalar product */ temp1 = dotp(xn, xn, L_subfr); gain_p_snr = ACELP_GAINS_CONST*sqrt(temp1/temp2); if( gain>gain_p_snr ) { gain = gain_p_snr; } } return gain; }