[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