I’m using the dsp::IIR:Filter together with coefficients from IIRCoefficients. The filter seems to work and the frequency response looks as expected. However, I notice there is a lot of noise in the lower frequencies. See here. I’ve seen it with both the low shelf and peak filter, and it happens with both process() and processSample().
I’m a C++/JUCE newbie so I might be missing something obvious, but I’m also wondering if it could be quantization noise and if there’s anything I can do to avoid it. Here’s my code:
Could it be a problem with the audio channel counts? The Juce filters only process in mono, but you apparently pass in the plugin’s main buffer, which could be stereo or more channels, into the filter instance.
Even if it didn’t matter I would still like to understand what’s going on Quantization noise was also my first suspicion. I’m embarrassed to ask, but how would I switch to double when using the JUCE dsp IIR filter?
Looking at the source of juce_IRRFilter I see that it stores the state in an array of SampleType. This means there can be a recursive buildup of noise in the filters. This means the recursive filters lose a few bits of float precision depending on filter settings - which can easily result in -100dB noise.
In my opinion this is a design flaw of the class, it should always use double (or better the largest available floating point type) for the state and use 64 bit multiplications for the recursive part, even when processing 32 bit floats.
Using double SampleType would help with this, but then you’d have to use buffers with double samples which most of the time is a waste of space.
You will have to change each <float> to <double> in the filter itself, the coefficients, and the audioblock.
And then there’s the problem with the input signal: the processBlock method gives you only float data. So you might want to create your signal yourself, with double precision, because you can only get float in and out of your plug-in. However, for testing purposes it’s fine to do so. Make sure your analyzer is also within your plugin, as you can only get float’s out. Maybe writing it to wav will retain the double precision (with 64bit wav files). Not sure if JUCE supports it, though.
Admittedly, for some applications -100dB could be a problem, especially if there are some kind of gain stages or dynamic processing involved. As a stratocaster player with a high-gain pedal active, I am quite happy about my noise less single coil pickups
When it comes to IIR filters and resolution, the coefficients are very critical. Quantization of coefficients has to be taken into account when designing filters, as poles could be made unstable by rounding errors. And of course the state also plays a role in the stability game. As long the design ensures stability, and I very much assume it does in JUCE’s implementation, we are all good.