Subject: Re: [linux-audio-dev] gain curves, interpolation, etc.
From: Jack O'Quin (joq_AT_io.com)
Date: Thu Nov 30 2000 - 18:56:17 EET
Steve Harris <S.W.Harris_AT_ecs.soton.ac.uk> writes:
> This sounds a bit fiddly, and you really don't want to be exposing
> exponential curves to the user, it wants to look linear, but infact the
> gain would be exponential. When I'm fading I think of the action I make
> with a slider, which is more or less linear, but the gain curve is
> exponential (or something like that).
>
> Often you just want a short crossfade. Select a point in two tracks, hit
> crossfade and it fades around it. If it sounds nasty you make the fade
> a bit longer. Isn't this the stuff that ProTools makes really easy?
I agree. Because of the logarithmic response characteristics of the
human ear, we measure loudness in decibels, not watts or volts. So,
it makes sense to use exponential rather than linear crossfade curves.
That should probably be the default behavior, when an xfade occurs.
On Wed, Nov 29, 2000 at 01:52:28PM +0100, Jörn Nettingsmeier wrote:
> > i'm assuming here that linear interpolation between breakpoints is
> > easy enough on the cpu to allow this to be computed real-time during
> > playback without hogging too much power - i may be wrong.
Steve Harris <S.W.Harris_AT_ecs.soton.ac.uk> writes:
> 1st order interpolation is cheap, but causes dicontinuities in the 1st
> derivative, which are often audible. I don't know if theres a metric for
> telling if a given discontinuity will be audible or not, but I think the
> effect would be made worse by dynamics processing.
Thinking about these points, I wondered about doing "exponential
interpolation" similarly to linear interpolation. To illustrate,
here's a modification of Paul Sladen's recent example:
#define GRANULARITY 32
for(;;)
{
x = gain-function(t);
logx = log(x);
dx = exp((logx-lastx)/GRANULARITY);
for( i=0; i < GRANULARITY; i++)
*out++ = *in++ * (x *= dx); /* rather than (x += dx) */
t += GRANULARITY;
lastx = logx;
}
You get the idea. Please check my math, there may be some mistake.
But, I think the basic concept is correct. The outer loop and it's
initialization are left as an exercize... :-)
Interestingly, this algorithm appears to be *more* computationally
stable than the linear version (where x += dx). Basically, floating
point math handles multiplication better than addition. The variable
"dx" tends to be very close to 1.0. If the slope of this part of the
gain-function is rather flat, rounding error may reduce "dx" to
*exactly* 1.0. That is OK. Effectively, the interpolation then
degenerates into a "stairstep" curve with a new value computed every
GRANULARITY samples. That is pretty good, given the accuracy of the
values represented.
-- Jack O'Quin Austin, Texas, USA
This archive was generated by hypermail 2b28 : Thu Nov 30 2000 - 20:08:56 EET