DSP module IIR Filter causing low freq noise

Hi all,

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:

Header:
dsp::IIR::Filter<float> lowShelfLeft;

Constructor:
lowShelfLeft(dsp::IIR::Coefficients<float>::makeLowShelf(44100, 100, 0.5f, 0.5f))

PrepareToPlay:
dsp::ProcessSpec spec;
spec.sampleRate = sampleRate;
spec.maximumBlockSize = samplesPerBlock;
spec.numChannels = getTotalNumOutputChannels();

lowShelfLeft.prepare(spec);
lowShelfLeft.reset();

ProcessBlock:
dsp::AudioBlock<float> block (buffer);
process(dsp::ProcessContextReplacing<float>(block));

Process:
lowShelfLeft.process(context);

Any input would be appreciated. Thanks!

No replies so far…
I am sure the filters in Juce are not this bad, so I am probably just making some rookie mistake. Anyone care to point me in the right direction? Thanks.

If I understand your image correctly, the noise is somewhere in the -175dB range, which isn’t audible. Is there some practical reason why you are concerned about that?

Thanks for your reply. In my image the purple is the unfiltered signal, and the light green is the filtered signal. So the noise is actually somewhere in the -100dB range where it does matter.

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.

I don’t know about your application but are you sure -100dB matters? If I would have to guess, I’d say the problem simply comes down to rounding errors with floating point -> quantization noise.

You could check it by switching to double, or look at it in python or Matlab.

Even if it didn’t matter I would still like to understand what’s going on :slight_smile: 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?

Thanks for helping out!

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.