[music-dsp] log scales to (and through) zero

Ross Bencina rbencina at iprimus.com.au
Sun Sep 28 17:56:00 EDT 2003

```Hi Laurent

Thanks for your clear explanation, this has really helped me. In the end I
decided to use your formula and use a curvature "as if" the minimum value
was  greater than zero by choosing a virtual minimum for calculating the
curvature.

Incidentally, assuming that the minimum is not zero, it seems that the
curvature (a) can be calculated as follows to get the equivalent of a log
scale:

numOctaves = log(max_val/ min_val) / log(2);
a = log(2) * numOctaves;

=>

a = log(max_val/ min_val)

Best wishes

Ross.

----- Original Message -----
From: "Laurent de Soras [Ohm Force]" <laurent.de.soras.m1 at club-internet.fr>
To: <music-dsp at aulos.calarts.edu>
Sent: Friday, September 26, 2003 6:05 PM
Subject: Re: [music-dsp] log scales to (and through) zero

>
> Ross Bencina wrote:
>
> >>f: [0 ; 1] -> [0 ; 1]
> >>          x -> (exp (a*x) - 1) / (exp (a) - 1)
> >
> > I think that's what I'm after, although I'm lacking clues as to how to
> > select the value of "a" - do you have a method for calculating it based
on
> > the output range? or do you just tweak it separately for each parameter
?
> >
> > For example, I'd like to use it to plot frequency with a constant number
of
> > pixels per octave.. which seems impossible if frequency goes to (or
thought)
> > zero...
>
> This function is intended to be quite similar to
> - f0(x) = a*x / (exp (a) - 1)
>    when x is close to 0 (linear behaviour)
> - f1(x) = exp (a*x) / exp (a)
>    when x is "not close" to 0 (exponential behaviour).
>
> Note: f1 becomes closer to f as a becomes big.
>
> For your concrete problem:
> - p is the number of pixels per octave
> - n is the number of octaves we want to fit in the display,
> if the furmula would not have to pass through 0. n has a
> direct impact on the calculation of a.
> f is actually the inverse of what you probably want, but the
> direct formula can be deduced easily. So we have:
>
> max_pix = n * p
> val (pix) = pow (2, pix / p)
> max_val = val (max_pix) = pow (2, n)
>
> We can compute f1, knowing that we have to scale the pixel
> position to [0 ; 1] and the result to [0 ; 1] in order to
> make f1 (1) = 1:
> f1 (pix) = val (pix) / max_val
>           = pow (2, pix / p) / pow (2, n)
> x (pix) = pix / max_pix
> so pix (x) = x * max_pix
> f1 (x) = pow (2, x * n) / pow (2, n)
>
> If you're not familiar with the exp and pow relationships,
> you'll be happy to know that pow (p, x) = exp (x * log (p))
>
> f1 (x) = exp (x * log (2) * n) / exp (n * log (2))
>
> We can deduce a, then f:
> a = log(2) * n
>
> And scale back:
> val (pix) = f (pix / max_pix) * max_val
>
> If we want the inverse of f:
> f_inv (y) = log (y * (exp (a) - 1) + 1) / a
>
> Therefore:
> pix (val) = f_inv (val / max_val) * max_pix
>
> > which returns me to my original question of whether to use piecewise
> > exp() with a linear segment from the lowest octave to zero.
>
> If you need *exact* exponential values excepted close to 0,
> exp + linear segment at 0 is the simplest solution.
>
> -- Laurent
>
> ==================================+========================
> Laurent de Soras                  |               Ohm Force
> DSP developer & Software designer |  Digital Audio Software
> http://ldesoras.free.fr           | http://www.ohmforce.com
> ==================================+========================
>
>
> dupswapdrop -- the music-dsp mailing list and website: subscription info,
FAQ, source code archive, list archive, book reviews, dsp links
http://shoko.calarts.edu/musicdsp/
> http://ceait.calarts.edu/mailman/listinfo/music-dsp

```