POSTFILT.C
上传用户:meifeng08
上传日期:2013-06-18
资源大小:5304k
文件大小:14k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2.    ITU-T G.729A Speech Coder    ANSI-C Source Code
  3.    Version 1.1    Last modified: September 1996
  4.    Copyright (c) 1996,
  5.    AT&T, France Telecom, NTT, Universite de Sherbrooke
  6.    All rights reserved.
  7. */
  8. /*------------------------------------------------------------------------*
  9.  *                         POSTFILTER.C                                   *
  10.  *------------------------------------------------------------------------*
  11.  * Performs adaptive postfiltering on the synthesis speech                *
  12.  * This file contains all functions related to the post filter.           *
  13.  *------------------------------------------------------------------------*/
  14. #include "typedef.h"
  15. #include "basic_op.h"
  16. #include "ld8a.h"
  17. #include "oper_32b.h"
  18. /*---------------------------------------------------------------*
  19.  *    Postfilter constant parameters (defined in "ld8a.h")       *
  20.  *---------------------------------------------------------------*
  21.  *   L_FRAME     : Frame size.                                   *
  22.  *   L_SUBFR     : Sub-frame size.                               *
  23.  *   M           : LPC order.                                    *
  24.  *   MP1         : LPC order+1                                   *
  25.  *   PIT_MAX     : Maximum pitch lag.                            *
  26.  *   GAMMA2_PST  : Formant postfiltering factor (numerator)      *
  27.  *   GAMMA1_PST  : Formant postfiltering factor (denominator)    *
  28.  *   GAMMAP      : Harmonic postfiltering factor                 *
  29.  *   MU          : Factor for tilt compensation filter           *
  30.  *   AGC_FAC     : Factor for automatic gain control             *
  31.  *---------------------------------------------------------------*/
  32. /*------------------------------------------------------------*
  33.  *   static vectors                                           *
  34.  *------------------------------------------------------------*/
  35.         /* inverse filtered synthesis (with A(z/GAMMA2_PST))   */
  36. static Word16 res2_buf[PIT_MAX+L_SUBFR];
  37. static Word16 *res2;
  38. static Word16 scal_res2_buf[PIT_MAX+L_SUBFR];
  39. static Word16 *scal_res2;
  40.         /* memory of filter 1/A(z/GAMMA1_PST) */
  41. static Word16 mem_syn_pst[M];
  42. /*---------------------------------------------------------------*
  43.  * Procedure    Init_Post_Filter:                                *
  44.  *              ~~~~~~~~~~~~~~~~                                 *
  45.  *  Initializes the postfilter parameters:                       *
  46.  *---------------------------------------------------------------*/
  47. void Init_Post_Filter(void)
  48. {
  49.   res2  = res2_buf + PIT_MAX;
  50.   scal_res2  = scal_res2_buf + PIT_MAX;
  51.   Set_zero(mem_syn_pst, M);
  52.   Set_zero(res2_buf, PIT_MAX+L_SUBFR);
  53.   Set_zero(scal_res2_buf, PIT_MAX+L_SUBFR);
  54.   return;
  55. }
  56. /*------------------------------------------------------------------------*
  57.  *  Procedure     Post_Filter:                                            *
  58.  *                ~~~~~~~~~~~                                             *
  59.  *------------------------------------------------------------------------*
  60.  *  The postfiltering process is described as follows:                    *
  61.  *                                                                        *
  62.  *  - inverse filtering of syn[] through A(z/GAMMA2_PST) to get res2[]    *
  63.  *  - use res2[] to compute pitch parameters                              *
  64.  *  - perform pitch postfiltering                                         *
  65.  *  - tilt compensation filtering; 1 - MU*k*z^-1                          *
  66.  *  - synthesis filtering through 1/A(z/GAMMA1_PST)                       *
  67.  *  - adaptive gain control                                               *
  68.  *------------------------------------------------------------------------*/
  69. void Post_Filter(
  70.   Word16 *syn,       /* in/out: synthesis speech (postfiltered is output)    */
  71.   Word16 *Az_4,      /* input : interpolated LPC parameters in all subframes */
  72.   Word16 *T          /* input : decoded pitch lags in all subframes          */
  73. )
  74. {
  75.  /*-------------------------------------------------------------------*
  76.   *           Declaration of parameters                               *
  77.   *-------------------------------------------------------------------*/
  78.  Word16 res2_pst[L_SUBFR];  /* res2[] after pitch postfiltering */
  79.  Word16 syn_pst[L_FRAME];   /* post filtered synthesis speech   */
  80.  Word16 Ap3[MP1], Ap4[MP1];  /* bandwidth expanded LP parameters */
  81.  Word16 *Az;                 /* pointer to Az_4:                 */
  82.                              /*  LPC parameters in each subframe */
  83.  Word16   t0_max, t0_min;    /* closed-loop pitch search range   */
  84.  Word16   i_subfr;           /* index for beginning of subframe  */
  85.  Word16 h[L_H];
  86.  Word16  i, j;
  87.  Word16  temp1, temp2;
  88.  Word32  L_tmp;
  89.    /*-----------------------------------------------------*
  90.     * Post filtering                                      *
  91.     *-----------------------------------------------------*/
  92.     Az = Az_4;
  93.     for (i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR)
  94.     {
  95.       /* Find pitch range t0_min - t0_max */
  96.       t0_min = sub(*T++, 3);
  97.       t0_max = add(t0_min, 6);
  98.       if (sub(t0_max, PIT_MAX) > 0) {
  99.         t0_max = PIT_MAX;
  100.         t0_min = sub(t0_max, 6);
  101.       }
  102.       /* Find weighted filter coefficients Ap3[] and ap[4] */
  103.       Weight_Az(Az, GAMMA2_PST, M, Ap3);
  104.       Weight_Az(Az, GAMMA1_PST, M, Ap4);
  105.       /* filtering of synthesis speech by A(z/GAMMA2_PST) to find res2[] */
  106.       Residu(Ap3, &syn[i_subfr], res2, L_SUBFR);
  107.       /* scaling of "res2[]" to avoid energy overflow */
  108.       for (j=0; j<L_SUBFR; j++)
  109.       {
  110.         scal_res2[j] = shr(res2[j], 2);
  111.       }
  112.       /* pitch postfiltering */
  113.       pit_pst_filt(res2, scal_res2, t0_min, t0_max, L_SUBFR, res2_pst);
  114.       /* tilt compensation filter */
  115.       /* impulse response of A(z/GAMMA2_PST)/A(z/GAMMA1_PST) */
  116.       Copy(Ap3, h, M+1);
  117.       Set_zero(&h[M+1], L_H-M-1);
  118.       Syn_filt(Ap4, h, h, L_H, &h[M+1], 0);
  119.       /* 1st correlation of h[] */
  120.       L_tmp = L_mult(h[0], h[0]);
  121.       for (i=1; i<L_H; i++) L_tmp = L_mac(L_tmp, h[i], h[i]);
  122.       temp1 = extract_h(L_tmp);
  123.       L_tmp = L_mult(h[0], h[1]);
  124.       for (i=1; i<L_H-1; i++) L_tmp = L_mac(L_tmp, h[i], h[i+1]);
  125.       temp2 = extract_h(L_tmp);
  126.       if(temp2 <= 0) {
  127.         temp2 = 0;
  128.       }
  129.       else {
  130.         temp2 = mult(temp2, MU);
  131.         temp2 = div_s(temp2, temp1);
  132.       }
  133.       preemphasis(res2_pst, temp2, L_SUBFR);
  134.       /* filtering through  1/A(z/GAMMA1_PST) */
  135.       Syn_filt(Ap4, res2_pst, &syn_pst[i_subfr], L_SUBFR, mem_syn_pst, 1);
  136.       /* scale output to input */
  137.       agc(&syn[i_subfr], &syn_pst[i_subfr], L_SUBFR);
  138.       /* update res2[] buffer;  shift by L_SUBFR */
  139.       Copy(&res2[L_SUBFR-PIT_MAX], &res2[-PIT_MAX], PIT_MAX);
  140.       Copy(&scal_res2[L_SUBFR-PIT_MAX], &scal_res2[-PIT_MAX], PIT_MAX);
  141.       Az += MP1;
  142.     }
  143.     /* update syn[] buffer */
  144.     Copy(&syn[L_FRAME-M], &syn[-M], M);
  145.     /* overwrite synthesis speech by postfiltered synthesis speech */
  146.     Copy(syn_pst, syn, L_FRAME);
  147.     return;
  148. }
  149. /*---------------------------------------------------------------------------*
  150.  * procedure pitch_pst_filt                                                  *
  151.  * ~~~~~~~~~~~~~~~~~~~~~~~~                                                  *
  152.  * Find the pitch period  around the transmitted pitch and perform           *
  153.  * harmonic postfiltering.                                                   *
  154.  * Filtering through   (1 + g z^-T) / (1+g) ;   g = min(pit_gain*gammap, 1)  *
  155.  *--------------------------------------------------------------------------*/
  156. void pit_pst_filt(
  157.   Word16 *signal,      /* (i)     : input signal                        */
  158.   Word16 *scal_sig,    /* (i)     : input signal (scaled, divided by 4) */
  159.   Word16 t0_min,       /* (i)     : minimum value in the searched range */
  160.   Word16 t0_max,       /* (i)     : maximum value in the searched range */
  161.   Word16 L_subfr,      /* (i)     : size of filtering                   */
  162.   Word16 *signal_pst   /* (o)     : harmonically postfiltered signal    */
  163. )
  164. {
  165.   Word16 i, j, t0;
  166.   Word16 g0, gain, cmax, en, en0;
  167.   Word16 *p, *p1, *deb_sig;
  168.   Word32 corr, cor_max, ener, ener0, temp;
  169.   Word32 L_temp;
  170. /*---------------------------------------------------------------------------*
  171.  * Compute the correlations for all delays                                   *
  172.  * and select the delay which maximizes the correlation                      *
  173.  *---------------------------------------------------------------------------*/
  174.   deb_sig = &scal_sig[-t0_min];
  175.   cor_max = MIN_32;
  176.   t0 = t0_min;             /* Only to remove warning from some compilers */
  177.   for (i=t0_min; i<=t0_max; i++)
  178.   {
  179.     corr = 0;
  180.     p    = scal_sig;
  181.     p1   = deb_sig;
  182.     for (j=0; j<L_subfr; j++)
  183.        corr = L_mac(corr, *p++, *p1++);
  184.     L_temp = L_sub(corr, cor_max);
  185.     if (L_temp > (Word32)0)
  186.     {
  187.       cor_max = corr;
  188.       t0 = i;
  189.     }
  190.     deb_sig--;
  191.   }
  192.   /* Compute the energy of the signal delayed by t0 */
  193.   ener = 1;
  194.   p = scal_sig - t0;
  195.   for ( i=0; i<L_subfr ;i++, p++)
  196.     ener = L_mac(ener, *p, *p);
  197.   /* Compute the signal energy in the present subframe */
  198.   ener0 = 1;
  199.   p = scal_sig;
  200.   for ( i=0; i<L_subfr; i++, p++)
  201.     ener0 = L_mac(ener0, *p, *p);
  202.   if (cor_max < 0)
  203.   {
  204.     cor_max = 0;
  205.   }
  206.   /* scale "cor_max", "ener" and "ener0" on 16 bits */
  207.   temp = cor_max;
  208.   if (ener > temp)
  209.   {
  210.     temp = ener;
  211.   }
  212.   if (ener0 > temp)
  213.   {
  214.     temp = ener0;
  215.   }
  216.   j = norm_l(temp);
  217.   cmax = round(L_shl(cor_max, j));
  218.   en = round(L_shl(ener, j));
  219.   en0 = round(L_shl(ener0, j));
  220.   /* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */
  221.   /* temp = (cor_max * cor_max) - (0.5 * ener * ener0)  */
  222.   temp = L_mult(cmax, cmax);
  223.   temp = L_sub(temp, L_shr(L_mult(en, en0), 1));
  224.   if (temp < (Word32)0)           /* if prediction gain < 3 dB   */
  225.   {                               /* switch off pitch postfilter */
  226.     for (i = 0; i < L_subfr; i++)
  227.       signal_pst[i] = signal[i];
  228.     return;
  229.   }
  230.   if (sub(cmax, en) > 0)      /* if pitch gain > 1 */
  231.   {
  232.     g0 = INV_GAMMAP;
  233.     gain = GAMMAP_2;
  234.   }
  235.   else {
  236.     cmax = shr(mult(cmax, GAMMAP), 1);  /* cmax(Q14) = cmax(Q15) * GAMMAP */
  237.     en = shr(en, 1);          /* Q14 */
  238.     i = add(cmax, en);
  239.     if(i > 0)
  240.     {
  241.       gain = div_s(cmax, i);    /* gain(Q15) = cor_max/(cor_max+ener)  */
  242.       g0 = sub(32767, gain);    /* g0(Q15) = 1 - gain */
  243.     }
  244.     else
  245.     {
  246.       g0 =  32767;
  247.       gain = 0;
  248.     }
  249.   }
  250.   for (i = 0; i < L_subfr; i++)
  251.   {
  252.     /* signal_pst[i] = g0*signal[i] + gain*signal[i-t0]; */
  253.     signal_pst[i] = add(mult(g0, signal[i]), mult(gain, signal[i-t0]));
  254.   }
  255.   return;
  256. }
  257. /*---------------------------------------------------------------------*
  258.  * routine preemphasis()                                               *
  259.  * ~~~~~~~~~~~~~~~~~~~~~                                               *
  260.  * Preemphasis: filtering through 1 - g z^-1                           *
  261.  *---------------------------------------------------------------------*/
  262. void preemphasis(
  263.   Word16 *signal,  /* (i/o)   : input signal overwritten by the output */
  264.   Word16 g,        /* (i) Q15 : preemphasis coefficient                */
  265.   Word16 L         /* (i)     : size of filtering                      */
  266. )
  267. {
  268.   static Word16 mem_pre = 0;
  269.   Word16 *p1, *p2, temp, i;
  270.   p1 = signal + L - 1;
  271.   p2 = p1 - 1;
  272.   temp = *p1;
  273.   for (i = 0; i <= L-2; i++)
  274.   {
  275.     *p1-- = sub(*p1, mult(g, *p2--));
  276.   }
  277.   *p1 = sub(*p1, mult(g, mem_pre));
  278.   mem_pre = temp;
  279.   return;
  280. }
  281. /*----------------------------------------------------------------------*
  282.  *   routine agc()                                                      *
  283.  *   ~~~~~~~~~~~~~                                                      *
  284.  * Scale the postfilter output on a subframe basis by automatic control *
  285.  * of the subframe gain.                                                *
  286.  *  gain[n] = AGC_FAC * gain[n-1] + (1 - AGC_FAC) g_in/g_out            *
  287.  *----------------------------------------------------------------------*/
  288. void agc(
  289.   Word16 *sig_in,   /* (i)     : postfilter input signal  */
  290.   Word16 *sig_out,  /* (i/o)   : postfilter output signal */
  291.   Word16 l_trm      /* (i)     : subframe size            */
  292. )
  293. {
  294.   static Word16 past_gain=4096;         /* past_gain = 1.0 (Q12) */
  295.   Word16 i, exp;
  296.   Word16 gain_in, gain_out, g0, gain;                     /* Q12 */
  297.   Word32 s;
  298.   Word16 signal[L_SUBFR];
  299.   /* calculate gain_out with exponent */
  300.   for(i=0; i<l_trm; i++)
  301.     signal[i] = shr(sig_out[i], 2);
  302.   s = 0;
  303.   for(i=0; i<l_trm; i++)
  304.     s = L_mac(s, signal[i], signal[i]);
  305.   if (s == 0) {
  306.     past_gain = 0;
  307.     return;
  308.   }
  309.   exp = sub(norm_l(s), 1);
  310.   gain_out = round(L_shl(s, exp));
  311.   /* calculate gain_in with exponent */
  312.   for(i=0; i<l_trm; i++)
  313.     signal[i] = shr(sig_in[i], 2);
  314.   s = 0;
  315.   for(i=0; i<l_trm; i++)
  316.     s = L_mac(s, signal[i], signal[i]);
  317.   if (s == 0) {
  318.     g0 = 0;
  319.   }
  320.   else {
  321.     i = norm_l(s);
  322.     gain_in = round(L_shl(s, i));
  323.     exp = sub(exp, i);
  324.    /*---------------------------------------------------*
  325.     *  g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out);  *
  326.     *---------------------------------------------------*/
  327.     s = L_deposit_l(div_s(gain_out,gain_in));   /* Q15 */
  328.     s = L_shl(s, 7);           /* s(Q22) = gain_out / gain_in */
  329.     s = L_shr(s, exp);         /* Q22, add exponent */
  330.     /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
  331.     s = Inv_sqrt(s);           /* Q19 */
  332.     i = round(L_shl(s,9));     /* Q12 */
  333.     /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
  334.     g0 = mult(i, AGC_FAC1);       /* Q12 */
  335.   }
  336.   /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  337.   /* sig_out(n) = gain(n) sig_out(n)                                   */
  338.   gain = past_gain;
  339.   for(i=0; i<l_trm; i++) {
  340.     gain = mult(gain, AGC_FAC);
  341.     gain = add(gain, g0);
  342.     sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3));
  343.   }
  344.   past_gain = gain;
  345.   return;
  346. }