postfila.c
上传用户:zhouyunkk
上传日期:2013-01-10
资源大小:59k
文件大小:13k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2.    ITU-T G.729 Annex C - Reference C code for floating point
  3.                          implementation of G.729 Annex A
  4.                          Version 1.01 of 15.September.98
  5. */
  6. /*
  7. ----------------------------------------------------------------------
  8.                     COPYRIGHT NOTICE
  9. ----------------------------------------------------------------------
  10.    ITU-T G.729 Annex C ANSI C source code
  11.    Copyright (C) 1998, AT&T, France Telecom, NTT, University of
  12.    Sherbrooke.  All rights reserved.
  13. ----------------------------------------------------------------------
  14. */
  15. /*------------------------------------------------------------------------*
  16.  *                         POSTFILTER.C                                   *
  17.  *------------------------------------------------------------------------*
  18.  * Performs adaptive postfiltering on the synthesis speech                *
  19.  * This file contains all functions related to the post filter.           *
  20.  *------------------------------------------------------------------------*/
  21. #include <math.h>
  22. #include "typedef.h"
  23. #include "ld8a.h"
  24. /* prototype of local functions */
  25. static void pit_pst_filt(
  26.   FLOAT *signal,        /* input : input signal                        */
  27.   int   t0_min,         /* input : minimum value in the searched range */
  28.   int   t0_max,         /* input : maximum value in the searched range */
  29.   int   L_subfr,        /* input : size of filtering                   */
  30.   FLOAT *signal_pst     /* output: harmonically postfiltered signal    */
  31. );
  32. static void agc(
  33.   FLOAT *sig_in,   /* input : postfilter input signal  */
  34.   FLOAT *sig_out,  /* in/out: postfilter output signal */
  35.   int l_trm        /* input : subframe size            */
  36. );
  37. static void preemphasis(
  38.   FLOAT *signal,   /* in/out: input signal overwritten by the output */
  39.   FLOAT g,         /* input : preemphasis coefficient                */
  40.   int L            /* input : size of filtering                      */
  41. );
  42. /*---------------------------------------------------------------*
  43.  *    Postfilter constant parameters (defined in "ld8a.h")       *
  44.  *---------------------------------------------------------------*
  45.  *   L_FRAME     : Frame size.                                   *
  46.  *   L_SUBFR     : Sub-frame size.                               *
  47.  *   M           : LPC order.                                    *
  48.  *   MP1         : LPC order+1                                   *
  49.  *   PIT_MAX     : Maximum pitch lag.                            *
  50.  *   GAMMA2_PST  : Formant postfiltering factor (numerator)      *
  51.  *   GAMMA1_PST  : Formant postfiltering factor (denominator)    *
  52.  *   GAMMAP      : Harmonic postfiltering factor                 *
  53.  *   MU          : Factor for tilt compensation filter           *
  54.  *   AGC_FAC     : Factor for automatic gain control             *
  55.  *---------------------------------------------------------------*/
  56. /*------------------------------------------------------------*
  57.  *   static vectors                                           *
  58.  *------------------------------------------------------------*/
  59.         /* inverse filtered synthesis (with A(z/GAMMA2_PST))   */
  60. static FLOAT res2_buf[PIT_MAX+L_SUBFR];
  61. static FLOAT *res2;
  62.         /* memory of filter 1/A(z/GAMMA1_PST) */
  63. static FLOAT mem_syn_pst[M];
  64. /*---------------------------------------------------------------*
  65.  * Procedure    init_post_filter:                                 *
  66.  *              ~~~~~~~~~~~~~                                    *
  67.  *  Initializes the postfilter parameters:                       *
  68.  *---------------------------------------------------------------*/
  69. void init_post_filter(void)
  70. {
  71.   res2  = res2_buf + PIT_MAX;
  72.   set_zero(mem_syn_pst, M);
  73.   set_zero(res2_buf, PIT_MAX+L_SUBFR);
  74.   return;
  75. }
  76. /*------------------------------------------------------------------------*
  77.  *  Procedure     post_filter:                                            *
  78.  *                ~~~~~~~~~~~                                             *
  79.  *------------------------------------------------------------------------*
  80.  *  The postfiltering process is described as follows:                    *
  81.  *                                                                        *
  82.  *  - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[]    *
  83.  *  - use res2[] to compute pitch parameters                              *
  84.  *  - perform pitch postfiltering                                         *
  85.  *  - tilt compensation filtering; 1 - MU*k*z^-1                          *
  86.  *  - synthesis filtering through 1/A(z/GAMMA1_PST)                       *
  87.  *  - adaptive gain control                                               *
  88.  *------------------------------------------------------------------------*/
  89. void post_filter(
  90.   FLOAT *syn,     /* in/out: synthesis speech (postfiltered is output)    */
  91.   FLOAT *az_4,    /* input : interpolated LPC parameters in all subframes */
  92.   int *T          /* input : decoded pitch lags in all subframes          */
  93. )
  94. {
  95.   /*-------------------------------------------------------------------*
  96.    *           Declaration of parameters                               *
  97.    *-------------------------------------------------------------------*/
  98.   FLOAT res2_pst[L_SUBFR];  /* res2[] after pitch postfiltering */
  99.   FLOAT syn_pst[L_FRAME];   /* post filtered synthesis speech   */
  100.   FLOAT ap3[MP1], ap4[MP1]; /* bandwidth expanded LP parameters */
  101.   FLOAT *az;                /* pointer to Az_4:
  102.                                LPC parameters in each subframe   */
  103.   int   t0_max, t0_min;     /* closed-loop pitch search range  */
  104.   int   i_subfr;            /* index for beginning of subframe */
  105.   FLOAT temp1, temp2;
  106.   FLOAT h[L_H];
  107.   int   i;
  108.   az = az_4;
  109.   for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
  110.   {
  111.     /* Find pitch range t0_min - t0_max */
  112.     t0_min = *T++ - 3;
  113.     t0_max = t0_min+6;
  114.     if (t0_max > PIT_MAX) {
  115.       t0_max = PIT_MAX;
  116.       t0_min = t0_max-6;
  117.     }
  118.     /* Find weighted filter coefficients ap3[] and ap[4] */
  119.     weight_az(az, GAMMA2_PST, M, ap3);
  120.     weight_az(az, GAMMA1_PST, M, ap4 );
  121.     /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */
  122.     residu(ap3, &syn[i_subfr], res2, L_SUBFR);
  123.     /* pitch postfiltering */
  124.     pit_pst_filt(res2, t0_min, t0_max, L_SUBFR, res2_pst);
  125.     /* tilt compensation filter */
  126.     /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */
  127.     copy(ap3, h, MP1);
  128.     set_zero(&h[MP1],L_H-MP1);
  129.     syn_filt(ap4, h, h, L_H, &h[M+1], 0);
  130.     /* 1st correlation of h[] */
  131.     temp1 = (F)0.0;
  132.     for (i=0; i<L_H; i++) temp1 += h[i]*h[i];
  133.     temp2 = (F)0.0;
  134.     for (i=0; i<L_H-1; i++) temp2 += h[i]*h[i+1];
  135.     if(temp2 <= (F)0.0) {
  136.       temp2 = (F)0.0;
  137.     }
  138.     else {
  139.        temp2 = temp2*MU/temp1;
  140.     }
  141.     preemphasis(res2_pst, temp2, L_SUBFR);
  142.     /* filtering through  1/A(z/GAMMA1_PST) */
  143.     syn_filt(ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, mem_syn_pst, 1);
  144.     /* scale output to input */
  145.     agc(&syn[i_subfr], &syn_pst[i_subfr], L_SUBFR);
  146.     /* update res2[] buffer;  shift by L_SUBFR */
  147.     copy(&res2[L_SUBFR-PIT_MAX], &res2[-PIT_MAX], PIT_MAX);
  148.     az += MP1;
  149.   }
  150.   /* update syn[] buffer */
  151.   copy(&syn[L_FRAME-M], &syn[-M], M);
  152.   /* overwrite synthesis speech by postfiltered synthesis speech */
  153.   copy(syn_pst, syn, L_FRAME);
  154.   return;
  155. }
  156. /*---------------------------------------------------------------------------*
  157.  * procedure pit_pst_filt                                                    *
  158.  * ~~~~~~~~~~~~~~~~~~~~~~                                                    *
  159.  * Find the pitch period  around the transmitted pitch and perform           *
  160.  * harmonic postfiltering.                                                   *
  161.  * Filtering through   (1 + g z^-T) / (1+g) ;   g = min(pit_gain*gammap, 1)  *
  162.  *--------------------------------------------------------------------------*/
  163. static void pit_pst_filt(
  164.   FLOAT *signal,        /* input : input signal                        */
  165.   int   t0_min,         /* input : minimum value in the searched range */
  166.   int   t0_max,         /* input : maximum value in the searched range */
  167.   int   L_subfr,        /* input : size of filtering                   */
  168.   FLOAT *signal_pst     /* output: harmonically postfiltered signal    */
  169. )
  170. {
  171.   int    i, j;
  172.   int    t0;
  173.   FLOAT  cor_max;
  174.   FLOAT  temp, g0, gain;
  175.   FLOAT  ener, corr, ener0;
  176.   FLOAT  *p, *p1, *deb_sig;
  177. /*---------------------------------------------------------------------------*
  178.  * Compute the correlations for all delays                                   *
  179.  * and select the delay which maximizes the correlation                      *
  180.  *---------------------------------------------------------------------------*/
  181.   deb_sig = &signal[-t0_min];
  182.   cor_max = FLT_MIN_G729;
  183.   for (i=t0_min; i<=t0_max; i++)
  184.   {
  185.     corr = (F)0.0;
  186.     p    = signal;
  187.     p1   = deb_sig;
  188.     for (j=0; j<L_subfr; j++)
  189.        corr += (*p++) * (*p1++);
  190.     if (corr>cor_max)
  191.     {
  192.       cor_max = corr;
  193.       t0 = i;
  194.     }
  195.     deb_sig--;
  196.   }
  197.   /* Compute the energy of the signal delayed by t0 */
  198.   ener = (F)0.5;
  199.   p = signal - t0;
  200.   for ( i=0; i<L_subfr ;i++, p++)
  201.     ener += (*p) * (*p);
  202.   /* Compute the signal energy in the present subframe */
  203.   ener0 = (F)0.5;
  204.   p = signal;
  205.   for ( i=0; i<L_subfr; i++, p++)
  206.     ener0 += (*p) * (*p);
  207.   if (cor_max < (F)0.0) cor_max = (F)0.0;
  208.   /* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */
  209.   temp = cor_max*cor_max;
  210.   if (temp < ener*ener0*0.5)        /* if prediction gain < 3 dB   */
  211.   {                                 /* switch off pitch postfilter */
  212.      for (i = 0; i < L_subfr; i++)
  213.                signal_pst[i] = signal[i];
  214.      return;
  215.   }
  216.   if (cor_max > ener)     /* if pitch gain > 1 */
  217.   {
  218.      g0 = INV_GAMMAP;
  219.      gain = GAMMAP_2;
  220.   }
  221.   else
  222.   {
  223.     cor_max *= GAMMAP;
  224.     temp = (F)1.0/(cor_max+ener);
  225.     gain = temp * cor_max;
  226.     g0   = (F)1.0 - gain;
  227.   }
  228.   for (i = 0; i < L_subfr; i++)
  229.     signal_pst[i] = g0*signal[i] + gain*signal[i-t0];
  230.   return;
  231. }
  232. /*---------------------------------------------------------------------*
  233.  * routine preemphasis()                                               *
  234.  * ~~~~~~~~~~~~~~~~~~~~~                                               *
  235.  * Preemphasis: filtering through 1 - g z^-1                           *
  236.  *---------------------------------------------------------------------*/
  237. static void preemphasis(
  238.   FLOAT *signal,    /* in/out: input signal overwritten by the output */
  239.   FLOAT g,          /* input : preemphasis coefficient                */
  240.   int L             /* input : size of filtering                      */
  241. )
  242. {
  243.   static FLOAT mem_pre = (F)0.;
  244.   FLOAT *p1, *p2, temp;
  245.   int   i;
  246.   p1 = signal + L - 1;
  247.   p2 = p1 - 1;
  248.   temp = *p1;
  249.   for (i = 0; i <= L-2; i++) {
  250.     *p1 -= g * (*p2--); p1--; }
  251.   *p1 = *p1 - g * mem_pre;
  252.   mem_pre = temp;
  253.   return;
  254. }
  255. /*----------------------------------------------------------------------*
  256.  *   routine agc()                                                      *
  257.  *   ~~~~~~~~~~~~~                                                      *
  258.  * Scale the postfilter output on a subframe basis by automatic control *
  259.  * of the subframe gain.                                                *
  260.  *  gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out            *
  261.  *----------------------------------------------------------------------*/
  262. static void agc(
  263.   FLOAT *sig_in,    /* input : postfilter input signal  */
  264.   FLOAT *sig_out,   /* in/out: postfilter output signal */
  265.   int l_trm         /* input : subframe size            */
  266. )
  267. {
  268.     static FLOAT past_gain = (F)1.0;
  269.     int i;
  270.     FLOAT gain_in, gain_out;
  271.     FLOAT g0, gain;
  272.     gain_out = (F)0.;
  273.     for(i=0; i<l_trm; i++) {
  274.             gain_out += sig_out[i]*sig_out[i];
  275.     }
  276.     if(gain_out == (F)0.) {
  277.             past_gain = (F)0.;
  278.             return;
  279.     }
  280.     gain_in = (F)0.;
  281.     for(i=0; i<l_trm; i++) {
  282.             gain_in += sig_in[i]*sig_in[i];
  283.     }
  284.     if(gain_in == (F)0.) {
  285.             g0 = (F)0.;
  286.     }
  287.     else {
  288.             g0 = (FLOAT)sqrt(gain_in/ gain_out);
  289.             g0 *=  AGC_FAC1;
  290.     }
  291.     /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  292.     /* sig_out(n) = gain(n) sig_out(n)                         */
  293.     gain = past_gain;
  294.     for(i=0; i<l_trm; i++) {
  295.             gain *= AGC_FAC;
  296.             gain += g0;
  297.             sig_out[i] *= gain;
  298.     }
  299.     past_gain = gain;
  300.     return;
  301. }