📄 tns.c
字号:
#include "all.h"
#define sfb_offset(x) ( ((x) > 0) ? sfb_top[(x)-1] : 0 )
/* Decoder transmitted coefficients for one TNS filter */
void
tns_decode_coef( int order, int coef_res, short *coef, Float *a )
{
int i, m;
Float iqfac, iqfac_m;
Float tmp[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1];
/* Inverse quantization */
iqfac = ((1 << (coef_res-1)) - 0.5) / (C_PI/2.0);
iqfac_m = ((1 << (coef_res-1)) + 0.5) / (C_PI/2.0);
for (i=0; i<order; i++) {
tmp[i+1] = sin( coef[i] / ((coef[i] >= 0) ? iqfac : iqfac_m) );
}
/* Conversion to LPC coefficients
* Markel and Gray, pg. 95
*/
a[0] = 1;
for (m=1; m<=order; m++) {
b[0] = a[0];
for (i=1; i<m; i++) {
b[i] = a[i] + tmp[m] * a[m-i];
}
b[m] = tmp[m];
for (i=0; i<=m; i++) {
a[i] = b[i];
}
}
}
/* apply the TNS filter */
void
tns_ar_filter( Float *spec, int size, int inc, Float *lpc, int order )
{
/*
* - Simple all-pole filter of order "order" defined by
* y(n) = x(n) - a(2)*y(n-1) - ... - a(order+1)*y(n-order)
*
* - The state variables of the filter are initialized to zero every time
*
* - The output data is written over the input data ("in-place operation")
*
* - An input vector of "size" samples is processed and the index increment
* to the next data sample is given by "inc"
*/
int i, j;
Float y, state[TNS_MAX_ORDER];
for (i=0; i<order; i++)
state[i] = 0;
if (inc == -1)
spec += size-1;
for (i=0; i<size; i++) {
y = *spec;
for (j=0; j<order; j++)
y -= lpc[j+1] * state[j];
for (j=order-1; j>0; j--)
state[j] = state[j-1];
state[0] = y;
*spec = y;
spec += inc;
}
}
/* TNS decoding for one channel and frame */
void
tns_decode_subblock(Float *spec, int nbands, short *sfb_top, int islong,
TNSinfo *tns_info)
{
int f, m, start, stop, size, inc;
int n_filt, coef_res, order, direction;
short *coef;
Float lpc[TNS_MAX_ORDER+1];
TNSfilt *filt;
n_filt = tns_info->n_filt;
for (f=0; f<n_filt; f++) {
coef_res = tns_info->coef_res;
filt = &tns_info->filt[f];
order = filt->order;
direction = filt->direction;
coef = filt->coef;
start = filt->start_band;
stop = filt->stop_band;
m = tns_max_order(islong);
if (order > m) {
// CommonWarning("Error in tns max order");
order = m;
}
if (!order) continue;
tns_decode_coef( order, coef_res, coef, lpc );
start = min(start, tns_max_bands(islong));
start = min(start, nbands);
start = sfb_offset( start );
stop = min(stop, tns_max_bands(islong));
stop = min(stop, nbands);
stop = sfb_offset( stop );
if ((size = stop - start) <= 0) continue;
if (direction) {
inc = -1;
} else {
inc = 1;
}
tns_ar_filter( &spec[start], size, inc, lpc, order );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -