[LAD] Mixing audio: Noiseless volume changes

Fons Adriaensen fons at linuxaudio.org
Tue Mar 19 13:02:35 UTC 2013

On Tue, Mar 19, 2013 at 04:26:21AM +0100, Tim Goetze wrote:
> A 2nd-order IIR filter is often called a "biquad"; at musicdsp, look
> for that instead. 

Not really. A biquad is one way to implement a 2nd order IIR, and
in many cases related to audio DSP, not really the best way.

Anyway, using a biquad for something so simple is giant overkill.

The code below will do the trick. The filter is
very slightly underdamped so it will reach its
target value faster.

// Init time calculation of constants:

constant float T = 0.05f;    // 50 milliseconds
float w, a, b;
w = 10.0f / (FS * t);        // FS = sample rate
a = 0.07f;                   // Controls damping
b = 1.0f / (1.0f - a);

// For each gain control:

float gt;       // gain set by user, i.e. in steps.
float g1, g2;   // filter state

gt = g1 = g2 = 0;

// You need some counter + logic to check how
// long ago the value gt was last changed.
// No high precision is required, just counting
// periods will do. The only purpose is to skip
// the filter calculation when it is not really
// required - when the output is close enough to
// its target value. With the values above, T
// seconds after the last input change the gain
// will be within 1/1000 dB of the requested
// value. 

// If gt has not changed for at least the time T,
// just use gt:

for (i = 0; i < nframes; i++)
    out [i] = gt * in [i];

// Else run the filter:

for (i = 0; i < nframes; i++)
    g1 += w * (gt - g1 - a * g2);
    g2 += w * (b * g1 - g2);
    out [i] = g2 * in [i];

// You could also run the filter all the time, in
// that case you may need denormal protection:

    g1 += w * (gt - g1 - a * g2 - 1e-20f);
    g2 += w * (b * g1 - g2 + 1e-20f);



A world of exhaustive, reliable metadata would be an utopia.
It's also a pipe-dream, founded on self-delusion, nerd hubris
and hysterically inflated market opportunities. (Cory Doctorow)

More information about the Linux-audio-dev mailing list