Added Timothy Wood's bark_noise_median() optimization patch
authorMonty <xiphmont@xiph.org>
Tue, 30 Jan 2001 23:40:33 +0000 (23:40 +0000)
committerMonty <xiphmont@xiph.org>
Tue, 30 Jan 2001 23:40:33 +0000 (23:40 +0000)
Correction to 8kHz 40dB tone masking curve
Correction to ATH application in _vp_compute_mask; should have
  been tied to local amplitude maximum, not global.

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

lib/masking.h
lib/psy.c

index 2935800..9c4acaf 100644 (file)
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: masking curve data for psychoacoustics
- last mod: $Id: masking.h,v 1.9 2001/01/22 01:38:25 xiphmont Exp $
+ last mod: $Id: masking.h,v 1.10 2001/01/30 23:40:33 xiphmont Exp $
 
  ********************************************************************/
 
@@ -167,27 +167,28 @@ float tone_4000_100dB_SL[EHMER_MAX]={
  -37,-900,-900,-900,-900,-900,-900,-900,  -900,-900,-900,-900,-900,-900,-900,-900,
 -900,-900,-900,-900,-900,-900,-900,-900};
 
+
 float tone_8000_40dB_SL[EHMER_MAX]={
--900,-900,-900,-900,-900,-900,-900, -50,   -41, -30, -21, -12,   0,   3,  10,  18,
-  23,  20,  16,  15,  16,  18,  21,  23,    25,  27,  29,  32,  35,  38,  41,  44,
-  47,  50,  55,  60,  85,-900,-900,-900,  -900,-900,-900,-900,-900,-900,-900,-900,
-  -900,-900,-900,-900,-900,-900,-900,-900};
+-900,-900,-900,-900,-900,-900,-900,-900,   -40, -30, -21, -12,   0,   3,  10,  18,
+  24,  21,  14,   5,   0,  0,   5,   10,    15,  25,  30,  45,  50,  55,  60,  65,
+  70,  75,  80,  85,  90, 95, 100,  100,  -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
 float tone_8000_60dB_SL[EHMER_MAX]={
 -900,-900,-900,-900,-900,-900,-900, -10,   -21, -18, -14, -10,   0,  3,   15,  30,
-  43,  40,  36,  35,  36,  38,  41,  43,    45,  47,  49,  52,  55,  58,  61,  64,
-  67,  70,  75,  80,-900,-900,-900,-900,  -900,-900,-900,-900,-900,-900,-900,-900,
--900,-900,-900,-900,-900,-900,-900,-900};
+  43,  40,  36,  35,  36,  38,  41,  43,    45,  47,  50,  55,  60,  65,  70,  75,
+  80,  85,  90,  95, 100, 100, 100, 100,  -900,-900,-900,-900,-900,-900,-900,-900,
+  -900,-900,-900,-900,-900,-900,-900,-900};
 float tone_8000_80dB_SL[EHMER_MAX]={
 -900,-900,-900,-900,-900,-900,-900, -10,    -1,   2,   6,  10,  13,  19,  25,  35,
   63,  55,  50,  48,  46,  45,  45,  50,    55,  65,  75,  80,  85,  90,  95,  100,
  100, 100, 100, 100,-900,-900,-900,-900,  -900,-900,-900,-900,-900,-900,-900,-900,
--900,-900,-900,-900,-900,-900,-900,-900};
-
+ -900,-900,-900,-900,-900,-900,-900,-900};
 float tone_8000_100dB_SL[EHMER_MAX]={
  -18, -12,  -7,  -3,   0,   2,   6,   9,    12,  19,  22,  21,  19,  21,  40,  40,
-  80,  60,  35,  25,  15,   5,   5,   5,    25,  30,  35,- 40,  45,  50,  55,  60,
-  65,  70,  80,  90, 100,-900,-900,-900,  -900,-900,-900,-900,-900,-900,-900,-900,
--900,-900,-900,-900,-900,-900,-900,-900};
+  80,  60,  35,  25,  15,   5,   5,   5,    25,  30,  35,  43,  50,  55,  60,  65,
+  70,  75,  80,  85,  90,  95, 100, 100,  -900,-900,-900,-900,-900,-900,-900,-900,
+  -900,-900,-900,-900,-900,-900,-900,-900};
+
 
 #if 0 /* not used for the time being */
 float noise_500_60dB_SL[EHMER_MAX]={
index 5a50541..529e01f 100644 (file)
--- a/lib/psy.c
+++ b/lib/psy.c
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: psychoacoustics not including preecho
- last mod: $Id: psy.c,v 1.36 2001/01/22 06:32:02 xiphmont Exp $
+ last mod: $Id: psy.c,v 1.37 2001/01/30 23:40:33 xiphmont Exp $
 
  ********************************************************************/
 
@@ -532,35 +532,47 @@ static void max_seeds(vorbis_look_psy *p,float *minseed,float *maxseed,
   
 }
 
-#define BIN(x) ((int)((x)*-4.))
-#define BINdB(x) ((x)*-.25)
+/* quarter-dB bins */
+#define BIN(x)   ((int)((x)*negFour))
+#define BINdB(x) ((x)*negQuarter)
+#define BINCOUNT (200*4)
+#define LASTBIN  (BINCOUNT-1)
+
 static void bark_noise_median(long n,float *b,float *f,float *noise,
                              float lowidth,float hiwidth,
                              int lomin,int himin,
                              float *thresh,float *off){
   long i=0,lo=0,hi=0;
-  long *radix=alloca(200*4*sizeof(long)); /* quarter-dB bins */
+  float bi,threshi;
+  long median=LASTBIN;
+  float negFour = -4.0f;
+  float negQuarter = -0.25f;
+
+   /* these are really integral values, but we store them in floats to
+      avoid excessive float/int conversions, which GCC and MSVC are
+      farily poor at optimizing. */
 
-  long countabove=0;
-  long median=200*4-1;
-  long countbelow=0;
+  float radix[BINCOUNT];
+  float countabove=0;
+  float countbelow=0;
 
-  memset(radix,0,200*4*sizeof(long));
+  memset(radix,0,sizeof(radix));
 
   for(i=0;i<n;i++){
     /* find new lo/hi */
-    for(;hi<n && (b[hi]<=b[i]+hiwidth || hi<i+himin);hi++){
+    bi=b[i];
+    for(;hi<n && (hi<i+himin || b[hi]<=bi+hiwidth);hi++){
       int bin=BIN(f[hi]);
-      if(bin>=200*4)bin=200*4-1;
+      if(bin>LASTBIN)bin=LASTBIN;
       radix[bin]++;
       if(bin<median)
        countabove++;
       else
        countbelow++;
     }
-    for(;lo<i && b[lo]+lowidth<=b[i] && lo+lomin<i;lo++){
+    for(;lo<i && lo+lomin<i && b[lo]+lowidth<=bi;lo++){
       int bin=BIN(f[lo]);
-      if(bin>=200*4)bin=200*4-1;
+      if(bin>LASTBIN)bin=LASTBIN;
       radix[bin]--;
       if(bin<median)
        countabove--;
@@ -570,15 +582,16 @@ static void bark_noise_median(long n,float *b,float *f,float *noise,
 
     /* move the median if needed */
     if(countabove+countbelow){
+      threshi = thresh[i];
 
-      while(thresh[i]>countbelow/(float)(countabove+countbelow) && median>0){
+      while((countabove+countbelow)*threshi>countbelow && median>0){
        median--;
        countabove-=radix[median];
        countbelow+=radix[median];
       }
 
-      while(thresh[i]<(countbelow-radix[median])/
-           (float)(countabove+countbelow) && median+1<200*4){
+      while((countabove+countbelow)*thresh[i]<(countbelow-radix[median])
+           && median+1<BINCOUNT){
        countabove+=radix[median];
        countbelow-=radix[median];
        median++;
@@ -594,9 +607,9 @@ float _vp_compute_mask(vorbis_look_psy *p,
                      float *mdct, 
                      float *flr, 
                      float *decay,
-                     float prev_maxamp){
+                     float specmax){
   int i,n=p->n;
-  float specmax=NEGINF;
+  float localmax=NEGINF;
   static int seq=0;
 
   float *minseed=alloca(sizeof(float)*p->total_octave_lines);
@@ -606,9 +619,9 @@ float _vp_compute_mask(vorbis_look_psy *p,
   /* go to dB scale. Also find the highest peak so we know the limits */
   for(i=0;i<n;i++){
     fft[i]=todB(fft[i]);
-    if(fft[i]>specmax)specmax=fft[i];
+    if(fft[i]>localmax)localmax=fft[i];
   }
-  if(specmax<prev_maxamp)specmax=prev_maxamp;
+  if(specmax<localmax)specmax=localmax;
 
 
   for(i=0;i<n;i++){
@@ -636,9 +649,10 @@ float _vp_compute_mask(vorbis_look_psy *p,
     for(i=0;i<n;i++)flr[i]=NEGINF;
   }
 
-  /* set the ATH (floating below specmax by a specified att) */
+  /* set the ATH (floating below localmax, not global max by a
+     specified att) */
   if(p->vi->athp){
-    float att=specmax+p->vi->ath_adjatt;
+    float att=localmax+p->vi->ath_adjatt;
     if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
 
     for(i=0;i<n;i++){