Glitchy sound issue with IIR filter

Hi JUCE folks,

I’m developing a synth plugin based on sampling instrument. In my customized synthesiserVoice::renderNextBlock method, I put a low pass filter at the end. When I turn it off, the playback sound is fine. My problem is that when I turn the filter on, the output sound is glitchy instantly when noteOff occurs.

My code roughly looks like below:

cutoffFreq = 1000.0f;

dsp::IIR::Filter<float>::CoefficientsPtr cutoffCoefficients = dsp::IIR::Coefficients<float>::makeLowPass (getSampleRate(), cutoffFreq);

updateCoefficients (leftCutoff.coefficients, cutoffCoefficients);
updateCoefficients (rightCutoff.coefficients, cutoffCoefficients);

auto leftBlock = block.getSingleChannelBlock(0);
auto rightBlock = block.getSingleChannelBlock(1);

juce::dsp::ProcessContextReplacing<float> leftContext (leftBlock);
juce::dsp::ProcessContextReplacing<float> rightContext (rightBlock);

leftCutoff.process (leftContext);
rightCutoff.process (rightContext);

I tested my code with sine wave input. The glitchy sound at noteOff point looks like this:

It seems that some discontinuity happened at that particular point. Any idea on how to fix it? Thanks.


Just a shot in the dark, but what happens in that function, does clearing filter states introduce some disconuity? Do you update the filter coefficients with every block? If the cutoff frequency is fixed, it’s usually just fine to set the coefficients once in prepare and then leave them as they are.

And as a sidenote, you can use the juce::dsp::ProcessorDuplicator if you want a multichannel capable filter, then you don’t need the single channel blocks and separate context and filter instances etc. But this is not related to the issue that you are seeing

In the SynthesiserVoice rendering code, you are not supposed to replace the contents of the buffer passed in, which you are apparently doing at the moment. You need to sum the voice audio into the passed in buffer. You also need to properly take into account the startSample and numSamples arguments given for the renderNextBlock method.

Thanks, xenakios.

Your comments are very right. I just observed that when noteOff happens, the startSample with numSamples arguments only covers a portion of the output buffer. But I mistakenly processed the entire output buffer. That’s why the glitchy sound occurs all the time. I just changed the process method to processSample. The glitchy sound goes away now.

Thanks for your reply.

The cutoff frequency is actually controlled by some other UI inputs. For simplicity, I fixed it to a constant for demonstration.

Yeah I agree the juce::dsp::ProcessorDuplicator is a better way. I don’t need to write a lot of similar and low efficient code. I will definitely consider the change. Thanks for your advice again.