http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
//==============================
w0 = (2.0 * Math.PI * f0)/getSamplerate();
// alpha = sin(w0)/(2*Q) (case: Q)
double alpha = Math.sin(w0)/(2.0 * q0);
// the following are for a low pass filter
// b0 = (1 - cos(w0))/2
double b0 = (1.0 - Math.cos(w0))/2;
// b1 = 1 - cos(w0)
double b1 = 1.0 - Math.cos(w0);
// b2 = (1 - cos(w0))/2
double b2 = (1.0 - Math.cos(w0))/2;
// a0 = 1 + alpha;
double a0 = 1 + alpha;
// a1 = -2*cos(w0)
double a1 = -2.0 * Math.cos(w0);
// a2 = 1 - alpha
double a2 = 1 - alpha;
And here's the actual filter code (it's ElmGen Java, I'll intersperse Spin ASM between each line):
Assume that input, output, D0 and D1 are all assigned to reasonable registers.
Code: Select all
// sfxb.scaleOffset(0, 0);
SOF 0,0
// sfxb.readRegister(input, b2/a0);
RDAX input, b2/a0
// sfxb.readRegister(output, -a2/a0);
RDAX output, -a2/a0
// sfxb.writeRegister(d1,0);
WRAX d1, 0
// sfxb.readRegister(input, b1/a0);
RDAX input, b1/a0
// sfxb.readRegister(output, -a1/a0);
RDAX output, -a1/a0
// sfxb.readRegister(d1, 1.0);
RDAX d1, 1.0
// sfxb.writeRegister(d0,0);
WRAX d0, 0
// sfxb.readRegister(input, b0/a0);
RDAX input, b0/a0
// sfxb.readRegister(d0, 1.0);
RDAX d0, 1.0
// sfxb.writeRegister(output,0);
WRAX output, 0
The frequency adjustment seems to work fine. I can adjust Q over a range of 1 to 1000 and can't hear a dang bit of difference. ???
PS This is my attempt at a Direct Form II filter.
By the way what I am looking for is a resonant LPF like you would find on a synth. Maybe the BiQuad is not good for this? It seems OK for plain filtering but it's not very exciting
I did find the resonant LPF from the "disco" patches at the Spin web site, however the coefficients for most filter patches I find here are all "magic numbers" and I can't trace what people did to get them.