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

语音压缩

开发平台:

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.  File : LPCA.C
  17.  Used for the floating point version of G.729A only
  18.  (not for G.729 main body)
  19. */
  20. /*****************************************************************************/
  21. /* lpc analysis routines                                                     */
  22. /*****************************************************************************/
  23. #include "typedef.h"
  24. #include "ld8a.h"
  25. #include "tab_ld8a.h"
  26. /* NOTE: these routines are assuming that the order is defined as M */
  27. /*       and that NC is defined as M/2. M has to be even           */
  28. /*----------------------------------------------------------------------------
  29.  * autocorr - compute the auto-correlations of windowed speech signal
  30.  *----------------------------------------------------------------------------
  31.  */
  32. void autocorr(
  33.      FLOAT *x,              /* input : input signal x[0:L_WINDOW] */
  34.      int m,                 /* input : LPC order                  */
  35.      FLOAT *r               /* output: auto-correlation vector r[0:M]*/
  36. )
  37. {
  38.    static FLOAT y[L_WINDOW];  /* dynamic memory allocation is used in real time*/
  39.    FLOAT sum;
  40.    int i, j;
  41.    for (i = 0; i < L_WINDOW; i++)
  42.         y[i] = x[i]*hamwindow[i];
  43.    for (i = 0; i <= m; i++)
  44.    {
  45.      sum = (F)0.0;
  46.      for (j = 0; j < L_WINDOW-i; j++)
  47.           sum += y[j]*y[j+i];
  48.      r[i] = sum;
  49.    }
  50.    if (r[0]<(F)1.0) r[0]=(F)1.0;
  51.    return;
  52. }
  53. /*-------------------------------------------------------------*
  54.  * procedure lag_window:                                       *
  55.  *           ~~~~~~~~~                                         *
  56.  * lag windowing of the autocorrelations                       *
  57.  *-------------------------------------------------------------*/
  58. void lag_window(
  59.      int m,                 /* input : LPC order                  */
  60.      FLOAT   r[]            /* in/out: correlation */
  61. )
  62. {
  63.    int i;
  64.    for (i=0; i<= m; i++)
  65.      r[i] *= lwindow[i];
  66.    return;
  67. }
  68. /*----------------------------------------------------------------------------
  69.  * levinson - levinson-durbin recursion to compute LPC parameters
  70.  *----------------------------------------------------------------------------
  71.  */
  72. FLOAT levinson(         /* output: prediction error (energy) */
  73.  FLOAT *r,              /* input : auto correlation coefficients r[0:M] */
  74.  FLOAT *a,              /* output: lpc coefficients a[0] = 1 */
  75.  FLOAT *rc              /* output: reflection coefficients rc[0:M-1]    */
  76. )
  77. {
  78.    FLOAT s, at, err;
  79.    int i, j, l;
  80.    rc[0] = (-r[1])/r[0];
  81.    a[0] = (F)1.0;
  82.    a[1] = rc[0];
  83.    err = r[0] + r[1]*rc[0];
  84.    for (i = 2; i <= M; i++)
  85.    {
  86.      s = (F)0.0;
  87.      for (j = 0; j < i; j++)
  88.        s += r[i-j]*a[j];
  89.      rc[i-1]= (-s)/(err);
  90.      for (j = 1; j <= (i/2); j++)
  91.      {
  92.        l = i-j;
  93.        at = a[j] + rc[i-1]*a[l];
  94.        a[l] += rc[i-1]*a[j];
  95.        a[j] = at;
  96.      }
  97.      a[i] = rc[i-1];
  98.      err += rc[i-1]*s;
  99.      if (err <= (F)0.0)
  100.         err = (F)0.001;
  101.    }
  102.    return (err);
  103. }
  104. /*------------------------------------------------------------------*
  105.  *  procedure az_lsp:                                               *
  106.  *            ~~~~~~                                                *
  107.  *   Compute the LSPs from  the LP coefficients a[] using Chebyshev *
  108.  * polynomials. The found LSPs are in the cosine domain with values *
  109.  * in the range from 1 down to -1.                                  *
  110.  * The table grid[] contains the points (in the cosine domain) at   *
  111.  * which the polynomials are evaluated. The table corresponds to    *
  112.  * NO_POINTS frequencies uniformly spaced between 0 and pi.         *
  113.  *------------------------------------------------------------------*/
  114. /* prototypes of local functions */
  115. static FLOAT chebyshev(FLOAT x, FLOAT *f, int n);
  116. void az_lsp(
  117.   FLOAT *a,         /* input : LP filter coefficients                     */
  118.   FLOAT *lsp,       /* output: Line spectral pairs (in the cosine domain) */
  119.   FLOAT *old_lsp    /* input : LSP vector from past frame                 */
  120. )
  121. {
  122.  int i, j, nf, ip;
  123.  FLOAT xlow,ylow,xhigh,yhigh,xmid,ymid,xint;
  124.  FLOAT *pf1;
  125.  FLOAT f1[NC+1], f2[NC+1];
  126.  /*-------------------------------------------------------------*
  127.   * find the sum and diff polynomials F1(z) and F2(z)           *
  128.   *      F1(z) = [A(z) + z^11 A(z^-1)]/(1+z^-1)                 *
  129.   *      F2(z) = [A(z) - z^11 A(z^-1)]/(1-z^-1)                 *
  130.   *-------------------------------------------------------------*/
  131.  f1[0] = (F)1.0;
  132.  f2[0] = (F)1.0;
  133.  for (i=1, j=M; i<=NC; i++, j--){
  134.     f1[i] = a[i]+a[j]-f1[i-1];
  135.     f2[i] = a[i]-a[j]+f2[i-1];
  136.  }
  137.  /*---------------------------------------------------------------------*
  138.   * Find the LSPs (roots of F1(z) and F2(z) ) using the                 *
  139.   * Chebyshev polynomial evaluation.                                    *
  140.   * The roots of F1(z) and F2(z) are alternatively searched.            *
  141.   * We start by finding the first root of F1(z) then we switch          *
  142.   * to F2(z) then back to F1(z) and so on until all roots are found.    *
  143.   *                                                                     *
  144.   *  - Evaluate Chebyshev pol. at grid points and check for sign change.*
  145.   *  - If sign change track the root by subdividing the interval        *
  146.   *    NO_ITER times and ckecking sign change.                          *
  147.   *---------------------------------------------------------------------*/
  148.  nf=0;      /* number of found frequencies */
  149.  ip=0;      /* flag to first polynomial   */
  150.  pf1 = f1;  /* start with F1(z) */
  151.  xlow=grid[0];
  152.  ylow = chebyshev(xlow,pf1,NC);
  153.  j = 0;
  154.  while ( (nf < M) && (j < GRID_POINTS) )
  155.  {
  156.    j++;
  157.    xhigh = xlow;
  158.    yhigh = ylow;
  159.    xlow = grid[j];
  160.    ylow = chebyshev(xlow,pf1,NC);
  161.    if (ylow*yhigh <= 0.0)  /* if sign change new root exists */
  162.    {
  163.      j--;
  164.      /* divide the interval of sign change by 2 */
  165.      for (i = 0; i < 2; i++)
  166.      {
  167.        xmid = (F)0.5*(xlow + xhigh);
  168.        ymid = chebyshev(xmid,pf1,NC);
  169.        if (ylow*ymid <= (F)0.0)
  170.        {
  171.          yhigh = ymid;
  172.          xhigh = xmid;
  173.        }
  174.        else
  175.        {
  176.          ylow = ymid;
  177.          xlow = xmid;
  178.        }
  179.      }
  180.      /* linear interpolation for evaluating the root */
  181.      xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);
  182.      lsp[nf] = xint;    /* new root */
  183.      nf++;
  184.      ip = 1 - ip;         /* flag to other polynomial    */
  185.      pf1 = ip ? f2 : f1;  /* pointer to other polynomial */
  186.      xlow = xint;
  187.      ylow = chebyshev(xlow,pf1,NC);
  188.    }
  189.  }
  190.  /* Check if M roots found */
  191.  /* if not use the LSPs from previous frame */
  192.  if ( nf < M)
  193.     for(i=0; i<M; i++)  lsp[i] = old_lsp[i];
  194.  return;
  195. }
  196. /*------------------------------------------------------------------*
  197.  *            End procedure az_lsp()                                *
  198.  *------------------------------------------------------------------*/
  199. /*--------------------------------------------------------------*
  200.  * function  chebyshev:                                         *
  201.  *           ~~~~~~~~~~                                         *
  202.  *    Evaluates the Chebyshev polynomial series                 *
  203.  *--------------------------------------------------------------*
  204.  *  The polynomial order is                                     *
  205.  *     n = m/2   (m is the prediction order)                    *
  206.  *  The polynomial is given by                                  *
  207.  *    C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *
  208.  *--------------------------------------------------------------*/
  209. FLOAT chebyshev(   /* output: the value of the polynomial C(x)       */
  210.   FLOAT x,         /* input : value of evaluation; x=cos(freq)       */
  211.   FLOAT *f,        /* input : coefficients of sum or diff polynomial */
  212.   int n            /* input : order of polynomial                    */
  213. )
  214. {
  215.   FLOAT b1, b2, b0, x2;
  216.   int i;                            /* for the special case of 10th order */
  217.                                       /*       filter (n=5)                 */
  218.   x2 = (F)2.0*x;                         /* x2 = 2.0*x;                        */
  219.   b2 = (F)1.0;  /* f[0] */               /*                                    */
  220.   b1 = x2 + f[1];                     /* b1 = x2 + f[1];                    */
  221.   for (i=2; i<n; i++) {               /*                                    */
  222.     b0 = x2*b1 - b2 + f[i];           /* b0 = x2 * b1 - 1. + f[2];          */
  223.     b2 = b1;                          /* b2 = x2 * b0 - b1 + f[3];          */
  224.     b1 = b0;                          /* b1 = x2 * b2 - b0 + f[4];          */
  225.   }                                   /*                                    */
  226.   return (x*b1 - b2 + (F)0.5*f[n]);      /* return (x*b1 - b2 + 0.5*f[5]);     */
  227. }