179 lines
4.5 KiB
C++
179 lines
4.5 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 "prot.h"
|
|
#include "options.h"
|
|
|
|
namespace evs {
|
|
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* tcxGetNoiseFillingTilt()
|
|
*
|
|
*
|
|
*-------------------------------------------------------------------*/
|
|
|
|
int tcxGetNoiseFillingTilt(
|
|
float A[],
|
|
int L_frame,
|
|
int mode,
|
|
float *noiseTiltFactor
|
|
)
|
|
{
|
|
int firstLine;
|
|
|
|
if (mode)
|
|
{
|
|
firstLine = L_frame / 6;
|
|
*noiseTiltFactor = 0.5625f;
|
|
}
|
|
else
|
|
{
|
|
firstLine = L_frame / 8;
|
|
*noiseTiltFactor = get_gain( A+1, A, M, NULL );
|
|
*noiseTiltFactor = min(1.0f, (*noiseTiltFactor) + 0.09375f);
|
|
}
|
|
|
|
return firstLine;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* tcxFormantEnhancement()
|
|
*
|
|
*
|
|
*-------------------------------------------------------------------*/
|
|
|
|
void tcxFormantEnhancement(
|
|
float xn_buf[],
|
|
float gainlpc[],
|
|
float spectrum[],
|
|
int L_frame
|
|
)
|
|
{
|
|
int k;
|
|
int i, j, l = 0;
|
|
float fac, step;
|
|
|
|
k = L_frame / FDNS_NPTS;
|
|
|
|
/* Formant enhancement via square root of the LPC gains */
|
|
xn_buf[0] = (float)sqrt(gainlpc[0]);
|
|
xn_buf[1] = (float)sqrt(gainlpc[1]);
|
|
fac = 1.0f / min(xn_buf[0], xn_buf[1]);
|
|
|
|
for (i = 1; i < FDNS_NPTS - 1; i++)
|
|
{
|
|
xn_buf[i+1] = (float)sqrt(gainlpc[i+1]);
|
|
|
|
if ((xn_buf[i-1] <= xn_buf[i]) && (xn_buf[i+1] <= xn_buf[i]))
|
|
{
|
|
step = max(xn_buf[i-1], xn_buf[i+1]);
|
|
step = (1.0f / step - fac) / (float)(i - l);
|
|
xn_buf[l] = 1.0f;
|
|
fac += step;
|
|
for (j = l + 1; j < i; j++)
|
|
{
|
|
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
|
fac += step;
|
|
}
|
|
l = i;
|
|
}
|
|
}
|
|
|
|
/* i = tcx_cfg->fdns_npts - 1; Completing changes to gains */
|
|
step = min(xn_buf[i-1], xn_buf[i]);
|
|
step = (1.0f / step - fac) / (float)(i - l);
|
|
xn_buf[l] = 1.0f;
|
|
fac += step;
|
|
for (j = l + 1; j < i; j++)
|
|
{
|
|
xn_buf[j] = min(1.0f, xn_buf[j] * fac);
|
|
fac += step;
|
|
}
|
|
xn_buf[i] = 1.0f;
|
|
|
|
/* Application of changed gains onto decoded MDCT lines */
|
|
for (i = j = 0; i < L_frame; j++)
|
|
{
|
|
for (l = 0; l < k; i++, l++)
|
|
{
|
|
spectrum[i] *= xn_buf[j];
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* tcxGetNoiseFillingTilt()
|
|
*
|
|
*
|
|
*-------------------------------------------------------------------*/
|
|
|
|
void tcxInvertWindowGrouping(
|
|
TCX_config *tcx_cfg,
|
|
float xn_buf[],
|
|
float spectrum[],
|
|
int L_frame,
|
|
int fUseTns,
|
|
int last_core,
|
|
int index,
|
|
int frame_cnt,
|
|
int bfi
|
|
)
|
|
{
|
|
short i, w, t_integer;
|
|
int L_win, L_spec;
|
|
|
|
if (frame_cnt && !bfi && last_core!=0)
|
|
{
|
|
/* fix sub-window overlap */
|
|
tcx_cfg->tcx_last_overlap_mode = tcx_cfg->tcx_curr_overlap_mode;
|
|
}
|
|
|
|
if (((!bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) ||
|
|
((tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP) && (frame_cnt == 0) && (index == 0))))
|
|
||
|
|
((bfi) &&((tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP) &&
|
|
!(tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP))))
|
|
{
|
|
|
|
/* ungroup sub-windows: deinterleave MDCT bins into separate windows */
|
|
for (t_integer = w = 0; w < 2; w++)
|
|
{
|
|
for (i = w; i < L_frame; i += 2)
|
|
{
|
|
xn_buf[t_integer++] = spectrum[i];
|
|
}
|
|
}
|
|
|
|
mvr2r( xn_buf, spectrum, L_frame );
|
|
|
|
if( tcx_cfg->fIsTNSAllowed && !bfi && fUseTns )
|
|
{
|
|
L_win = L_frame >> 1;
|
|
L_spec = tcx_cfg->tnsConfig[0][0].iFilterBorders[0];
|
|
|
|
/* rearrange LF sub-window lines prior to TNS synthesis filtering */
|
|
if( L_spec < L_frame )
|
|
{
|
|
mvr2r( spectrum+8, spectrum+16, L_spec/2-8 );
|
|
mvr2r( spectrum+L_frame/2, spectrum+8, 8 );
|
|
mvr2r( spectrum+L_frame/2+8, spectrum+L_spec/2+8, L_spec/2-8 );
|
|
}
|
|
else
|
|
{
|
|
mvr2r( spectrum+8, xn_buf, L_win );
|
|
mvr2r( xn_buf, spectrum+16, L_win-8 );
|
|
mvr2r( xn_buf+L_win-8, spectrum+8, 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
} // end of namespace
|