LPC filter generation (for pre- and post-extrapolation) requires
authorMonty <xiphmont@xiph.org>
Fri, 7 Mar 2003 09:13:30 +0000 (09:13 +0000)
committerMonty <xiphmont@xiph.org>
Fri, 7 Mar 2003 09:13:30 +0000 (09:13 +0000)
greater than float mantissa depth.  Go to doubles for filter generation.

svn path=/trunk/vorbis/; revision=4433

lib/floor0.c
lib/lpc.c
lib/lpc.h

index 5b0d68e..cfa8487 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: floor backend 0 implementation
- last mod: $Id: floor0.c,v 1.53 2002/07/17 21:34:31 xiphmont Exp $
+ last mod: $Id: floor0.c,v 1.54 2003/03/07 09:13:30 xiphmont Exp $
 
  ********************************************************************/
 
@@ -39,8 +39,6 @@ typedef struct {
   int  n[2];
 
   vorbis_info_floor0 *vi;
-  lpc_lookup lpclook;
-  float *lsp_look;
 
   long bits;
   long frames;
@@ -68,8 +66,6 @@ static void floor0_free_look(vorbis_look_floor *i){
 
       _ogg_free(look->linearmap);
     }
-    if(look->lsp_look)_ogg_free(look->lsp_look);
-    lpc_clear(&look->lpclook);
     memset(look,0,sizeof(*look));
     _ogg_free(look);
   }
@@ -154,15 +150,8 @@ static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
   look->ln=info->barkmap;
   look->vi=info;
 
-  if(vd->analysisp)
-    lpc_init(&look->lpclook,look->ln,look->m);
-
   look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
 
-  look->lsp_look=_ogg_malloc(look->ln*sizeof(*look->lsp_look));
-  for(j=0;j<look->ln;j++)
-    look->lsp_look[j]=2*cos(M_PI/look->ln*j);
-
   return look;
 }
 
index d74e72e..cb41d2d 100644 (file)
--- a/lib/lpc.c
+++ b/lib/lpc.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: LPC low level routines
-  last mod: $Id: lpc.c,v 1.35 2002/07/11 06:40:49 xiphmont Exp $
+  last mod: $Id: lpc.c,v 1.36 2003/03/07 09:13:30 xiphmont Exp $
 
  ********************************************************************/
 
@@ -58,17 +58,17 @@ Carsten Bormann
 /* Input : n elements of time doamin data
    Output: m lpc coefficients, excitation energy */
 
-float vorbis_lpc_from_data(float *data,float *lpc,int n,int m){
-  float *aut=alloca(sizeof(*aut)*(m+1));
-  float error;
+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;
   int i,j;
 
   /* autocorrelation, p+1 lag coefficients */
-
   j=m+1;
   while(j--){
     double d=0; /* double needed for accumulator depth */
-    for(i=j;i<n;i++)d+=data[i]*data[i-j];
+    for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
     aut[j]=d;
   }
   
@@ -77,7 +77,7 @@ float vorbis_lpc_from_data(float *data,float *lpc,int n,int m){
   error=aut[0];
   
   for(i=0;i<m;i++){
-    float r= -aut[i+1];
+    double r= -aut[i+1];
 
     if(error==0){
       memset(lpc,0,m*sizeof(*lpc));
@@ -96,75 +96,24 @@ float vorbis_lpc_from_data(float *data,float *lpc,int n,int m){
     
     lpc[i]=r;
     for(j=0;j<i/2;j++){
-      float tmp=lpc[j];
+      double tmp=lpc[j];
+
       lpc[j]+=r*lpc[i-1-j];
       lpc[i-1-j]+=r*tmp;
     }
     if(i%2)lpc[j]+=lpc[j]*r;
-    
+
     error*=1.f-r*r;
   }
-  
+
+  for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
+
   /* we need the error value to know how big an impulse to hit the
      filter with later */
   
   return error;
 }
 
-/* Input : n element envelope spectral curve
-   Output: m lpc coefficients, excitation energy */
-
-float vorbis_lpc_from_curve(float *curve,float *lpc,lpc_lookup *l){
-  int n=l->ln;
-  int m=l->m;
-  float *work=alloca(sizeof(*work)*(n+n));
-  float fscale=.5f/n;
-  int i,j;
-  
-  /* input is a real curve. make it complex-real */
-  /* This mixes phase, but the LPC generation doesn't care. */
-  for(i=0;i<n;i++){
-    work[i*2]=curve[i]*fscale;
-    work[i*2+1]=0;
-  }
-  work[n*2-1]=curve[n-1]*fscale;
-  
-  n*=2;
-  drft_backward(&l->fft,work);
-
-  /* The autocorrelation will not be circular.  Shift, else we lose
-     most of the power in the edges. */
-  
-  for(i=0,j=n/2;i<n/2;){
-    float temp=work[i];
-    work[i++]=work[j];
-    work[j++]=temp;
-  }
-  
-  /* we *could* shave speed here by skimping on the edges (thus
-     speeding up the autocorrelation in vorbis_lpc_from_data) but we
-     don't right now. */
-
-  return(vorbis_lpc_from_data(work,lpc,n,m));
-}
-
-void lpc_init(lpc_lookup *l,long mapped, int m){
-  memset(l,0,sizeof(*l));
-
-  l->ln=mapped;
-  l->m=m;
-
-  /* we cheat decoding the LPC spectrum via FFTs */  
-  drft_init(&l->fft,mapped*2);
-
-}
-
-void lpc_clear(lpc_lookup *l){
-  if(l){
-    drft_clear(&l->fft);
-  }
-}
-
 void vorbis_lpc_predict(float *coeff,float *prime,int m,
                      float *data,long n){
 
index 366226a..4f49e81 100644 (file)
--- a/lib/lpc.h
+++ b/lib/lpc.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: LPC low level routines
-  last mod: $Id: lpc.h,v 1.19 2002/07/11 06:40:49 xiphmont Exp $
+  last mod: $Id: lpc.h,v 1.20 2003/03/07 09:13:30 xiphmont Exp $
 
  ********************************************************************/
 
 #define _V_LPC_H_
 
 #include "vorbis/codec.h"
-#include "smallft.h"
-
-typedef struct lpclook{
-  /* en/decode lookups */
-  drft_lookup fft;
-
-  int ln;
-  int m;
-
-} lpc_lookup;
-
-extern void lpc_init(lpc_lookup *l,long mapped, int m);
-extern void lpc_clear(lpc_lookup *l);
 
 /* simple linear scale LPC code */
 extern float vorbis_lpc_from_data(float *data,float *lpc,int n,int m);
-extern float vorbis_lpc_from_curve(float *curve,float *lpc,lpc_lookup *l);
 
 extern void vorbis_lpc_predict(float *coeff,float *prime,int m,
                               float *data,long n);