IIR FILTER + stereo operation

Hello fellow Jucers,
i want to create a HighPass - LowPass filter plugin using the IIR filter,
in my PluginProcessor.h i have included as private:
IIRFilter monoFilterHighP, monoFilterLowP;
and my PluginProcessor.cpp looks like this:

void DaBorderAudioProcessor::prepareToPlay(double newSampleRate, int /*samplesPerBlock*/)
{
	// Use this method as the place to do any pre-playback
	// initialisation that you need..
	sampleRate = newSampleRate;

	monoFilterHighP.setCoefficients(IIRCoefficients::makeHighPass(newSampleRate, *LPFREQParam, q));
	monoFilterLowP.setCoefficients(IIRCoefficients::makeLowPass(newSampleRate, *HPFREQParam, q));

	reset();
}

void DaBorderAudioProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
	auto totalNumInputChannels = getTotalNumInputChannels();
	auto totalNumOutputChannels = getTotalNumOutputChannels();


	for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
		buffer.clear(i, 0, buffer.getNumSamples());

	monoFilterHighP.setCoefficients(IIRCoefficients::makeHighPass(sampleRate, *LPFREQParam, q));
	monoFilterLowP.setCoefficients(IIRCoefficients::makeLowPass(sampleRate, *HPFREQParam, q));

	
	for (int channel = 0; channel < totalNumInputChannels; ++channel)
	{
		auto* channelData = buffer.getWritePointer(channel);

		monoFilterHighP.processSamples(channelData, buffer.getNumSamples());
		monoFilterLowP.processSamples(channelData, buffer.getNumSamples());
	}

} 

The problem is that i get some kind of unstable operation for the Hipass filter on the Right channel,
Any ideas?

You called your filter correctly monoFilterXY… but then you process both channels through the same filter instance…

Since the filters are stateful, you need an instance per channel…

1 Like

You need separate filter objects for each audio channel.

Many thanks!
i did the following:

PluginProcessor.h :
IIRFilter monoFilterHighPLeft, monoFilterLowPLeft , monoFilterHighPRight, monoFilterLowPRight;

PluginProcessor.cpp :

void DaBorderAudioProcessor::prepareToPlay(double newSampleRate, int /*samplesPerBlock*/)

monoFilterHighPLeft.setCoefficients(IIRCoefficients::makeHighPass(newSampleRate, *LPFREQParam, q));
	monoFilterLowPLeft.setCoefficients(IIRCoefficients::makeLowPass(newSampleRate, *HPFREQParam, q));
	monoFilterHighPRight.setCoefficients(IIRCoefficients::makeHighPass(newSampleRate, *LPFREQParam, q));
	monoFilterLowPRight.setCoefficients(IIRCoefficients::makeLowPass(newSampleRate, *HPFREQParam, q));


void DaBorderAudioProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
	auto totalNumInputChannels = getTotalNumInputChannels();
	auto totalNumOutputChannels = getTotalNumOutputChannels();


	for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
		buffer.clear(i, 0, buffer.getNumSamples());

	monoFilterHighPLeft.setCoefficients(IIRCoefficients::makeHighPass(sampleRate, *LPFREQParam, q));
	monoFilterLowPLeft.setCoefficients(IIRCoefficients::makeLowPass(sampleRate, *HPFREQParam, q));

	monoFilterHighPRight.setCoefficients(IIRCoefficients::makeHighPass(sampleRate, *LPFREQParam, q));
	monoFilterLowPRight.setCoefficients(IIRCoefficients::makeLowPass(sampleRate, *HPFREQParam, q));

	//float * channelDataL = buffer.getWritePointer(0);
	
	for (int channel = 0; channel < totalNumInputChannels; ++channel)
	{
		//auto* channelData = buffer.getWritePointer(channel);
		float *dataLeft = buffer.getWritePointer(0);
		float *dataRight = buffer.getWritePointer(1);

		monoFilterHighPLeft.processSamples(dataLeft, buffer.getNumSamples());
		monoFilterLowPLeft.processSamples(dataLeft, buffer.getNumSamples());

		monoFilterHighPRight.processSamples(dataRight, buffer.getNumSamples());
		monoFilterLowPRight.processSamples(dataRight, buffer.getNumSamples());
	}
} 

and i still have the same problem…

You no longer must have this loop in the code :

for (int channel = 0; channel < totalNumInputChannels; ++channel)
1 Like

Solved !!!
Many thanks!
Here is the code in case somebody is interested:

void DaBorderAudioProcessor::processBlock(AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
	auto totalNumInputChannels = getTotalNumInputChannels();
	auto totalNumOutputChannels = getTotalNumOutputChannels();


	for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
		buffer.clear(i, 0, buffer.getNumSamples());

	monoFilterHighPLeft.setCoefficients(IIRCoefficients::makeHighPass(sampleRate, *LPFREQParam, q));
	monoFilterLowPLeft.setCoefficients(IIRCoefficients::makeLowPass(sampleRate, *HPFREQParam, q));

	monoFilterHighPRight.setCoefficients(IIRCoefficients::makeHighPass(sampleRate, *LPFREQParam, q));
	monoFilterLowPRight.setCoefficients(IIRCoefficients::makeLowPass(sampleRate, *HPFREQParam, q));

	float *dataLeft = buffer.getWritePointer(0);
	float *dataRight = buffer.getWritePointer(1);

	monoFilterHighPLeft.processSamples(dataLeft, buffer.getNumSamples());
	monoFilterLowPLeft.processSamples(dataLeft, buffer.getNumSamples());

	monoFilterHighPRight.processSamples(dataRight, buffer.getNumSamples());
	monoFilterLowPRight.processSamples(dataRight, buffer.getNumSamples());

}