Some new preecho code; split energy threshholding up into a few bands.
authorMonty <xiphmont@xiph.org>
Thu, 15 Feb 2001 19:06:02 +0000 (19:06 +0000)
committerMonty <xiphmont@xiph.org>
Thu, 15 Feb 2001 19:06:02 +0000 (19:06 +0000)
Monty

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

12 files changed:
lib/block.c
lib/codec_internal.h
lib/envelope.c
lib/envelope.h
lib/iir.c
lib/iir.h
lib/modes/mode_A.h
lib/modes/mode_AA.h
lib/modes/mode_B.h
lib/modes/mode_C.h
lib/modes/mode_D.h
lib/modes/mode_E.h

index fe2cd19..e3dbc2d 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.44 2001/02/02 03:51:55 xiphmont Exp $
+ last mod: $Id: block.c,v 1.45 2001/02/15 19:05:45 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -493,7 +493,7 @@ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
       largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]/4;
     else
       /* min boundary; nW large, next small */
-      largebound=v->centerW+ci->blocksizes[1]*3/4+ci->blocksizes[0]*3/4;
+      largebound=v->centerW+ci->blocksizes[1]/2+ci->blocksizes[0]/2;
 
     bp=_ve_envelope_search(v,largebound);
     if(bp==-1)return(0); /* not enough data currently to search for a
index f0b0892..61420a3 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: libvorbis codec headers
- last mod: $Id: codec_internal.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: codec_internal.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $
 
  ********************************************************************/
 
@@ -110,8 +110,8 @@ typedef struct codec_setup_info {
   
   /* for block long/sort tuning; encode only */
   int       envelopesa;
-  float     preecho_thresh;
-  float     postecho_thresh;
+  float     preecho_thresh[4];
+  float     postecho_thresh[4];
   float     preecho_minenergy;
 
   float     ampmax_att_per_sec;
index b023992..05999c3 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.c,v 1.31 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: envelope.c,v 1.32 2001/02/15 19:05:45 xiphmont Exp $
 
  Preecho calculation.
 
 #include "envelope.h"
 #include "misc.h"
 
-/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
-   Command line: /www/usr/fisher/helpers/mkfilter -Ch \
-   -6.0000000000e+00 -Bp -o 5 -a 1.3605442177e-01 3.1746031746e-01 -l */
-
-#if 0
-static int    cheb_bandpass_stages=10;
-static float cheb_bandpass_gain=5.589612458e+01f;
-static float cheb_bandpass_B[]={-1.f,0.f,5.f,0.f,-10.f,0.f,
-                               10.f,0.f,-5.f,0.f,1f};
-static float cheb_bandpass_A[]={
-  -0.1917409386f,
-  0.0078657069f,
-  -0.7126903444f,
-  0.0266343467f,
-  -1.4047174730f,
-  0.0466964232f,
-  -1.9032773429f,
-  0.0451493360f,
-  -1.4471447397f,
-  0.0303413711f};
-#endif 
-
-/* 4kHz Chebyshev highpass */
-static int    cheb_highpass_stages=10;
-static float cheb_highpass_gain= 1.314337427e+01f;
-/* z^-stage, z^-stage+1... */
-static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f,
-                               -252.f,210.f,-120.f,45.f,-10.f,1.f};
-static float cheb_highpass_A[]={
-  -0.1013448254f,
-  0.4524819695f,
-  -1.3268091670f,
-  3.2875726855f,
-  -7.2782468961f,
-  13.0298867474f,
-  -17.6698599469f,
-  17.2757670409f,
-  -11.6207967046f,
-  4.8672119675f};
-
-#if 0
-/* 6kHz Chebyshev highpass */
-static int    cheb_highpass_stages=10;
-static float cheb_highpass_gain= 5.291963434e+01f;
-/* z^-stage, z^-stage+1... */
-static float cheb_highpass_B[]={1.f,-10.f,45.f,-120.f,210.f,
-                               -252.f,210.f,-120.f,45.f,-10.f,1.f};
-static float cheb_highpass_A[]={
-  -0.1247628029f,
-  0.1334086523f,
-  -0.3997715614f,
-  0.3213011089f,
-  -1.1131924119f,
-  1.7692446626f,
-  -3.6241199038f,
-  4.1950871291f,
-  -4.2771757867f,
-  2.3920318913f};
-#endif
+/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher */
+
+
+
+static int   cheb_highpass_stages=6;
+static float cheb_highpass_B[]={1.f,-6.f,15.f,-20.f,15.f,-6.f,1.f};
+
+static int   cheb_bandpass_stages=6;
+static float cheb_bandpass_B[]={-1.f,0.f,3.f,0.f,-3.f,0.f,1.f};
+
+
+/* 10kHz Chebyshev highpass */
+static float cheb_highpass10k_gain= 54.34519586f;
+static float cheb_highpass10k_A[]={
+  -0.2064797169f,
+  -0.5609713214f,
+  -1.1352465327f,
+  -1.4495555418f,
+  -1.7938140760f,
+  -0.9473564683f};
+
+/* 6kHz-10kHz Chebyshev bandpass */
+static float cheb_bandpass6k_gain=113.4643935f;
+static float cheb_bandpass6k_A[]={
+   -0.5712621337f,
+    1.5626130710f,
+   -3.3348854983f,
+    4.0471340821f,
+   -4.0051680331f,
+   2.2786325610f};
+
+/* 3kHz-6kHz Chebyshev bandpass */
+static float cheb_bandpass3k_gain= 248.8359377f;
+static float cheb_bandpass3k_A[]={
+     -0.6564230022f,
+      3.3747911257f,
+     -8.0098635981f,
+     11.0040876874f,
+     -9.2250963484f,
+      4.4760355389f};
+
+/* 1.5kHz-3kHz Chebyshev bandpass */
+static float cheb_bandpass1k_gain= 1798.537183f;
+static float cheb_bandpass1k_A[]={
+     -0.8097527363f,
+      4.7725742682f,
+    -11.9800219408f,
+     16.3770336223f,
+    -12.8553129536f,
+     5.4948074309f};
+
 
 void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
   codec_setup_info *ci=vi->codec_setup;
@@ -97,31 +89,35 @@ void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){
   int i;
   e->winlength=window;
   e->minenergy=fromdB(ci->preecho_minenergy);
-  e->iir=_ogg_calloc(ch,sizeof(IIR_state));
-  e->filtered=_ogg_calloc(ch,sizeof(float *));
+  e->iir=_ogg_calloc(ch*4,sizeof(IIR_state));
+  e->filtered=_ogg_calloc(ch*4,sizeof(float *));
   e->ch=ch;
   e->storage=128;
-  for(i=0;i<ch;i++){
-    IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass_gain,
-            cheb_highpass_A,cheb_highpass_B);
+  for(i=0;i<ch*4;i+=4){
+
+    IIR_init(e->iir+i,cheb_highpass_stages,cheb_highpass10k_gain,
+            cheb_highpass10k_A,cheb_highpass_B);
+    IIR_init(e->iir+i+1,cheb_bandpass_stages,cheb_bandpass6k_gain,
+            cheb_bandpass6k_A,cheb_bandpass_B);
+    IIR_init(e->iir+i+2,cheb_bandpass_stages,cheb_bandpass3k_gain,
+            cheb_bandpass3k_A,cheb_bandpass_B);
+    IIR_init(e->iir+i+3,cheb_bandpass_stages,cheb_bandpass1k_gain,
+            cheb_bandpass1k_A,cheb_bandpass_B);
+
     e->filtered[i]=_ogg_calloc(e->storage,sizeof(float));
+    e->filtered[i+1]=_ogg_calloc(e->storage,sizeof(float));
+    e->filtered[i+2]=_ogg_calloc(e->storage,sizeof(float));
+    e->filtered[i+3]=_ogg_calloc(e->storage,sizeof(float));
   }
 
-  drft_init(&e->drft,window);
-  e->window=_ogg_malloc(e->winlength*sizeof(float));
-  /* We just use a straight sin(x) window for this */
-  for(i=0;i<e->winlength;i++)
-    e->window[i]=sin((i+.5)/e->winlength*M_PI);
 }
 
 void _ve_envelope_clear(envelope_lookup *e){
   int i;
-  for(i=0;i<e->ch;i++){
+  for(i=0;i<e->ch*4;i++){
     IIR_clear((e->iir+i));
     _ogg_free(e->filtered[i]);
   }
-  drft_clear(&e->drft);
-  _ogg_free(e->window);
   _ogg_free(e->filtered);
   _ogg_free(e->iir);
   memset(e,0,sizeof(envelope_lookup));
@@ -156,52 +152,58 @@ static float _ve_deltai(envelope_lookup *ve,float *pre,float *post){
   return(B-A);
 }
 
-static float _ve_ampi(envelope_lookup *ve,float *pre){
-  long n=ve->winlength;
-
-  long i;
-
-  /* we want to have a 'minimum bar' for energy, else we're just
-     basing blocks on quantization noise that outweighs the signal
-     itself (for low power signals) */
-
-  float min=ve->minenergy;
-  float A=min*min*n;
-
-  for(i=0;i<n;i++){
-    A+=pre[i]*pre[i];
-  }
-
-  A=todB(A);
-  return(A);
-}
-
 long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
   vorbis_info *vi=v->vi;
   codec_setup_info *ci=vi->codec_setup;
   envelope_lookup *ve=((backend_lookup_state *)(v->backend_state))->ve;
-  long i,j,k;
+  long i,j,k,l;
   float *work=alloca(sizeof(float)*ve->winlength*2);
+  static int seq=0;
 
   /* make sure we have enough storage to match the PCM */
   if(v->pcm_storage>ve->storage){
     ve->storage=v->pcm_storage;
-    for(i=0;i<ve->ch;i++)
+    for(i=0;i<ve->ch*4;i++)
       ve->filtered[i]=_ogg_realloc(ve->filtered[i],ve->storage*sizeof(float));
   }
 
   /* catch up the highpass to match the pcm */
   for(i=0;i<ve->ch;i++){
-    float *filtered=ve->filtered[i];
     float *pcm=v->pcm[i];
-    IIR_state *iir=ve->iir+i;
+    float *filtered0=ve->filtered[i*4];
+    float *filtered1=ve->filtered[i*4+1];
+    float *filtered2=ve->filtered[i*4+2];
+    float *filtered3=ve->filtered[i*4+3];
+    IIR_state *iir0=ve->iir+i*4;
+    IIR_state *iir1=ve->iir+i*4+1;
+    IIR_state *iir2=ve->iir+i*4+2;
+    IIR_state *iir3=ve->iir+i*4+3;
     int flag=1;
     
     for(j=ve->current;j<v->pcm_current;j++){
-      filtered[j]=IIR_filter(iir,pcm[j]);
+      filtered0[j]=IIR_filter(iir0,pcm[j]);
+      filtered1[j]=IIR_filter(iir1,pcm[j]);
+      filtered2[j]=IIR_filter(iir2,pcm[j]);
+      filtered3[j]=IIR_filter(iir3,pcm[j]);
       if(pcm[j])flag=0;
     }
-    if(flag && ve->current+64<v->pcm_current)IIR_reset(iir);
+    if(flag && ve->current+64<v->pcm_current){
+      IIR_reset(iir0);
+      IIR_reset(iir1);
+      IIR_reset(iir2);
+      IIR_reset(iir3);
+    }
+
+    _analysis_output("pcm",seq,pcm+v->centerW,v->pcm_current-v->centerW,0,0);
+    _analysis_output("f0",seq,filtered0+v->centerW,v->pcm_current-v->centerW,
+                    0,0);
+    _analysis_output("f1",seq,filtered1+v->centerW,v->pcm_current-v->centerW,
+                    0,0);
+    _analysis_output("f2",seq,filtered2+v->centerW,v->pcm_current-v->centerW,
+                    0,0);
+    _analysis_output("f3",seq++,filtered3+v->centerW,v->pcm_current-v->centerW,
+                    0,0);
+
   }
 
   ve->current=v->pcm_current;
@@ -215,44 +217,22 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
   
   while(j+ve->winlength<=v->pcm_current){
     for(i=0;i<ve->ch;i++){
-      float *filtered=ve->filtered[i]+j;
-      float m=_ve_deltai(ve,filtered-ve->winlength,filtered);
-      
-      if(m>ci->preecho_thresh){
-       /*granulepos++;*/
-       return(0);
-      }
-      if(m<ci->postecho_thresh){
-       /*granulepos++;*/
-       return(0);
-      }
-      /*granulepos++;*/
-    }
-
-    /* look also for preecho in coupled channel pairs with the center
-       subtracted out (A-B) */
-    for(i=1;i<ve->ch;i+=2){
-      float *filteredA=ve->filtered[i-1]+j-ve->winlength;
-      float *filteredB=ve->filtered[i]+j-ve->winlength;
-      float m;
-
-      for(k=0;k<ve->winlength*2;k++)
-       work[k]=filteredA[k]-filteredB[k];
-
-      m=_ve_deltai(ve,work,work+ve->winlength);
+      for(k=0;k<4;k++){
+       float *filtered=ve->filtered[i*4+k]+j;
+       float m=_ve_deltai(ve,filtered-ve->winlength,filtered);
       
-      if(m>ci->preecho_thresh){
-       /*granulepos++;*/
-       return(0);
-      }
-      if(m<ci->postecho_thresh){
+       if(m>ci->preecho_thresh[k]){
+         /*granulepos++;*/
+         return(0);
+       }
+       if(m<ci->postecho_thresh[k]){
+         /*granulepos++;*/
+         return(0);
+       }
        /*granulepos++;*/
-       return(0);
       }
-      /*granulepos++;*/
     }
 
-
     j+=min(ci->blocksizes[0],ve->winlength)/2;
 
     if(j>=searchpoint){
@@ -265,7 +245,7 @@ long _ve_envelope_search(vorbis_dsp_state *v,long searchpoint){
 
 void _ve_envelope_shift(envelope_lookup *e,long shift){
   int i;
-  for(i=0;i<e->ch;i++)
+  for(i=0;i<e->ch*4;i++)
     memmove(e->filtered[i],e->filtered[i]+shift,(e->current-shift)*
            sizeof(float));
   e->current-=shift;
index cfb0ca5..c889ca5 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data envelope analysis and manipulation
- last mod: $Id: envelope.h,v 1.12 2001/02/02 03:51:56 xiphmont Exp $
+ last mod: $Id: envelope.h,v 1.13 2001/02/15 19:05:45 xiphmont Exp $
 
  ********************************************************************/
 
@@ -31,11 +31,10 @@ typedef struct {
 
   IIR_state *iir;
   float    **filtered;
+
   long storage;
   long current;
 
-  drft_lookup drft;
-  float *window;
 } envelope_lookup;
 
 extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi);
index ecf03d8..9d55d91 100644 (file)
--- a/lib/iir.c
+++ b/lib/iir.c
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: Direct Form I, II IIR filters, plus some specializations
-  last mod: $Id: iir.c,v 1.7 2001/02/02 03:51:56 xiphmont Exp $
+  last mod: $Id: iir.c,v 1.8 2001/02/15 19:05:45 xiphmont Exp $
 
  ********************************************************************/
 
@@ -69,8 +69,8 @@ float IIR_filter(IIR_state *s,float in){
 }
 
 /* this assumes the symmetrical structure of the feed-forward stage of
-   a Chebyshev bandpass to save multiplies */
-float IIR_filter_ChebBand(IIR_state *s,float in){
+   a typical bandpass to save multiplies */
+float IIR_filter_Band(IIR_state *s,float in){
   int stages=s->stages,i;
   float newA;
   float newB=0;
index 1fab188..c220f2c 100644 (file)
--- a/lib/iir.h
+++ b/lib/iir.h
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: Direct Form I, II IIR filters, plus some specializations
-  last mod: $Id: iir.h,v 1.5 2001/02/02 03:51:56 xiphmont Exp $
+  last mod: $Id: iir.h,v 1.6 2001/02/15 19:05:45 xiphmont Exp $
 
  ********************************************************************/
 
@@ -30,7 +30,7 @@ typedef struct {
 extern void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B);
 extern void IIR_clear(IIR_state *s);
 extern float IIR_filter(IIR_state *s,float in);
-extern float IIR_filter_ChebBand(IIR_state *s,float in);
+extern float IIR_filter_Band(IIR_state *s,float in);
 extern void IIR_reset(IIR_state *s);
 
 #endif
index 0f1b868..d2682d4 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_A.h,v 1.11 2001/02/02 03:52:24 xiphmont Exp $
+ last mod: $Id: mode_A.h,v 1.12 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -310,8 +310,9 @@ codec_setup_info info_A={
   },
   /* psy */
   {&_psy_set_A0,&_psy_set_A},
+
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 20.f, -26.f, -96.f,
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -10., 
 
index 233d1cc..c400abd 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_AA.h,v 1.7 2001/02/02 03:52:25 xiphmont Exp $
+ last mod: $Id: mode_AA.h,v 1.8 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -240,7 +240,7 @@ static vorbis_info_floor0 _floor_set0AA={9, 44100,  64, 10,130, 2, {0,1},
                                         0.246f, .387f};
 static vorbis_info_floor0 _floor_set1AA={30, 44100, 256, 12,150, 2, {2,3}, 
                                         .082f, .126f};
-static vorbis_info_residue0 _residue_set0AA={0,64,16,6,4,
+static vorbis_info_residue0 _residue_set0AA={0,192,16,6,4,
                                            {0,1,1,1,1,1},
                                            {6,7,8,9,10},
                                            
@@ -269,7 +269,7 @@ static vorbis_info_mode _mode_set1AA={1,0,0,1};
 codec_setup_info info_AA={
 
   /* smallblock, largeblock */
-  {256, 2048}, 
+  {512, 2048}, 
   /* modes,maps,times,floors,residues,books,psys */
   2,          2,    1,     2,       2,   20,   2,
   /* modes */
@@ -311,7 +311,7 @@ codec_setup_info info_AA={
   /* psy */
   {&_psy_set_AA0,&_psy_set_AA},
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 24.f, -28.f, -96.f,
+  256, {30.f,30.f,30.f,34.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -10., 
 
index 76aa778..6870936 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_B.h,v 1.10 2001/02/02 03:52:25 xiphmont Exp $
+ last mod: $Id: mode_B.h,v 1.11 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -311,7 +311,7 @@ codec_setup_info info_B={
   /* psy */
   {&_psy_set_B0,&_psy_set_B},
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 20.f, -24.f, -96.f,
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -10., 
 
index 7843e6c..23c4e5c 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_C.h,v 1.9 2001/02/02 03:52:25 xiphmont Exp $
+ last mod: $Id: mode_C.h,v 1.10 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -311,7 +311,7 @@ codec_setup_info info_C={
   /* psy */
   {&_psy_set_C0,&_psy_set_C},
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 20.f, -20.f, -96.f,
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -15., 
 
index 7578fbe..443aebb 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_D.h,v 1.10 2001/02/02 03:52:25 xiphmont Exp $
+ last mod: $Id: mode_D.h,v 1.11 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -308,7 +308,7 @@ codec_setup_info info_D={
   /* psy */
   {&_psy_set_D0,&_psy_set_D},
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 18.f, -18.f, -96.f,
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -15., 
 
index ec6c479..b7cfa95 100644 (file)
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: predefined encoding modes
- last mod: $Id: mode_E.h,v 1.8 2001/02/02 03:52:25 xiphmont Exp $
+ last mod: $Id: mode_E.h,v 1.9 2001/02/15 19:06:02 xiphmont Exp $
 
  ********************************************************************/
 
@@ -306,7 +306,7 @@ codec_setup_info info_E={
   /* psy */
   {&_psy_set_E0,&_psy_set_E},
   /* thresh sample period, preecho clamp trigger threshhold, range, minenergy */
-  256, 18.f, -18.f, -96.f,
+  256, {26.f,26.f,26.f,30.f}, {-90.f,-90.f,-90.f,-90.f}, -90.f,
 
   -15.,