Resonant Low Pass Filter
PHX
Posts: 17
Hi,
I'm working on a waveform generator for a sound engine and would like to add a resonant low pass filter to it.
So far, I'm generating waveforms as unsigned 24bits integers (I'm using the same trick as the SID chip, with a phase accumulator to generate square, saw, ramp etc) at 48.1khz.
I found the following C function on www.musicdsp.org that looks straightforward.....in C !
Tdouble MoogVCF::run(double input, double fc, double res)
{
double f = fc * 1.16;
double fb = res * (1.0 - 0.15 * f * f);
input -= out4 * fb;
input *= 0.35013 * (f*f)*(f*f);
out1 = input + 0.3 * in1 + (1 - f) * out1; // Pole 1
in1 = input;
out2 = out1 + 0.3 * in2 + (1 - f) * out2; // Pole 2
in2 = out1;
out3 = out2 + 0.3 * in3 + (1 - f) * out3; // Pole 3
in3 = out2;
out4 = out3 + 0.3 * in4 + (1 - f) * out4; // Pole 4
in4 = out3;
return out4;
}
I'm struggling about how to implement this in assembly. Should I go with pseudo-real numbers, or with the exponent form (log/antilog table) ??
Thanks for your help !!
Richard
I'm working on a waveform generator for a sound engine and would like to add a resonant low pass filter to it.
So far, I'm generating waveforms as unsigned 24bits integers (I'm using the same trick as the SID chip, with a phase accumulator to generate square, saw, ramp etc) at 48.1khz.
I found the following C function on www.musicdsp.org that looks straightforward.....in C !
Tdouble MoogVCF::run(double input, double fc, double res)
{
double f = fc * 1.16;
double fb = res * (1.0 - 0.15 * f * f);
input -= out4 * fb;
input *= 0.35013 * (f*f)*(f*f);
out1 = input + 0.3 * in1 + (1 - f) * out1; // Pole 1
in1 = input;
out2 = out1 + 0.3 * in2 + (1 - f) * out2; // Pole 2
in2 = out1;
out3 = out2 + 0.3 * in3 + (1 - f) * out3; // Pole 3
in3 = out2;
out4 = out3 + 0.3 * in4 + (1 - f) * out4; // Pole 4
in4 = out3;
return out4;
}
I'm struggling about how to implement this in assembly. Should I go with pseudo-real numbers, or with the exponent form (log/antilog table) ??
Thanks for your help !!
Richard
Comments
I think the best way to go about that is to break the C-code into smaller parts and code them in ASM from that.
Although that code simulates the Moog's Voltage Controlled Filter (Moog's was very bassy and had a lot of punch to it, My Arp Odyssey's VCF always was more tinny sounding and sharp)... I think the SID's was different and had only one pole.
I got the mos6581 datasheet at home so I don't know if I'm 100% correct or not.
But from what I remember back in the day when I programmed on the c64, the filter only had one pole. So the code to simulate the C64's filter might be simpler.
--Andrew Arsenault
I do have the datasheet also, thanks for your proposal.
Yes, you're right, it's more advanced than the SID's one but sonically much more appealing :-D...so that's somehow more motivating.
Would you recommend pseudo-real (like 16bits integer-16bits decimal) or the exponent form using the log/antilog table ?
Tks,
Richard
SID has a 2pole filer.
I've never used the tables so I'd start with the integer design. I'm not saying it would be better though.
I havn't learn what is actally stored in those tables... other then the Boot-Rom and Sine-Rom.