www.pudn.com > source.rar > POSTFILA.C
/* ITU-T G.729 Software Package Release 2 (November 2006) */
/*
ITU-T G.729 Annex C - Reference C code for floating point
implementation of G.729 Annex A
Version 1.01 of 15.September.98
*/
/*
----------------------------------------------------------------------
COPYRIGHT NOTICE
----------------------------------------------------------------------
ITU-T G.729 Annex C ANSI C source code
Copyright (C) 1998, AT&T, France Telecom, NTT, University of
Sherbrooke. All rights reserved.
----------------------------------------------------------------------
*/
/*------------------------------------------------------------------------*
* POSTFILTER.C *
*------------------------------------------------------------------------*
* Performs adaptive postfiltering on the synthesis speech *
* This file contains all functions related to the post filter. *
*------------------------------------------------------------------------*/
#include
#include "typedef.h"
#include "ld8a.h"
/* prototype of local functions */
static void pit_pst_filt(
FLOAT *signal, /* input : input signal */
int t0_min, /* input : minimum value in the searched range */
int t0_max, /* input : maximum value in the searched range */
int L_subfr, /* input : size of filtering */
FLOAT *signal_pst /* output: harmonically postfiltered signal */
);
static void agc(
FLOAT *sig_in, /* input : postfilter input signal */
FLOAT *sig_out, /* in/out: postfilter output signal */
int l_trm /* input : subframe size */
);
static void preemphasis(
FLOAT *signal, /* in/out: input signal overwritten by the output */
FLOAT g, /* input : preemphasis coefficient */
int L /* input : size of filtering */
);
/*---------------------------------------------------------------*
* Postfilter constant parameters (defined in "ld8a.h") *
*---------------------------------------------------------------*
* L_FRAME : Frame size. *
* L_SUBFR : Sub-frame size. *
* M : LPC order. *
* MP1 : LPC order+1 *
* PIT_MAX : Maximum pitch lag. *
* GAMMA2_PST : Formant postfiltering factor (numerator) *
* GAMMA1_PST : Formant postfiltering factor (denominator) *
* GAMMAP : Harmonic postfiltering factor *
* MU : Factor for tilt compensation filter *
* AGC_FAC : Factor for automatic gain control *
*---------------------------------------------------------------*/
/*------------------------------------------------------------*
* static vectors *
*------------------------------------------------------------*/
/* inverse filtered synthesis (with A(z/GAMMA2_PST)) */
static FLOAT res2_buf[PIT_MAX+L_SUBFR];
static FLOAT *res2;
/* memory of filter 1/A(z/GAMMA1_PST) */
static FLOAT mem_syn_pst[M];
/*---------------------------------------------------------------*
* Procedure init_post_filter: *
* ~~~~~~~~~~~~~ *
* Initializes the postfilter parameters: *
*---------------------------------------------------------------*/
void init_post_filter(void)
{
res2 = res2_buf + PIT_MAX;
set_zero(mem_syn_pst, M);
set_zero(res2_buf, PIT_MAX+L_SUBFR);
return;
}
/*------------------------------------------------------------------------*
* Procedure post_filter: *
* ~~~~~~~~~~~ *
*------------------------------------------------------------------------*
* The postfiltering process is described as follows: *
* *
* - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[] *
* - use res2[] to compute pitch parameters *
* - perform pitch postfiltering *
* - tilt compensation filtering; 1 - MU*k*z^-1 *
* - synthesis filtering through 1/A(z/GAMMA1_PST) *
* - adaptive gain control *
*------------------------------------------------------------------------*/
void post_filter(
FLOAT *syn, /* in/out: synthesis speech (postfiltered is output) */
FLOAT *az_4, /* input : interpolated LPC parameters in all subframes */
int *T /* input : decoded pitch lags in all subframes */
)
{
/*-------------------------------------------------------------------*
* Declaration of parameters *
*-------------------------------------------------------------------*/
FLOAT res2_pst[L_SUBFR]; /* res2[] after pitch postfiltering */
FLOAT syn_pst[L_FRAME]; /* post filtered synthesis speech */
FLOAT ap3[MP1], ap4[MP1]; /* bandwidth expanded LP parameters */
FLOAT *az; /* pointer to Az_4:
LPC parameters in each subframe */
int t0_max, t0_min; /* closed-loop pitch search range */
int i_subfr; /* index for beginning of subframe */
FLOAT temp1, temp2;
FLOAT h[L_H];
int i;
az = az_4;
for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
{
/* Find pitch range t0_min - t0_max */
t0_min = *T++ - 3;
t0_max = t0_min+6;
if (t0_max > PIT_MAX) {
t0_max = PIT_MAX;
t0_min = t0_max-6;
}
/* Find weighted filter coefficients ap3[] and ap[4] */
weight_az(az, GAMMA2_PST, M, ap3);
weight_az(az, GAMMA1_PST, M, ap4 );
/* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */
residu(ap3, &syn[i_subfr], res2, L_SUBFR);
/* pitch postfiltering */
pit_pst_filt(res2, t0_min, t0_max, L_SUBFR, res2_pst);
/* tilt compensation filter */
/* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */
copy(ap3, h, MP1);
set_zero(&h[MP1],L_H-MP1);
syn_filt(ap4, h, h, L_H, &h[M+1], 0);
/* 1st correlation of h[] */
temp1 = (F)0.0;
for (i=0; icor_max)
{
cor_max = corr;
t0 = i;
}
deb_sig--;
}
/* Compute the energy of the signal delayed by t0 */
ener = (F)0.5;
p = signal - t0;
for ( i=0; i ener) /* if pitch gain > 1 */
{
g0 = INV_GAMMAP;
gain = GAMMAP_2;
}
else
{
cor_max *= GAMMAP;
temp = (F)1.0/(cor_max+ener);
gain = temp * cor_max;
g0 = (F)1.0 - gain;
}
for (i = 0; i < L_subfr; i++)
signal_pst[i] = g0*signal[i] + gain*signal[i-t0];
return;
}
/*---------------------------------------------------------------------*
* routine preemphasis() *
* ~~~~~~~~~~~~~~~~~~~~~ *
* Preemphasis: filtering through 1 - g z^-1 *
*---------------------------------------------------------------------*/
static void preemphasis(
FLOAT *signal, /* in/out: input signal overwritten by the output */
FLOAT g, /* input : preemphasis coefficient */
int L /* input : size of filtering */
)
{
static FLOAT mem_pre = (F)0.;
FLOAT *p1, *p2, temp;
int i;
p1 = signal + L - 1;
p2 = p1 - 1;
temp = *p1;
for (i = 0; i <= L-2; i++) {
*p1 -= g * (*p2--); p1--; }
*p1 = *p1 - g * mem_pre;
mem_pre = temp;
return;
}
/*----------------------------------------------------------------------*
* routine agc() *
* ~~~~~~~~~~~~~ *
* Scale the postfilter output on a subframe basis by automatic control *
* of the subframe gain. *
* gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out *
*----------------------------------------------------------------------*/
static void agc(
FLOAT *sig_in, /* input : postfilter input signal */
FLOAT *sig_out, /* in/out: postfilter output signal */
int l_trm /* input : subframe size */
)
{
static FLOAT past_gain = (F)1.0;
int i;
FLOAT gain_in, gain_out;
FLOAT g0, gain;
gain_out = (F)0.;
for(i=0; i