* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
- * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
- * by the XIPHOPHORUS Company http://www.xiph.org/ *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: LPC low level routines
- last mod: $Id: lpc.c,v 1.36 2003/03/07 09:13:30 xiphmont Exp $
+ last mod: $Id$
********************************************************************/
double *aut=alloca(sizeof(*aut)*(m+1));
double *lpc=alloca(sizeof(*lpc)*(m));
double error;
+ double epsilon;
int i,j;
/* autocorrelation, p+1 lag coefficients */
/* Generate lpc coefficients from autocorr values */
- error=aut[0];
-
+ /* set our noise floor to about -100dB */
+ error=aut[0] * (1. + 1e-10);
+ epsilon=1e-9*aut[0]+1e-10;
+
for(i=0;i<m;i++){
double r= -aut[i+1];
- if(error==0){
- memset(lpc,0,m*sizeof(*lpc));
- return 0;
+ if(error<epsilon){
+ memset(lpc+i,0,(m-i)*sizeof(*lpc));
+ goto done;
}
/* Sum up this iteration's reflection coefficient; note that in
lpc[j]+=r*lpc[i-1-j];
lpc[i-1-j]+=r*tmp;
}
- if(i%2)lpc[j]+=lpc[j]*r;
+ if(i&1)lpc[j]+=lpc[j]*r;
+
+ error*=1.-r*r;
- error*=1.f-r*r;
+ }
+
+ done:
+
+ /* slightly damp the filter */
+ {
+ double g = .99;
+ double damp = g;
+ for(j=0;j<m;j++){
+ lpc[j]*=damp;
+ damp*=g;
+ }
}
for(j=0;j<m;j++)lpci[j]=(float)lpc[j];