Rockbox.org home
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.
From: Paul Suade (paul.suade_at_laposte.net)
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[17];

/* 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
>



Page was last modified "Jan 10 2012" The Rockbox Crew
aaa