Files
rtphone/src/libs/libevs/lib_com/low_rate_band_att.cpp
2020-06-15 15:41:54 +03:00

164 lines
5.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 <stdlib.h>
#include <math.h>
#include "options.h"
#include "rom_com.h"
#include "prot.h"
/*--------------------------------------------------------------------------*
* fine_gain_pred()
*
* Fine gain prediction
*--------------------------------------------------------------------------*/
void fine_gain_pred(
const short *sfm_start, /* i : Sub band start indices */
const short *sfm_end, /* i : Sub band end indices */
const short *sfm_size, /* i : Sub band bandwidths */
const short *i_sort, /* i : Energy sorting indices */
const short *K, /* i : Number of pulses per band */
const short *maxpulse, /* i : Maximum pulse per band */
const short *R, /* i : Bits per sub band (Q3) */
const short num_sfm, /* i : Number of sub bands */
float *xq, /* i/o: Quantized vector /quantized vector with finegain adj */
short *y, /* i/o: Quantized vector (int) */
float *fg_pred, /* o : Predicted fine gains */
const short core /* i : Core */
)
{
short i, band;
float gp;
float xx;
float accuracy;
short k, bw;
float att;
for( band = 0; band < num_sfm; band++)
{
k = K[i_sort[band]];
if(k > 0)
{
bw = sfm_size[i_sort[band]];
xx = 0;
for(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++)
{
xx += xq[i] * xq[i];
}
if ( xx > 0)
{
/* Normalize synthesis to RMS=1.0 */
gp = (float) sqrt(bw / xx);
if (core == HQ_CORE && R != NULL && R[i_sort[band]] <= 256)
{
accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]];
att = 1.0f - 0.05f / accuracy;
att = max( 0.840896f, att); /* Limit attenuation to norm quantizer error, 2^-0.25 */
gp *= att;
}
fg_pred[band] = gp;
}
else
{
fg_pred[band] = 0;
}
}
else
{
fg_pred[band] = 0;
for(i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++)
{
y[i] = 0;
xq[i] = 0;
}
}
}
return;
}
/*--------------------------------------------------------------------------*
* get_max_pulses()
*
* Find the maximum pulse height (in unit pulses) in each band
*--------------------------------------------------------------------------*/
void get_max_pulses(
const short *band_start, /* i : Sub band start indices */
const short *band_end, /* i : Sub band end indices */
const short *k_sort, /* i : Indices for sorting by energy */
const short *npulses, /* i : Pulses per sub band */
const short BANDS, /* i : Number of bands */
short *inp_vector, /* i/o: Encoded shape vectors (int)*/
short *maxpulse /* o : Maximum pulse height per band */
)
{
short i, k;
int npul;
int maxp;
for (k = 0; k < BANDS; k++)
{
npul = npulses[k_sort[k]];
maxp = 0;
if (npul > 0)
{
for (i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++)
{
if (abs(inp_vector[i]) > maxp)
{
maxp = abs(inp_vector[i]);
}
}
}
maxpulse[k_sort[k]] = maxp;
}
return;
}
/*--------------------------------------------------------------------------*
* fine_gain_dec()
*
* Fine gain decoder. Decodes fine gain adjustments and applies correction to
* predicted fine gains
*--------------------------------------------------------------------------*/
void fine_gain_dec
(
Decoder_State *st, /* i/o: Decoder state struct */
const short *ord, /* i : Indices for energy order */
const short num_sfm, /* i : Number of bands */
const short *gain_bits, /* i : Gain adjustment bits per sub band */
float *fg_pred /* i/o: Predicted gains / Corrected gains */
)
{
short band;
short gbits;
short idx;
float gain_dbq;
for ( band = 0; band < num_sfm; band++)
{
gbits = gain_bits[ord[band]];
if ( fg_pred[band] != 0 && gbits > 0 )
{
idx = (short)get_next_indice( st, (short)gbits );
gain_dbq = finegain[gbits-1][idx];
/* Update prediced gain with quantized correction */
fg_pred[band] *= (float)pow(10, gain_dbq * 0.05f);
}
}
return;
}