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);
Ciao,
--
FA
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)