rtphone/src/libs/libevs/lib_com/lsf_msvq_ma.cpp

153 lines
3.7 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 <stdlib.h>
#include <assert.h>
#include "options.h"
#include "cnst.h"
#include "prot.h"
#include "rom_com.h"
#include "stl.h"
#include "basop_proto_func.h"
namespace evs {
/*---------------------------------------------------------------------*
* midlsf_dec()
*
*
*---------------------------------------------------------------------*/
void midlsf_dec(
float qlsf0[],
float qlsf1[],
short idx,
float qlsf[],
int N,
int coder_type,
short *mid_lsf_int,
short prev_bfi,
short safety_net
)
{
const float *ratio=NULL;
int j;
short bad_spacing = 0;
/* Select codebook */
if ( coder_type == UNVOICED )
{
ratio = tbl_mid_unv_wb_5b;
}
else
{
ratio = tbl_mid_gen_wb_5b;
}
for (j=0; j<N; j++)
{
qlsf[j] = (1.0f - ratio[idx*N+j]) * qlsf0[j] + ratio[idx*N+j] * qlsf1[j];
}
if(mid_lsf_int != NULL) /*at the decoder*/
{
/* check for incorrect LSF ordering */
if ( *mid_lsf_int == 1 )
{
for (j=1; j<N; j++)
{
if ( qlsf[j] < qlsf[j-1] )
{
bad_spacing = 1;
break;
}
}
}
/* Redo mid-LSF interpolation with 0.4 in case of LSF instability */
if ( prev_bfi || ( *mid_lsf_int == 1 && bad_spacing ) )
{
for (j=0; j<N; j++)
{
/* redo mid-LSF interpolation with 0.4 */
qlsf[j] = 0.4f * qlsf0[j] + 0.6f * qlsf1[j];
/* ensure correct ordering of LSF indices */
if ( j > 0 && j < N && qlsf[j] < qlsf[j-1] + LSF_GAP_MID )
{
qlsf[j] = qlsf[j-1] + LSF_GAP_MID;
}
}
}
else
{
/* otherwise, use regular LSF spacing and ordering as in the encoder */
for (j=0; j<N; j++)
{
if ( j > 0 && j < N && qlsf[j] < qlsf[j-1] + LSF_GAP_MID )
{
qlsf[j] = qlsf[j-1] + LSF_GAP_MID;
}
}
}
if ( prev_bfi )
{
/* continue redoing mid-LSF interpolation with 0.4 in order not to propagate the error */
*mid_lsf_int = 1;
}
if ( safety_net )
{
/* safety-net encountered -> stop redoing mid-LSF interpolation with 0.4 */
*mid_lsf_int = 0;
}
}
else
{
/* use regular LSF spacing */
for (j=0; j<N; j++)
{
if ( j > 0 && j < N && qlsf[j] < qlsf[j-1] + LSF_GAP_MID )
{
qlsf[j] = qlsf[j-1] + LSF_GAP_MID;
}
}
}
return;
}
/*---------------------------------------------------------------------*
* lsf_ind_is_active()
*
*
*---------------------------------------------------------------------*/
int lsf_ind_is_active(
const Word16 lsf_q_ind[],
const float means[],
int narrowband,
int cdk
)
{
Word16 lsf[2], min_distance;
lsf[0] = add(lsf_q_ind[0], LSFM(means[0]));
move16();
lsf[1] = add(lsf_q_ind[1], LSFM(means[1]));
move16();
min_distance = lsf[0];
min_distance = s_min(min_distance, sub(lsf[1], lsf[0]));
assert(narrowband == 0 || narrowband == 1);
assert(cdk == 0 || cdk == 1);
return sub(min_distance, min_distance_thr[narrowband][cdk]) < 0;
}
} // end of namespace