📄 pstcp.c
字号:
if(den0 > den_max) {
den_max = den0;
}
}
else {
if(den1 > den_max) {
den_max = den1;
}
}
ptr_y_up += L_SUBFRP1;
ptr_h += LH2_S;
}
if(den_max < (F)0.1 ) {
*num_gltp = (F)0.;
*den_gltp = (F)1.;
*ltpdel = 0;
*phase = 0;
return;
}
/* Computation of the numerators */
/* and selection of best num*num/den */
/* for non null phases */
/* Initialize with null phase */
num_max = num_int;
den_max = den_int;
numsq_max = num_max * num_max;
phi_max = 0;
ioff = 1;
ptr_den0 = tab_den0;
ptr_den1 = tab_den1;
ptr_y_up = y_up;
/* if den_max = 0 : will be selected and declared unvoiced */
/* if num!=0 & den=0 : will be selected and declared unvoiced */
/* degenerated seldom cases, switch off LT is OK */
/* Loop on phase */
for(phi=1; phi<F_UP_PST; phi++) {
/* computes num for lambda_max+1 - phi/F_UP_PST */
num = (F)0.;
for(n = 0; n<L_SUBFR; n++) {
num += ptr_sig_in[n] * ptr_y_up[n];
}
if(num < (F)0.) num = (F)0.;
numsq = num * num;
/* selection if num/sqrt(den0) max */
den0 = *ptr_den0++;
temp0 = numsq * den_max;
temp1 = numsq_max * den0;
if(temp0 > temp1) {
num_max = num;
numsq_max = numsq;
den_max = den0;
ioff = 0;
phi_max = phi;
}
/* computes num for lambda_max - phi/F_UP_PST */
ptr_y_up++;
num = (F)0.;
for(n = 0; n<L_SUBFR; n++) {
num += ptr_sig_in[n] * ptr_y_up[n];
}
if(num < (F)0.) num = (F)0.;
numsq = num * num;
/* selection if num/sqrt(den1) max */
den1 = *ptr_den1++;
temp0 = numsq * den_max;
temp1 = numsq_max * den1;
if(temp0 > temp1) {
num_max = num;
numsq_max = numsq;
den_max = den1;
ioff = 1;
phi_max = phi;
}
ptr_y_up += L_SUBFR;
}
/***************************************************/
/*** test if normalised crit0[iopt] > THRESCRIT ***/
/***************************************************/
if((num_max == (F)0.) || (den_max <= (F)0.1)) {
*num_gltp = (F)0.;
*den_gltp = (F)1.;
*ltpdel = 0;
*phase = 0;
return;
}
/* comparison num * num */
/* with ener * den x THRESCRIT */
temp1 = den_max * ener * THRESCRIT;
if(numsq_max >= temp1) {
*ltpdel = lambda + 1 - ioff;
*off_yup = ioff;
*phase = phi_max;
*num_gltp = num_max;
*den_gltp = den_max;
}
else {
*num_gltp = (F)0.;
*den_gltp = (F)1.;
*ltpdel = 0;
*phase = 0;
}
return;
}
/*----------------------------------------------------------------------------
* filt_plt - ltp postfilter
*----------------------------------------------------------------------------
*/
static void filt_plt(
FLOAT *s_in, /* input : input signal with past*/
FLOAT *s_ltp, /* input : filtered signal with gain 1 */
FLOAT *s_out, /* output: output signal */
FLOAT gain_plt /* input : filter gain */
)
{
/* Local variables */
int n;
FLOAT gain_plt_1;
gain_plt_1 = (F)1. - gain_plt;
for(n=0; n<L_SUBFR; n++) {
s_out[n] = gain_plt * s_in[n] + gain_plt_1 * s_ltp[n];
}
return;
}
/*----------------------------------------------------------------------------
* compute_ltp_l : compute delayed signal,
num & den of gain for fractional delay
* with long interpolation filter
*----------------------------------------------------------------------------
*/
static void compute_ltp_l(
FLOAT *s_in, /* input signal with past*/
int ltpdel, /* delay factor */
int phase, /* phase factor */
FLOAT *y_up, /* delayed signal */
FLOAT *num, /* numerator of LTP gain */
FLOAT *den /* denominator of LTP gain */
)
{
/* Pointer on table of constants */
FLOAT *ptr_h;
/* Local variables */
int n, i;
FLOAT *ptr2, temp;
/* Filtering with long filter */
ptr_h = tab_hup_l + (phase-1) * LH2_L;
ptr2 = s_in - ltpdel + LH_UP_L;
/* Compute y_up */
for(n = 0; n<L_SUBFR; n++) {
temp = (F)0.;
for(i=0; i<LH2_L; i++) {
temp += ptr_h[i] * *ptr2--;
}
y_up[n] = temp;
ptr2 += LH2_L_P1;
}
/* Compute num */
*num = (F)0.;
for(n = 0; n<L_SUBFR; n++) {
*num += y_up[n]* s_in[n];
}
if(*num < (F)0.0) *num = (F)0.0;
*den = (F)0.;
/* Compute den */
for(n = 0; n<L_SUBFR; n++) {
*den += y_up[n]* y_up[n];
}
return;
}
/*----------------------------------------------------------------------------
* select_ltp : selects best of (gain1, gain2)
* with gain1 = num1 * 2** sh_num1 / den1 * 2** sh_den1
* and gain2 = num2 * 2** sh_num2 / den2 * 2** sh_den2
*----------------------------------------------------------------------------
*/
static int select_ltp( /* output : 1 = 1st gain, 2 = 2nd gain */
FLOAT num1, /* input : numerator of gain1 */
FLOAT den1, /* input : denominator of gain1 */
FLOAT num2, /* input : numerator of gain2 */
FLOAT den2 /* input : denominator of gain2 */
)
{
if(den2 == (F)0.) {
return(1);
}
if(num2 * num2 * den1> num1 * num1 * den2) {
return(2);
}
else {
return(1);
}
}
/*----------------------------------------------------------------------------
* calc_st_filt - computes impulse response of A(gamma2) / A(gamma1)
* controls gain : computation of energy impulse response as
* SUMn (abs (h[n])) and computes parcor0
*----------------------------------------------------------------------------
*/
static void calc_st_filte(
FLOAT *apond2, /* input : coefficients of numerator */
FLOAT *apond1, /* input : coefficients of denominator */
FLOAT *parcor0, /* output: 1st parcor calcul. on composed filter */
FLOAT *sig_ltp_ptr, /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */
int long_h_st, /* input : impulse response length */
int m_pst /* input : LPC order */
)
{
FLOAT h[LONG_H_ST_E];
FLOAT g0, temp;
int i;
/* compute i.r. of composed filter apond2 / apond1 */
syn_filte(m_pst, apond1, apond2, h, long_h_st, mem_zero, 0);
/* compute 1st parcor */
calc_rc0_he(h, parcor0, long_h_st);
/* compute g0 */
g0 = (F)0.;
for(i=0; i<long_h_st; i++) {
g0 += (FLOAT)fabs(h[i]);
}
/* Scale signal input of 1/A(gamma1) */
if(g0 > (F)1.) {
temp = (F)1./g0;
for(i=0; i<L_SUBFR; i++) {
sig_ltp_ptr[i] = sig_ltp_ptr[i] * temp;
}
}
return;
}
/*----------------------------------------------------------------------------
* calc_rc0_h - computes 1st parcor from composed filter impulse response
*----------------------------------------------------------------------------
*/
static void calc_rc0_he(
FLOAT *h, /* input : impulse response of composed filter */
FLOAT *rc0, /* output: 1st parcor */
int long_h_st /*input : impulse response length */
)
{
FLOAT acf0, acf1;
FLOAT temp, temp2;
FLOAT *ptrs;
int i;
/* computation of the autocorrelation function acf */
temp = (F)0.;
for(i=0; i<long_h_st; i++) {
temp += h[i] * h[i];
}
acf0 = temp;
temp = (F)0.;
ptrs = h;
for(i=0;i<long_h_st-1;i++){
temp2 = *ptrs++;
temp += temp2 * (*ptrs);
}
acf1 = temp;
/* Initialisation of the calculation */
if( acf0 == (F)0.) {
*rc0 = (F)0.;
return;
}
/* Compute 1st parcor */
/**********************/
if(acf0 < (FLOAT)fabs(acf1) ) {
*rc0 = (F)0.0;
return;
}
*rc0 = - acf1 / acf0;
return;
}
/*----------------------------------------------------------------------------
* filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
* computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
*----------------------------------------------------------------------------
*/
static void filt_mu(
FLOAT *sig_in, /* input : input signal (beginning at sample -1) */
FLOAT *sig_out, /* output: output signal */
FLOAT parcor0 /* input : parcor0 (mu = parcor0 * gamma3) */
)
{
int n;
FLOAT mu, ga, temp;
FLOAT *ptrs;
if(parcor0 > (F)0.) {
mu = parcor0 * GAMMA3_PLUS;
}
else {
mu = parcor0 * GAMMA3_MINUS;
}
ga = (F)1. / ((F)1. - (FLOAT)fabs(mu));
ptrs = sig_in; /* points on sig_in(-1) */
for(n=0; n<L_SUBFR; n++) {
temp = mu * (*ptrs++);
temp += (*ptrs);
sig_out[n] = ga * temp;
}
return;
}
/*----------------------------------------------------------------------------
* scale_st - control of the subframe gain
* gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out
*----------------------------------------------------------------------------
*/
void scale_st(
FLOAT *sig_in, /* input : postfilter input signal */
FLOAT *sig_out, /* in/out: postfilter output signal */
FLOAT *gain_prec /* in/out: last value of gain for subframe */
)
{
int i;
FLOAT gain_in, gain_out;
FLOAT g0, gain;
/* compute input gain */
gain_in = (F)0.;
for(i=0; i<L_SUBFR; i++) {
gain_in += (FLOAT)fabs(sig_in[i]);
}
if(gain_in == (F)0.) {
g0 = (F)0.;
}
else {
/* Compute output gain */
gain_out = (F)0.;
for(i=0; i<L_SUBFR; i++) {
gain_out += (FLOAT)fabs(sig_out[i]);
}
if(gain_out == (F)0.) {
*gain_prec = (F)0.;
return;
}
g0 = gain_in/ gain_out;
g0 *= AGC_FAC1;
}
/* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
/* sig_out(n) = gain(n) sig_out(n) */
gain = *gain_prec;
for(i=0; i<L_SUBFR; i++) {
gain *= AGC_FAC;
gain += g0;
sig_out[i] *= gain;
}
*gain_prec = gain;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -