⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpca.c

📁 g729a 语音编码,再linux c 环境下实现,有非常的好的移植性,通话质量好
💻 C
字号:
/*

   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.

----------------------------------------------------------------------

*/



/*

 File : LPCA.C

 Used for the floating point version of G.729A only

 (not for G.729 main body)

*/



/*****************************************************************************/

/* lpc analysis routines                                                     */

/*****************************************************************************/



#include "typedef.h"

#include "ld8a.h"

#include "tab_ld8a.h"



/* NOTE: these routines are assuming that the order is defined as M */

/*       and that NC is defined as M/2. M has to be even           */



/*----------------------------------------------------------------------------

 * autocorr - compute the auto-correlations of windowed speech signal

 *----------------------------------------------------------------------------

 */

void autocorr(

     FLOAT *x,              /* input : input signal x[0:L_WINDOW] */

     int m,                 /* input : LPC order                  */

     FLOAT *r               /* output: auto-correlation vector r[0:M]*/

)

{

   static FLOAT y[L_WINDOW];  /* dynamic memory allocation is used in real time*/

   FLOAT sum;

   int i, j;





   for (i = 0; i < L_WINDOW; i++)

        y[i] = x[i]*hamwindow[i];



   for (i = 0; i <= m; i++)

   {

     sum = (F)0.0;

     for (j = 0; j < L_WINDOW-i; j++)

          sum += y[j]*y[j+i];

     r[i] = sum;

   }

   if (r[0]<(F)1.0) r[0]=(F)1.0;



   return;

}



/*-------------------------------------------------------------*

 * procedure lag_window:                                       *

 *           ~~~~~~~~~                                         *

 * lag windowing of the autocorrelations                       *

 *-------------------------------------------------------------*/



void lag_window(

     int m,                 /* input : LPC order                  */

     FLOAT   r[]            /* in/out: correlation */

)

{

   int i;



   for (i=0; i<= m; i++)

     r[i] *= lwindow[i];



   return;

}





/*----------------------------------------------------------------------------

 * levinson - levinson-durbin recursion to compute LPC parameters

 *----------------------------------------------------------------------------

 */

FLOAT levinson(         /* output: prediction error (energy) */

 FLOAT *r,              /* input : auto correlation coefficients r[0:M] */

 FLOAT *a,              /* output: lpc coefficients a[0] = 1 */

 FLOAT *rc              /* output: reflection coefficients rc[0:M-1]    */

)

{

   FLOAT s, at, err;

   int i, j, l;



   rc[0] = (-r[1])/r[0];

   a[0] = (F)1.0;

   a[1] = rc[0];

   err = r[0] + r[1]*rc[0];

   for (i = 2; i <= M; i++)

   {

     s = (F)0.0;

     for (j = 0; j < i; j++)

       s += r[i-j]*a[j];

     rc[i-1]= (-s)/(err);

     for (j = 1; j <= (i/2); j++)

     {

       l = i-j;

       at = a[j] + rc[i-1]*a[l];

       a[l] += rc[i-1]*a[j];

       a[j] = at;

     }

     a[i] = rc[i-1];

     err += rc[i-1]*s;

     if (err <= (F)0.0)

        err = (F)0.001;

   }

   return (err);

}



/*------------------------------------------------------------------*

 *  procedure az_lsp:                                               *

 *            ~~~~~~                                                *

 *   Compute the LSPs from  the LP coefficients a[] using Chebyshev *

 * polynomials. The found LSPs are in the cosine domain with values *

 * in the range from 1 down to -1.                                  *

 * The table grid[] contains the points (in the cosine domain) at   *

 * which the polynomials are evaluated. The table corresponds to    *

 * NO_POINTS frequencies uniformly spaced between 0 and pi.         *

 *------------------------------------------------------------------*/

/* prototypes of local functions */



static FLOAT chebyshev(FLOAT x, FLOAT *f, int n);



void az_lsp(

  FLOAT *a,         /* input : LP filter coefficients                     */

  FLOAT *lsp,       /* output: Line spectral pairs (in the cosine domain) */

  FLOAT *old_lsp    /* input : LSP vector from past frame                 */

)

{

 int i, j, nf, ip;

 FLOAT xlow,ylow,xhigh,yhigh,xmid,ymid,xint;

 FLOAT *pf1;



 FLOAT f1[NC+1], f2[NC+1];



 /*-------------------------------------------------------------*

  * find the sum and diff polynomials F1(z) and F2(z)           *

  *      F1(z) = [A(z) + z^11 A(z^-1)]/(1+z^-1)                 *

  *      F2(z) = [A(z) - z^11 A(z^-1)]/(1-z^-1)                 *

  *-------------------------------------------------------------*/



 f1[0] = (F)1.0;

 f2[0] = (F)1.0;

 for (i=1, j=M; i<=NC; i++, j--){

    f1[i] = a[i]+a[j]-f1[i-1];

    f2[i] = a[i]-a[j]+f2[i-1];

 }



 /*---------------------------------------------------------------------*

  * Find the LSPs (roots of F1(z) and F2(z) ) using the                 *

  * Chebyshev polynomial evaluation.                                    *

  * The roots of F1(z) and F2(z) are alternatively searched.            *

  * We start by finding the first root of F1(z) then we switch          *

  * to F2(z) then back to F1(z) and so on until all roots are found.    *

  *                                                                     *

  *  - Evaluate Chebyshev pol. at grid points and check for sign change.*

  *  - If sign change track the root by subdividing the interval        *

  *    NO_ITER times and ckecking sign change.                          *

  *---------------------------------------------------------------------*/



 nf=0;      /* number of found frequencies */

 ip=0;      /* flag to first polynomial   */



 pf1 = f1;  /* start with F1(z) */



 xlow=grid[0];

 ylow = chebyshev(xlow,pf1,NC);



 j = 0;

 while ( (nf < M) && (j < GRID_POINTS) )

 {

   j++;

   xhigh = xlow;

   yhigh = ylow;

   xlow = grid[j];

   ylow = chebyshev(xlow,pf1,NC);



   if (ylow*yhigh <= 0.0)  /* if sign change new root exists */

   {

     j--;



     /* divide the interval of sign change by 2 */



     for (i = 0; i < 2; i++)

     {

       xmid = (F)0.5*(xlow + xhigh);

       ymid = chebyshev(xmid,pf1,NC);

       if (ylow*ymid <= (F)0.0)

       {

         yhigh = ymid;

         xhigh = xmid;

       }

       else

       {

         ylow = ymid;

         xlow = xmid;

       }

     }



     /* linear interpolation for evaluating the root */



     xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);



     lsp[nf] = xint;    /* new root */

     nf++;



     ip = 1 - ip;         /* flag to other polynomial    */

     pf1 = ip ? f2 : f1;  /* pointer to other polynomial */



     xlow = xint;

     ylow = chebyshev(xlow,pf1,NC);

   }

 }



 /* Check if M roots found */

 /* if not use the LSPs from previous frame */



 if ( nf < M)

    for(i=0; i<M; i++)  lsp[i] = old_lsp[i];



 return;

}

/*------------------------------------------------------------------*

 *            End procedure az_lsp()                                *

 *------------------------------------------------------------------*/



/*--------------------------------------------------------------*

 * function  chebyshev:                                         *

 *           ~~~~~~~~~~                                         *

 *    Evaluates the Chebyshev polynomial series                 *

 *--------------------------------------------------------------*

 *  The polynomial order is                                     *

 *     n = m/2   (m is the prediction order)                    *

 *  The polynomial is given by                                  *

 *    C(x) = T_n(x) + f(1)T_n-1(x) + ... +f(n-1)T_1(x) + f(n)/2 *

 *--------------------------------------------------------------*/



FLOAT chebyshev(   /* output: the value of the polynomial C(x)       */

  FLOAT x,         /* input : value of evaluation; x=cos(freq)       */

  FLOAT *f,        /* input : coefficients of sum or diff polynomial */

  int n            /* input : order of polynomial                    */

)

{

  FLOAT b1, b2, b0, x2;

  int i;                            /* for the special case of 10th order */

                                      /*       filter (n=5)                 */

  x2 = (F)2.0*x;                         /* x2 = 2.0*x;                        */

  b2 = (F)1.0;  /* f[0] */               /*                                    */

  b1 = x2 + f[1];                     /* b1 = x2 + f[1];                    */

  for (i=2; i<n; i++) {               /*                                    */

    b0 = x2*b1 - b2 + f[i];           /* b0 = x2 * b1 - 1. + f[2];          */

    b2 = b1;                          /* b2 = x2 * b0 - b1 + f[3];          */

    b1 = b0;                          /* b1 = x2 * b2 - b0 + f[4];          */

  }                                   /*                                    */

  return (x*b1 - b2 + (F)0.5*f[n]);      /* return (x*b1 - b2 + 0.5*f[5]);     */

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -