- work on evs decoder

This commit is contained in:
2020-06-15 15:40:54 +03:00
parent 9ec2f734d8
commit 46c355e29a
661 changed files with 173606 additions and 252743 deletions

View File

@@ -0,0 +1,557 @@
/*====================================================================================
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
====================================================================================*/
#include <math.h>
#include <assert.h>
#include "options.h"
#include "cnst.h"
#include "prot.h"
#include "rom_com.h"
/*---------------------------------------------------------------------*
* 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<L_frame; i++ )
{
exc2[i] = (float)own_random( seed );
}
/*------------------------------------------------------------*
* Insert random variation for excitation energy
* (random variation is scaled according to *lp_ener value)
*------------------------------------------------------------*/
for ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
{
ener_lp = ( (own_random( cng_ener_seed ) * (*lp_ener) ) * GAIN_VAR ) + (*lp_ener);
if( ener_lp < 0.0f)
{
ener_lp = 0.01f;
}
enr = dotp( &exc2[i_subfr], &exc2[i_subfr], L_SUBFR ) + 0.01f;
enr = (float)sqrt( ener_lp * L_SUBFR / enr );
for ( i=0; i<L_SUBFR; i++ )
{
exc2[i_subfr+i] *= enr;
}
}
if ( Opt_AMR_WB != 1 )
{
mvr2r( exc2, exc3, L_FRAME16k);
enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f );
if ( core_brate == SID_2k40 )
{
if ( *sid_bw == 0 )
{
for ( i=0; i<NUM_ENV_CNG; i++ )
{
/* get quantized envelope */
env[i] = pow(2.0f,(enr1 - q_env[i]));
}
}
/* initialize CNG envelope */
if( *first_CNG == 0 && *sid_bw == 0 )
{
mvr2r(env, lp_env, NUM_ENV_CNG);
}
if ( *sid_bw == 0 )
{
mvr2r(env, old_env, NUM_ENV_CNG);
}
}
for ( i=0; i<NUM_ENV_CNG; i++ )
{
/* get AR low-passed envelope */
lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i];
}
/* calculate the spectrum of random excitation signal */
mvr2r(exc2, fft_io, L_frame);
if ( L_frame == L_FRAME16k )
{
modify_Fs( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
}
fft_rel(fft_io, L_FFT, LOG2_L_FFT);
ptR = &fft_io[1];
ptI = &fft_io[L_FFT-1];
for ( i=0; i<NUM_ENV_CNG; i++ )
{
env[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
ptR++;
ptI--;
}
for ( i=0; i<NUM_ENV_CNG; i++ )
{
denv[i] = lp_env[i] + 2*(*lp_ener) - env[i];
if ( denv[i] < 0 )
{
denv[i] = 0;
}
}
set_f(itmp, 0.0f, NUM_ENV_CNG);
set_f(fft_io, 0.0f, L_FFT);
ptR = &fft_io[1];
ptI = &fft_io[L_FFT-1];
for (i=0; i<NUM_ENV_CNG; i++)
{
*ptR = own_random( cng_ener_seed1 );
*ptI = own_random( cng_ener_seed1 );
env[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
ptR++;
ptI--;
}
for ( i=0; i<NUM_ENV_CNG; i++ )
{
itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i];
if (itmp[i] < 0.0f)
{
itmp[i] = 0;
}
}
ptR = &fft_io[1];
ptI = &fft_io[L_FFT-1];
for ( i=0; i<NUM_ENV_CNG; i++ )
{
*ptR *= sqrt(itmp[i]/env[i]);
*ptI *= sqrt(itmp[i]/env[i]);
ptR++;
ptI--;
}
ifft_rel(fft_io, L_FFT, LOG2_L_FFT);
if ( L_frame == L_FRAME16k )
{
modify_Fs( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
}
enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame;
/* add time domain randomization */
for ( i_subfr=0; i_subfr<L_frame; i_subfr += L_SUBFR )
{
enr = dotp( &fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR ) + 0.01f;
ener_lp = ( (own_random( cng_ener_seed1 ) * (enr1) ) * 0.000011f ) + (enr1);
ener_lp *= L_SUBFR;
enr = (float)sqrt( ener_lp / enr );
if( last_core_brate != SID_2k40 && last_core_brate != SID_1k75 && last_core_brate != FRAME__NO_DATA && core_brate == SID_2k40 )
{
if ( enr > 1 )
{
enr = 1;
}
}
for ( i=0; i<L_SUBFR; i++ )
{
fft_io[i_subfr+i] *= enr;
}
}
for ( i=0; i<L_frame; i++ )
{
fft_io[i] = 0.75f*fft_io[i] + exc2[i];
}
enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f;
enr = (*lp_ener)/enr;
if ( enr > 1 )
{
enr = 1;
}
ftmp = sqrt(enr);
for (i=0; i<L_frame; i++)
{
fft_io[i] *= ftmp;
}
mvr2r( fft_io, exc2, L_frame );
}
if ( Opt_AMR_WB != 1 )
{
mvr2r( exc3, exc, L_frame );
}
else
{
mvr2r( exc2, exc, L_frame );
}
if( L_frame == L_FRAME )
{
interp_code_5over2( exc2, bwe_exc, L_frame );
}
else
{
interp_code_4over2( exc2, bwe_exc, L_frame );
}
return;
}
/*-------------------------------------------------------*
* cng_params_postupd
*
* Post-update of CNG parameters
*-------------------------------------------------------*/
void cng_params_postupd(
const short ho_circ_ptr, /* i : pointer for CNG averaging buffers */
short *cng_buf_cnt, /* i/o: counter for CNG store buffers */
const float *const cng_exc2_buf, /* i : Excitation buffer */
const long *const cng_brate_buf, /* i : bit rate buffer */
float ho_env_circ[] /* i/o: Envelope buffer */
)
{
short i, j;
const float *exc2;
float fft_io[L_FFT];
float sp[129];
float *ptR,*ptI;
float env[NUM_ENV_CNG];
short CNG_mode;
short ptr;
float att;
long last_active_brate;
ptr = ho_circ_ptr - *cng_buf_cnt + 1;
if( ptr < 0 )
{
ptr += HO_HIST_SIZE;
}
for( j = 0; j < *cng_buf_cnt; j++ )
{
exc2 = &cng_exc2_buf[ptr*L_FFT];
last_active_brate = cng_brate_buf[ptr];
/* calculate the spectrum of residual signal */
/* calculate the spectrum of residual signal */
mvr2r(exc2, fft_io, L_FFT);
fft_rel(fft_io, L_FFT, LOG2_L_FFT);
ptR = &fft_io[1];
ptI = &fft_io[L_FFT-1];
for (i=0; i<NUM_ENV_CNG; i++)
{
sp[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
ptR++;
ptI--;
}
mvr2r(sp,env,NUM_ENV_CNG);
if( last_active_brate > 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<NUM_ENV_CNG; i++ )
{
env[i] *= att;
}
/* update the circular buffer of old residual envelope */
mvr2r( env, &(ho_env_circ[(ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
ptr++;
if(ptr == HO_HIST_SIZE)
{
ptr = 0;
}
}
*cng_buf_cnt = 0;
return;
}
/*-------------------------------------------------------*
* cng_params_upd()
*
* update CNG parameters
*-------------------------------------------------------*/
void cng_params_upd(
const float lsp_new[], /* i : LSP parameters */
const float exc2[], /* i : current enhanced excitation */
const short L_frame, /* i : frame length */
short *ho_circ_ptr, /* i/o: pointer for CNG averaging buffers */
float ho_ener_circ[], /* o : energy buffer for CNG averaging */
short *ho_circ_size, /* i/o: size of DTX hangover history buffer for averaging */
float ho_lsp_circ[], /* o : old LSP buffer for CNG averaging */
const short enc_dec_flag, /* i : Flag indicating encoder or decoder (ENC,DEC) */
float ho_env_circ[], /* i/o: Envelope buffer */
short *cng_buf_cnt, /* i/o: Counter of postponed FFT-processing instances */
float cng_exc2_buf[], /* i/o: Excitation buffer */
long cng_brate_buf[], /* i/o: last_active_brate buffer */
const long last_active_brate /* i : Last active bit rate */
)
{
float enr;
float fft_io[L_FRAME16k];
float sp[129];
float *ptR,*ptI;
float env[NUM_ENV_CNG];
short i;
short CNG_mode;
float att;
/* update the pointer to circular buffer of old LSP vectors */
(*ho_circ_ptr)++;
if( *ho_circ_ptr == HO_HIST_SIZE )
{
*ho_circ_ptr = 0;
}
/* update the circular buffer of old LSP vectors with the new LSP vector */
mvr2r( lsp_new, &(ho_lsp_circ[(*ho_circ_ptr)*M]), M );
/* calculate the residual signal energy */
enr = dotp( exc2, exc2, L_frame ) / L_frame;
/* update the circular buffer of old energies */
ho_ener_circ[*ho_circ_ptr] = enr;
if( enc_dec_flag == ENC)
{
/* Store residual signal for postponed FFT-processing*/
(*cng_buf_cnt)++;
if( *cng_buf_cnt > 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<NUM_ENV_CNG; i++)
{
sp[i] = 2.0f*(*ptR **ptR + *ptI **ptI)/L_FFT;
ptR++;
ptI--;
}
mvr2r(sp,env,NUM_ENV_CNG);
if( last_active_brate > 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<NUM_ENV_CNG; i++ )
{
env[i] *= att;
}
/* update the circular buffer of old residual envelope */
mvr2r( env, &(ho_env_circ[(*ho_circ_ptr)*NUM_ENV_CNG]), NUM_ENV_CNG );
}
(*ho_circ_size)++;
if( *ho_circ_size > HO_HIST_SIZE )
{
*ho_circ_size = HO_HIST_SIZE;
}
return;
}