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

# Rockbox mail archive

Subject: Re: berzerk peak meter? Alpha testers wanted.
Date: 2002-09-24

Okay this code was tested under mingwin et Dev-C++ and it works : it
computes log2(x) where x is a 16-bit integer and result is a 16.16
fixedpoint integer.

I will try a log(x) another time.

----------8<---------
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

static unsigned short log2_table;

/* you'd better to get the values and fill the table at compile-time */
void generate_log2_table (void)
{
int i;
for(i=0;i<16;i++)
log2_table[i]=(unsigned
short)(65536.0*log(1.0+(((double)i)/16.0))/log(2.0));
}

#if 0
/* test code : it works */
double _log2 (unsigned short x)
{
unsigned i = 15; /* integer part */
unsigned j; /* fractional part */

if (!x)
return 0;

if (x < (1<<8)) {
x <<= 8;
i -= 8;
}
if (x < (1<<12)) {
x <<= 4;
i -= 4;
}
if (x < (1<<14)) {
x <<= 2;
i -= 2;
}
if (x < (1<<15)) {
x <<= 1;
i -= 1;
}

x <<= 1;

j = x >> 12;

return /* integer part */ i
+ /* fractional part */ (log2_table[j] + (65536.0 * (x & 0xfff) *
(log2_table[j+1] - log2_table[j]))) / 65536.0;
}
#endif

/* IN: 16-bit integer
OUT: 32-bit integer as a fixedpoint 16.16-bit integer */
int fflog2 (unsigned short x)
{
unsigned i = 15; /* integer part */
unsigned j; /* fractional part */

if (!x)
return 0;

if (x < (1<<8)) {
x <<= 8;
i -= 8;
}
if (x < (1<<12)) {
x <<= 4;
i -= 4;
}
if (x < (1<<14)) {
x <<= 2;
i -= 2;
}
if (x < (1<<15)) {
x <<= 1;
i -= 1;
}

x <<= 1;

j = x >> 12;

return /* integer part */ (i << 16)
| /* fractional part */ (log2_table[j] + (((x & 0xfff) << 16) *
(log2_table[j+1] - log2_table[j])));
}

int
main (int argc, char *argv[])
{
generate_log2_table();

// fflog2(72) should give us 6.16992
int res = fflog2((unsigned short)(1<<6)+(1<<3));

// cout << "log2(" << int((1<<6)+(1<<3)) << ") = " << _log2((unsigned
short)(1<<6)+(1<<3)) << endl;
cout << "log2(" << int((1<<6)+(1<<3)) << ") = " << double(res) / 65536.0
<< endl;

cout << "Press ENTER to continue..." << endl;
getchar ();
return 0;
}

----- Original Message -----
From: "Philipp Pertermann" <philipp.pertermann_at_web.de>
To: <rockbox_at_cool.haxx.se>
Sent: Monday, September 23, 2002 2:29 PM
Subject: Re: berzerk peak meter? Alpha testers wanted.

> From: "Andreas Stemmer" <Andreas.Stemmer_at_web.de>
> > While comparing your peak meter with the one from archos,
> I noticed that
> > the levels are slightly lower on your peak meter. Perhaps
> they calculate
> > the levels in a different way?
>
> Yes, the archos meter is logarithmic. I intend to make the
> meter in dbfs some day but there are other things first and
> I'm too stupid for the math. It means calculating logarithms
> using fix point data types. I've read a cookbook on that and
> didn't grasp a word.
>
> Phil
>