Bump the encoder vendor string for the 1.2.1 release, since there were
[platform/upstream/libvorbis.git] / lib / lpc.c
index 7fabe84..b3c0998 100644 (file)
--- a/lib/lpc.c
+++ b/lib/lpc.c
@@ -5,13 +5,13 @@
  * 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.37 2003/03/08 07:15:32 xiphmont Exp $
+  last mod: $Id$
 
  ********************************************************************/
 
@@ -62,6 +62,7 @@ float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
   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 */
@@ -74,14 +75,16 @@ float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
   
   /* 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(lpci,0,m*sizeof(*lpci));
-      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
@@ -101,9 +104,22 @@ float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
       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];