release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide

# Rockbox mail archive

Subject: Re: Log base 2
Date: 2002-09-20

----- Original Message -----
From: "Andreas Stemmer" <Andreas.Stemmer_at_web.de>
To: <rockbox_at_cool.haxx.se>
Sent: Friday, September 20, 2002 10:26 AM
Subject: RE: Log base 2

> > In order to convert a linear volume sample info into dBfs I
> > have to calculate:
> >
> > dBfs = 20 * log( sample / SAMPLE_RANGE)
> >
> > with log being the logarithmus base 10.
>
> That's no problem because of the rules for the loagrithm:
> log(x) base 10 = (log (x) base 2) / (log (10) base 2)
>
> Andreas
>

dBfs = 20 * ( log(sample) - log(SAMPLE_RANGE) )
= 20 * ( log2(sample) - log2(SAMPLE_RANGE) ) / ( log2(10) )

So you only need to compute log2(sample) (I suppose SAMPLE_RANGE is a
constant).

int log2(short x) {

unsigned int i = 8;
unsigned int j = x;

if (!x)
return 0;

// use an O(log2(n)) MSB bit scanner instead of an O(n) MSB bit scanner !
// very good for PC, but for SH1 you really should unroll it
while (j) {
if (j >= (1<<i)) {
j >>= i;
} else {
x <<= i;
}
i >>= 1;
}

x <<= 1;
j = x >> 12;

return log2_table[j]
+ ((x & 0xfff) * (log2_table[j+1] - log2_table[j])) >> 12;
}

SH1 has poor shift operations so you'd better use the following unrolled
code which should be far faster as O(log2(n)) MSB bit scanner :

...
if (j >= (1<<8))
j >>= 8;
else
x <<= 8;
if (j >= (1<<4))
j >>= 4;
else
x <<= 4;
if (j >= (1<<2))
j >>= 2;
else
x <<= 2;
if (j >= (1<<1))
j >>= 1;
else
x <<= 1;
if (j >= (1<<0))
;
else
x <<= 1;
...