Files
rtphone/src/libs/libevs/lib_com/gs_inact_switching_fx.cpp

154 lines
6.3 KiB
C++
Executable File

/*====================================================================================
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
====================================================================================*/
#include "options.h" /* Compilation switches */
#include "cnst_fx.h" /* Common constants */
#include "rom_com_fx.h" /* Static table prototypes */
#include "prot_fx.h" /* Function prototypes */
#include "stl.h"
/*-------------------------------------------------------------------*
* Local constants
*-------------------------------------------------------------------*/
#define ALPHA0_FX 13107
#define BETA0_FX (32768-ALPHA0_FX)
/*========================================================================*/
/* FUNCTION : Inac_swtch_ematch_fx() */
/*------------------------------------------------------------------------*/
/* PURPOSE : Apply energy matching when swithcing to INACTIVE frame coded */
/* by the GSC technology */
/*------------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* _ (Word16) coder_type : Coding mode */
/* _ (Word16) L_frame : Frame lenght */
/* _ (Word32) core_brate : core bitrate */
/*------------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ (Word16[]) exc2 : CELP/GSC excitation buffer Q_exc */
/* _ (Word16[]) lt_ener_per_band : Long term energy per band Q12 */
/* _ (Word16*) Q_exc : input and output format of exc2 */
/*------------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ None */
/*========================================================================*/
void Inac_swtch_ematch_fx(
Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/
Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */
Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */
const Word16 coder_type, /* i : Coding mode */
const Word16 L_frame, /* i : Frame lenght */
const Word32 core_brate, /* i : Core bit rate */
const Word16 Q_exc /* i : input and output format of exc2 */
,const Word16 bfi /* i : frame lost indicator */
,const Word16 last_core, /* i : Last core used */
const Word16 last_codec_mode /* i : Last codec mode */
)
{
Word16 Ener_per_bd[MBANDS_GN];
Word16 ftmp;
Word16 *pt_exc;
Word16 j, i;
Word16 exp,frac;
Word32 L_tmp;
/*--------------------------------------------------------------------------
* average energy per band
*--------------------------------------------------------------------------*/
test();
test();
test();
test();
test();
test();
IF(sub(coder_type,AUDIO) == 0 && bfi == 0)
{
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1);
/* reset long-term energy per band */
FOR(i = 0; i < MBANDS_GN; i++)
{
lt_ener_per_band[i] = Ener_per_bd[i];
move16();
}
}
ELSE IF( sub(coder_type,VOICED) == 0 || sub(coder_type,GENERIC) == 0 || sub(coder_type,TRANSITION) == 0 || sub(last_core,ACELP_CORE) != 0 || sub(last_codec_mode,MODE1) != 0 )
{
/* Find spectrum and energy per band for GC and VC frames */
edct_16fx( exc2, dct_exc_tmp, L_frame, 5 );
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1);
/* reset long-term energy per band */
FOR(i = 0; i < MBANDS_GN; i++)
{
lt_ener_per_band[i] = Ener_per_bd[i];
move16();
}
}
ELSE IF( sub(coder_type,INACTIVE) == 0 && L_sub(core_brate,ACELP_24k40) <= 0)
{
/* Find spectrum and energy per band for inactive frames */
edct_16fx( exc2, dct_exc_tmp, L_frame, 5 );
Ener_per_band_comp_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1 );
/* More agressive smoothing in the first 50 frames */
pt_exc = dct_exc_tmp;
move16();
FOR(i = 0; i < MBANDS_GN; i++)
{
/* Compute smoothing gain to apply with gain limitation */
L_tmp = L_mult(ALPHA0_FX,lt_ener_per_band[i]); /*Q(15+12+1)=Q(28) */
L_tmp = L_mac(L_tmp,BETA0_FX,Ener_per_bd[i]); /*Q28 */
lt_ener_per_band[i] = round_fx(L_tmp); /*Q12 */
ftmp = sub(lt_ener_per_band[i],Ener_per_bd[i]); /*Q12 */
/* ftmp = (float)pow(10, ftmp);= pow(2,3.321928*ftmp);*/
L_tmp = L_mult(27213,ftmp); /*Q(13+12+1)=Q26 ; 27213=3.321928 in Q13 */
L_tmp = L_shr(L_tmp, 10); /* From Q26 to Q16 */
frac = L_Extract_lc(L_tmp, &exp); /* Extract exponent of ftmp */
ftmp = extract_l(Pow2(14, frac));/* Put 14 as exponent so that */
/* output of Pow2() will be: */
/* 16384 < Pow2() <= 32767 */
exp = sub(exp,14);
IF( sub(i,2) < 0 )
{
FOR (j = 0; j < 8; j ++)
{
L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */
L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/
*pt_exc = round_fx(L_tmp);
pt_exc++;
}
}
ELSE
{
FOR (j = 0; j < 16; j ++)
{
L_tmp = L_mult(*pt_exc,ftmp); /* Q_exc*Q0 -> Q(Q_exc+1) */
L_tmp = L_shl(L_tmp, add(exp,15)); /* Q(Q_exc+1) -> Q(16+Q_exc)*/
*pt_exc = round_fx(L_tmp); /*Q_exc*/
pt_exc++;
}
}
}
/* Going back to time */
edct_16fx( dct_exc_tmp, exc2, L_frame, 5 );
}
return;
}