How to use IIR filter sample by sample?

Hi there! I followed the audio programmer’s tutorial about building an IIR filter. I found that he used “ProcessorDuplicator”, which can’t be processed sample by sample in the for loop of processBlock. It’s a noob question but can anyone help me thanks!

The reason why I want to use the IIR filter in the for loops is that I have a dry wet mix knob. And the mix control is in the for loop of my process block. I want to control the mix after I do filtering.

Instead of using the ProcessorDuplicator, you could use multiple instances of the filters. (Put them in an array.) It’s going to be a bit annoying to manage those manually in the code but if you really need the sample by sample processing, I don’t think there’s currently any other way.

Sorry, I don’t understand what do you mean by “use multiple instances of the filters”? Do you mean I create a filter and its coefficients separately and put them into an array? I don’t know how to link the filter and its coefficients. I think when I use ProcessorDuplicator, they just link each other automatically, is that correct?

Yes, the purpose of the ProcessorDuplicator is to hold multiple instances of mono processors so they can be used for stereo (or more channels) processing and link the parameters. If you can’t use the duplicator, you will need to do all that yourself.

Also I’ m thinking about is there another way to control the dry wet mix after filtering. There’s a solution I come up with but I don’t know if that’s doable. First I store the clean signal in the first for loop like this

float *cleanSignal = new float[buffer.getNumSamples()];
for (int channel = 0; channel < totalNumInputChannels; ++channel)
{
    for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
    {
        cleanSignal[sample] = channelData[sample]
        // do something
    }
}

Then I add the filter like this

dsp::AudioBlock<float> block (buffer);
filterIIR.process(dsp::ProcessContextReplacing<float>(block));
updateFilter();

And I add another for loop to control the mix

for (int channel = 0; channel < totalNumInputChannels; ++channel)
{
    auto* channelData = buffer.getWritePointer(channel);
    for (int sample = 0; sample < buffer.getNumSamples(); ++sample)
    {
        channelData[sample] = (1.f - mix) * cleanSignal[sample] + mix * channelData[sample];
    }
}

This should work I guess, just looks kinda dumb to have two for loops, lol.

You should not allocate the helper buffer in the processBlock method. Your code also appears to be leaking it. You should instead have it as a member variable of your AudioProcessor subclass. Also instead of a raw float* buffer, use an AudioBuffer. Preallocate the AudioBuffer in the prepareToPlay method with the “expected samples” size that is passed into the method.

Ah I see! Thanks for your suggestion!