dsp::IIR::Filter slope and max frequency issue

Hello,

I am quite new in filtering at all, so my questions are probably stupid. I have two issues with Juce dsp::IIR::Filter that I can’t find the solution. So I would like to ask for help.

LOW PASS FILTER SLOPE
My first issue is about low pass filter slope. By slope I mean 6 dB per octave or 12 dB per octave etc.

I use code like that:
dsp::IIR::Filter<float> myFilter;
And later in the code I call:
myFilter.coefficients = dsp::IIR::Coefficients<float>::makeLowPass(sampleRate, freq, paramQ);

But as you can see there is no slope parameter. So is there any way to achieve Low Pass Filter with 6db per octave or any other slopes?

MAX FREQUENCY OF LOW PASS FILTER
My second issue is about highest frequency of filter. In dsp::IIR::Coefficients::makeLowPass there is jassert that doesn’t allow me to set frequency that is higher than 0.5 * sample rate. And this is obvious for me due to Nyquist frequency. But in all plugins EQ which I know there are constant range of frequencies, no matter what sample rate I have chosen in my DAW. For example in Fabfilter Pro-Q3, the max frequency is 25kHz, while users often uses sample rate 44,1kHz or 48kHz which is still less than 2 * 25kHz. So how they solve situation if user set in DAW lower sample rate than 2*maxFilterFreq? Don’t you know how to solve that with Juce dsp::IIR::Filter?

For any help great thanks in advance.

Best Regards

Hey!

Checkout this free course by matcat music https://www.programmingformusicians.com/simpleeq/. I think in part 4 he shows how to setup filter of different orders (different slope).

Hey, great thanks. That course looks gorgeous. Thanks a lot

1 Like

Hmm, once again great thanks for that course. I found the slope subject. Unfortunately in the course there ara only 12, 24, 36 and 48 dB per octave, while I need 6dB. But that course inspired me to more experiments, and finally I found that 6dB per octave slope I can achieve with the:
dsp::IIR::Coefficients<float>::makeFirstOrderLowPass()

But still I have no idea how to keep max value of freq higher then 0.5 * sampleRate.

The Nyquist theorem says, that the highest frequency that can be reconstructed by a sampled signal is at 0.5 * sampleRate. So setting a filter frequency higher than that doesn’t work because these frequencies cannot even exist in the signal you are processing. But since that point is practically out of the audible range, what’s your use-case for keeping the value that high?

Hello PluginPengui,
Yes you are right about Nyquist freq, I wrote about it on the begining of my post. And this is not problem for me.

The problem is that many EQs I know have constant frequency range, sometimes much more above the popular sample rate 0.5 * 44,1kHz or 48kHz. For example in Fabfilter Pro-Q3 they have max freq 30kHz or 25kHz, not sure, but even for 25 kHz it is still higher than 0.5 * 48kHz. So I wonder how they handle it. And that’s the question. Or how to handle it with Juce dsp?

Of course before set new freq I can make if statement:

if(newFreq > 0.5 * getSampleRate())
    newFreq = 0.5 * getSampleRate()

Where getSampleRate() gives let’s say 44100. So my highest freq would be 22050Hz.

But on my slider the max value is still let’s say 25kHz. So it looks like it is cheat. Basicly not true.

Of course I could also change my slider range always the sampleRate is changed, but it is also not as I see it in other EQs.

That’s why I wonder how to solve that in proper way?

For any help great thanks in advance.
Best Regards

Ah I see, sorry for not reading the first post entirely.

My best guess is that they are either oversampling or that they are simply not reaching the target frequency, because it makes no sense. Our EQs are limited to a frequency range of 20Hz to 20kHz, and at least I haven’t heard of any customer feedback asking for a broader range over time.

Still, being a programer with solid understanding of filters but working together with some far more skilled dsp brains, I vaguely remember a discussion about various approaches when it comes to filter design when reaching the Nyquist frequency. So there might be a chance that there is some technique that I’m not into, allowing you to design cut filters with a frequency out of range, which transform to a stupid all-pass for higher frequencies. If so, I think the JUCE classes don’t use that approach. Maybe some others here have more insight :wink:

Thanks for your answer.
Yes I also think that oversampling is first bet to achieve that. But I decided to ask some more experienced developers.

And as I remember in Fabfilter oversampling is only option, but highest freq 25kHz is available no matter if you turn on oversampling or turn off. So that’s why it is still interesting issue for me.

So I will also try to ask similar question on Stack Exchange Signal Processing forum. If I know something new I will share it here.

Does setting the frequency to 25kHz produce different results compare to let’s say 22.05kHz when working @ 44.1kHz? If no, they will just clamp the value. And with results I am referring to the audio results, as for the GUI they can just use a higher sampling rate and calculate the frequency responses with that one.

1 Like

Hello Daniel, great thanks for your suggestion.
I think that finally you are right. My ears are not so perfect to hear differences in frequencies range about 17-20 kHz. But I create my EQ for professional audio engineers, and I don’t know what exactly they hear, so I try to be as accurate as I can.
So please find the chart I enclosed and my explanation:

This is the chart for two Equalisers, the red one is Fabfilter Pro-Q3 and the yellow one is mine EQ.
The sample rate is set to 44100Hz. And the both filters (mine and Fabfilter) are set to LPF 6dB per octave, and frequency is set to 3000Hz.
So as you can see my (yellow) EQ has 6dB per octave only to about 10kHz, but above it is much more. There are big difference between freq from about 10kHz to 20kHz. So it’s audible range. Both filters starting to look identical when I set frequencies about 700Hz or lower.
Let’s see it:

So I am pretty sure the differences for higher frequencies are because I don’t handle the frequencies above 0.5 * sample rate.

So there are two sides of coin :slight_smile:
At first the truth is what you said that frequencies above 0.5 * sampleRate are doesn’t matter.

But at second what you didn’t notice is that those frequencies also impact on lower frequencies when filtering.

That’s why I wonder how to achieve what I want, I mean LPF with real 6dB per octave. But now I have 6dB per octave for frequencies below 10kHz, but above it is much more per octave.

I guess the point of allowing frequencies higher than Nyquist is that you could set them for a higher rate, and the state should still be valid at the lower one. Anyway, the main difference here is how the analog filters are converted to digital. An analog filter has a frequency response from 0 to infinite Hz -you need to fit that into the 0…sr/2 digital range. Juce classes use the bilinear transform, which scales 0…inf to 0…sr/2 using a tan mapping. Another option is the impulse invariance method, which folds the infinite response over the finite range, as in aliasing. None of them match the analog response near Nyquist:

response

Blue is the analog response. The bilinear transform (green) falls to -inf at Nyquist, as the analog response would reach that at inf Hz. The impulse invariant (orange) is higher near Nyquist, because it adds all the foldovers.

Fabfilter is probably using some other method which renders a more exact match. They also have a method to match the phase response, with the “natural phase” mode. You won’t find their formulas so easily, they’re part of their selling point. You could look for papers on corrected impulse invariance methods, which is likely what they’re using. I don’t have anything about it, as I’m perfectly happy with my warped bilinear transformed filters =)

Hello Kamedin,
great thanks for your explanation. It is very interesting, and it looks like it is much more complicated than I thought. I will consider everything what you mention.

Best Regards