[vorbis-dev] optimization to bark_noise_median()

Timothy J. Wood tjw at omnigroup.com
Sat Jan 27 05:21:22 PST 2001



  Could someone please try this version of bark_noise_median() on a x86 box?  On my PPC box, this runs about 1.85x as fast as the current version, making the encoding speed about 6.5% faster (at least on my test case).

  The basic idea is to (a) avoid needless float/int conversions and (b) use multiplies instead of divides.  I'm assuming (after having done some tests), that  'countabove+countbelow' is always non-negative.  If this isn't the case, that would cause problems.  The one other important point is putting -4.0 and -0.25 in stack registers since gcc on Mac OS X Public Beta is too stupid to do it itself and loads the constants inside loops.  Duh.  Hopefully this will be fixed with the final OS X which will have something 2.95 based.

  If this doesn't hurt performance on x86 or some other platform or have some other problem, could you please commit it?

  Thanks!

-tim

/* quarter-dB bins */
#define BIN(x)   ((int)((x)*negFour))
#define BINdB(x) ((x)*negQuarter)
#define BINCOUNT (200*4)
#define LASTBIN  (BINCOUNT-1)

tatic void bark_noise_median(long n,const float *b,const float *f,float *noise,
                              float lowidth,float hiwidth,
                              int lomin,int himin,
                              const float *thresh,const float *off){
  long i=0,lo=0,hi=0;
  float bi,threshi;
  long median=LASTBIN;
  float negFour = -4.0;
  float negQuarter = -0.25;
  
  /* these are really integral values, but we store them in floats to avoid excessive float/int conversions */
  float *radix=alloca(BINCOUNT*sizeof(*radix));
  float countabove=0;
  float countbelow=0;
  
  memset(radix,0,BINCOUNT*sizeof(*radix));

  for(i=0;i<n;i++){
    /* find new lo/hi */
    bi=b[i];
    for(;hi<n && (hi<i+himin || b[hi]<=bi+hiwidth);hi++){
      int bin=BIN(f[hi]);
      if(bin>LASTBIN)bin=LASTBIN;
      radix[bin]++;
      if(bin<median)
        countabove++;
      else
        countbelow++;
    }
    for(;lo<i && lo+lomin<i && b[lo]+lowidth<=bi;lo++){
      int bin=BIN(f[lo]);
      if(bin>LASTBIN)bin=LASTBIN;
      radix[bin]--;
      if(bin<median)
        countabove--;
      else
        countbelow--;
    }

    /* move the median if needed */
    /* we assume that countabove+countbelow > 0.0 to avoid a divide */
    if(countabove+countbelow){
      threshi = thresh[i];
      while((countabove+countbelow)*threshi>countbelow && median>0){
        median--;
        countabove-=radix[median];
        countbelow+=radix[median];
      }

      while((countabove+countbelow)*threshi<(countbelow-radix[median])
             && median+1<BINCOUNT){
        countabove+=radix[median];
        countbelow-=radix[median];
        median++;
      }
    }

    noise[i]=BINdB(median)+off[i];
  }
}

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the Vorbis-dev mailing list