How can I learn how to implement filters from scratch? (C++)

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

currently im building a basic waveshape synthesizer, only using JUCE to handle GUI and as a quick setup for the main audio processing loop, everything else is done by me - which is key, im mostly doing this as a learning experience. If I gave up and downloaded a fancy buttermilk filter library from github repository #9781 now I'd never forgive myself

I have everything else done mostly - midi handling, Oscillators, Envelopes, basic LFO modulation but I just cant wrap my head around filters. Ive watched a bunch of learning materials on FIR and IIR filter creation but everyone falls into one of three categories:
-Using mathematical expressions I cant even begin to understand (I never took calculus)
-The use of third party packages that take care of all the "heavy lifting"
-or in the case of this one guy I watched, he did an excellent job of explaining everything but did it in a general filter statement opposed describing how I'd make a specific filter (IE lowpass) with a cutoff frequency and how I'd use said filter

what I basically need help with is getting a hacky lowpass filter up and running in c++ to filter my 1's and -1's. I really struggle looking at mathematics and theories. The best way for me to learn a new concept is to get in and just do it while asking questions.

So, does anyone have any resources or some directions to point me in so I can take on this tremendous task? Ive tried in the past before but never got very far. All I know is you can define a filter shape with coefficients. I dont know how to use it in the context of taking say - my oscillator outputs. Ive vaguely researched the term "angular velocity" which seems to be a promising way of converting a cutoff frequency to something I can use in the context of a filter? Its like im learning how to program all over again :cry:

Post

There is a classic book on the subject, which comes up about once a year here in discussions about filters:
viewtopic.php?t=350246

Probably goes over your head on the first read, but try anyway, read all discussions here. There is a search function:
search.php?keywords=Filter&terms=all&au ... mit=Search
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post

This book https://www.dspguide.com can be read for free online (but read the PDFs not the HTML version) and explains filters in a very approachable fashion. Not too much math, lots of examples.
My audio programming blog: https://audiodev.blog

Post

thugsxmugs wrote: Mon Nov 04, 2024 1:18 am what I basically need help with is getting a hacky lowpass filter up and running in c++ to filter my 1's and -1's. I really struggle looking at mathematics and theories. The best way for me to learn a new concept is to get in and just do it while asking questions.
Filtering is one particular subject that I recommend that you copy/paste first. Then understand latter. I know this may sound like an evil and bad thing to say. But for most people (I mean the rest of us :)). You can't understand filtering in 2 weeks. You just can't. By the time you truly get your feet strong into making your own filters, you would probably have forgotten what you have coded in your synth. Which we know is not great for programming.

Copy some freely available working good code and use it. Modify it to your liking (thats not hard). Then slowly understand on the go as you read and experiment further and further.
www.solostuff.net
The 3rd law of thermo-dynamics states that: the 2nd law has two meanings, one of them is strictly wrong, the other is massively misunderstood.

Post

thugsxmugs wrote: Mon Nov 04, 2024 1:18 am So, does anyone have any resources or some directions to point me in so I can take on this tremendous task? Ive tried in the past before but never got very far. All I know is you can define a filter shape with coefficients. I dont know how to use it in the context of taking say - my oscillator outputs. Ive vaguely researched the term "angular velocity" which seems to be a promising way of converting a cutoff frequency to something I can use in the context of a filter? Its like im learning how to program all over again :cry:
In terms of using a filter in your synth, let's say a lowpass filter of some kind, your implemented filter will have a means to set sample rate, cutoff and Q. Sample rate only needs to be set in your JUCE prepareToPlay plugin method. Now, let's say you have your audio buffer full of your oscillator audio samples. You'll iterate over this buffer applying the filter to each sample and either overwriting it or putting it in a new processed output buffer. If your cutoff frequency parameter changes then it's common practice to update this in the filter every 8 or 16 samples to save CPU. It's important that your code doesn't reset the state of the filter when you change the cutoff or Q, just the coefficients used. And...you'll also need a separate filter with individual state for stereo left and right channels.

So, an interface might be something like:

setSampleRate - sets sample rate of the filter, recomputes coefficients accordingly.
reset - resets the state of the filter, for note on etc.
setCutoff - set the cutoff frequency of the filter commonly in hz. Call this every 8 or 16 samples.
setQ - set the Q of the filter. Call this every 8 or 16 samples.
process - apply the filter to a given sample. Call this for every audio sample generated by your oscillator.

That's the gist of how you'll end up using a filter in your synth code. If you wanted to get this working quickly, JUCE has a Moog style ladder filter you can quickly integrate.

If you're wanting to learn filters from scratch then it's going to take time and a lot of reading/research. No way around it. The links provided by other posters are a good start.

Post

thugsxmugs wrote: Mon Nov 04, 2024 1:18 am I have everything else done mostly - midi handling, Oscillators, Envelopes, basic LFO modulation but I just cant wrap my head around filters. Ive watched a bunch of learning materials on FIR and IIR filter creation but everyone falls into one of three categories:
-Using mathematical expressions I cant even begin to understand (I never took calculus)
-The use of third party packages that take care of all the "heavy lifting"
The basic way in which filters work is that we use a delays (digital) or "integrators" (capacitors/inductors in analog) to produce different phase-shifts at different frequencies. When we add versions of the signal with different phase-shifts, we'll get constructive and destructive interference depending on which frequencies are "in phase" or "out-of phase" due to the phase-shifts we caused.

Unfortunately, actually predicting these constructive and destructive interferences is something where you pretty much need to take your systems into the frequency domain by using Laplace- or z-transforms (for analog and digital respectively), which is why it seems as if every filter text directly jumps into the deep end of the pool... and even though in frequency domain the filter design becomes a "simple" matter of working out some complex rational functions, it's just the nature of the problem that the mathematics get quite nasty quite fast.

So it's basically a choice: do the math, or rely on someone else's work. That's just the nature of the problem.

Post

Start with one effect at a time with just one or two sliders then build up to a larger project . the juce dsp is not as fun as rolling your own .

This is a great book as well people here on the forum

https://www.native-instruments.com/file ... 60X4lYoyaO

Post

Part of iPlug tutorial:
https://www.martin-finke.de/articles/au ... 13-filter/

(though meanwhile it's iPlug2)

Post

thugsxmugs wrote: Mon Nov 04, 2024 1:18 amIf I gave up and downloaded a fancy buttermilk filter library from github repository #9781 now I'd never forgive myself [/i]
Where is that library? I have never heard of it. And what do you mean by "github repository #9781"? Are the repos enumerated somewhere?
what I basically need help with is getting a hacky lowpass filter up and running in c++ to filter my 1's and -1's.
Maybe the easiest way to get something up and running is to use these cookbook filters:

https://webaudio.github.io/Audio-EQ-Coo ... okbook.txt

You just need to implement Eq. 4 in code and the coefficients (b0,b1,b2,a0,a1,a2) can be computed using the formulas below (under LPF, HPF, etc.). That will give you a very basic 12 dB/oct multimode filter with adjustable resonance (via the "Q" parameter). It's nothing particularly good, though - especially with regard to modulation - but it is something "hacky" to get you started. It should be good enough for a "my very first filter" project. Starting from there, you can explore how to do it better.
I dont know how to use it in the context of taking say - my oscillator outputs.
Your oscillator output at sample instant n is the x[n] in Eq. 4 and x[n-1] and x[n-2] are the osc-outputs with 1 sample and 2 samples delay, respectively and y[n-1] and y[n-2] are the output samples of the filter delayed by 1 and 2 samples. You may want to keep these values around as "state" variables inside the filter object. Some sort of "getSample(double input)" function should implement Eq. 4 (the so called difference equation of the filter) and then update the stored state variables for the next call (which will occur at the next sample instant). Your filter output at sample instant n is y[n]. The formula computes it from the current input sample x[n], two delayed input samples x[n-1], x[n-2] and two delayed output samples y[n-1], y[n-2]. Such a filter is called a "biquad" and the second most basic filter structure (after the one-pole) that one should know about.
Last edited by Music Engineer on Tue Nov 05, 2024 4:49 pm, edited 2 times in total.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Music Engineer wrote: Tue Nov 05, 2024 12:30 pm Maybe the easiest way to get something up and running is to use these cookbook filters:

https://webaudio.github.io/Audio-EQ-Coo ... okbook.txt

You just need to implement Eq. 4 in code and the coefficients (b0,b1,b2,a0,a1,a2) can be computed using the formulas below (under LPF, HPF, etc.). That will give you a very basic 12 dB/oct multimode filter with adjustable resonance (via the "Q" parameter). It's nothing particularly good, though - especially with regard to modulation - but it is something "hacky" to get you started. It should be good enough for a "my very first filter" project. Starting from there, you can explore how to do it better.
I think recommending cookbook filters for "synth filter" is terrible advice (although full disclosure: my general hatred for direct form filters is probably quite well-known at this point), because the direct form biquads are terrible for modulation and really pretty much a "dead-end" as far as building something better goes. I'd much rather just recommend starting with "the Art of VA Filter Design" and perhaps trying to find some of the threads on this forum with examples of modern SK or SVF .. because all the cookbook filters will really do for you is give you a solution that doesn't really work for the purpose.

Post

Well, maybe I should have worded my caveats about the shortcomings of these filters more strongly. But it appeared to me that the OP asked for a quick and dirty ("hacky") solution and mentioned specifically that they really struggle with the math so I think pointing to "The Art of VA Filter Design" as starting point may appear quite daunting. Btw. - here it is:

https://www.discodsp.net/VAFilterDesign_2.1.2.pdf

Of course, I completely agree that this is the right way to do it, but I think, it should perhaps be one of the later and more advanced steps. As "starting point" for someone who struggles with math, this material seems to me a bit difficult to digest. I don't necessarily think that RBJ-cookbook filters are a dead-end road, though. They can be converted into SVF form later.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Music Engineer wrote: Tue Nov 05, 2024 4:21 pm I don't necessarily think that RBJ-cookbook filters are a dead-end road, though. They can be converted into SVF form later.
Or, you could just download this:

https://www.cytomic.com/files/dsp/SvfLi ... mised2.pdf

...and pretty much go to the last two pages for all the filter shape variable definitions and the tick function. Drop dead simple, none of the modulation woes.

Post

JustinJ wrote: Tue Nov 05, 2024 7:23 pm Or, you could just download this:

https://www.cytomic.com/files/dsp/SvfLi ... mised2.pdf

...and pretty much go to the last two pages for all the filter shape variable definitions and the tick function. Drop dead simple, none of the modulation woes.
Ah - OK - nice. Agreed. So, basically, that's the SVF cookbook then.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Music Engineer wrote: Tue Nov 05, 2024 8:11 pm
JustinJ wrote: Tue Nov 05, 2024 7:23 pm Or, you could just download this:

https://www.cytomic.com/files/dsp/SvfLi ... mised2.pdf

...and pretty much go to the last two pages for all the filter shape variable definitions and the tick function. Drop dead simple, none of the modulation woes.
Ah - OK - nice. Agreed. So, basically, that's the SVF cookbook then.
Pretty much. A slight variation is possible if you take the highpass directly from the solver as the "voltage" after the feedback sum, but before the first integrator, which then gives you HP, BP, LP directly as the basis (ie. without summing input). If one solves for the HP term, then BP and LP are simple to compute simply as feed-forward integrators.

The cool thing about this variation is that if you have an analog prototype (such as those given in the cookbook) of the form (a*s^2 + b*s + c)/(s^2 + s/Q + 1) then a,b,c give you the mixing gains for HP,BP,LP (respectively) directly. For a purely linear filter, it doesn't make a whole lot of difference either way (which one runs faster is basically a matter of phase of the moon), but I like this variation because (for better or worse) it gives you HP directly from inside the loop and once there's non-linearities (eg. Q limiting by additional BP feedback) the "inside the loop" HP can be a bit "better" (well, this is quite subjective, but point is the mismatch between input and "not quite linear" BP/LP can degrade the HP response) than the one derived from input.

Post

Here is a basic implementation of the Cytomic SVF in C++: https://gist.github.com/hollance/2891d8 ... f0e1e55c4b
My audio programming blog: https://audiodev.blog

Post Reply

Return to “DSP and Plugin Development”