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

100 lines
3.2 KiB
C++

/*====================================================================================
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 "options.h"
#include "cnst.h"
#include "rom_com.h"
#include "prot.h"
namespace evs {
/*-------------------------------------------------------------------*
* Local constants
*-------------------------------------------------------------------*/
#define ATT_LENGHT 64
#define ATT_SEG_LEN (L_FRAME/ATT_LENGHT)
#define INV_ATT_SEG_LEN (1.0f/ATT_SEG_LEN)
#define INV_L_FRAME (1.0f/L_FRAME)
/*-------------------------------------------------------------------*
* pre_echo_att()
*
* Attenuation of the pre-echo when encoder specifies an attack
*-------------------------------------------------------------------*/
void pre_echo_att(
float *Last_frame_ener, /* i/o: Energy of the last frame */
float *exc, /* i/o: Excitation of the current frame */
const short attack_flag, /* i : flag signalling attack encoded by AC mode (GSC) */
const short last_coder_type /* i : Last coder type */
)
{
float etmp;
float etmp1;
float finc[ATT_LENGHT], ratio;
short attack_pos, i;
if ( attack_flag == 1 && last_coder_type == AUDIO)
{
/*-------------------------------------------------------------------------*
* Find where the onset (attack) occurs by computing the energy per section
* The inverse weighting aims to favor the first maxima in case of
* gradual onset
*-------------------------------------------------------------------------*/
for(i = 0; i < ATT_LENGHT; i++)
{
finc[i] = sum2_f( exc + i*ATT_SEG_LEN, ATT_SEG_LEN )*((float)(ATT_LENGHT-i)/(ATT_LENGHT));
}
etmp = -1;
attack_pos = maximum(finc, ATT_LENGHT, &etmp);
/* Scaled the maximum energy and allowed 6 dB increase*/
etmp *= INV_ATT_SEG_LEN;
etmp1 = etmp;
*Last_frame_ener *= 4.0f;
/* If the maximum normalized energy > last frame energy + 6dB */
if( etmp > *Last_frame_ener && attack_pos > 0 )
{
/* Find the average energy before the attack */
etmp = sum_f( finc, attack_pos ) + 0.01f;
etmp /= (attack_pos*ATT_SEG_LEN);
/* Find the correction factor and apply it before the attack */
ratio = (float)sqrt(*Last_frame_ener/etmp);
/* Pre-echo atttenuation should never increase the energy */
ratio = min(ratio, 1.0f);
for(i = 0; i < attack_pos*ATT_SEG_LEN; i++)
{
exc[i] *= ratio;
}
}
*Last_frame_ener = etmp1;
}
else
{
/*-------------------------------------------------------*
* In normal cases, just compute the energy of the frame
*-------------------------------------------------------*/
etmp = sum2_f( exc, L_FRAME ) + 0.01f;
etmp *= INV_L_FRAME;
*Last_frame_ener = etmp;
}
return;
}
} // end of namespace