dsp::FIR::Filter::process does not work, but processSample does

I have a lowpass filter like:

juce::dsp::FIR::Filter<float> lowpass;
auto coefficients = juce::dsp::FilterDesign<float>::designFIRLowpassTransitionMethod(cutoffFrequency,reader->sampleRate,  filterOrder,0.01f, 4.0f);
lowpass.coefficients = *coefficients;

Processing samples manually works fine, but when I try using “process”, it doesn’t work:

Doesn’t work:

 juce::dsp::AudioBlock<float> block(audioBuffer);
                 juce::dsp::ProcessContextReplacing<float> context(block);
                 lowpass.reset();
                 lowpass.prepare(juce::dsp::ProcessSpec{.sampleRate = static_cast<double>(sampleRate), .maximumBlockSize = static_cast<juce::uint32>(bufferSampleSize), .numChannels = static_cast<juce::uint32>(numChannels)});
                    lowpass.process(context);

Works:

                for (int i = 0; i < audioBuffer.getNumSamples(); i++){
                    for(int c=0; c<numChannels; c++){
                    audioBuffer.setSample(c, i, lowpass.processSample(audioBuffer.getSample(c,i)));
                    }
                }

What am I doing wrong? processSample works when I manually process every sample in every channel, but for some reason calling process on my audio buffer using ProcessContextReplacing doesn’t work (the audio is unchanged). Any ideas?

That’s weird because process() essentially just does that loop that calls processSample().

Does it work OK when you move the calls to lowpass.reset() and lowpass.prepare(...) into prepareToPlay rather than in processBlock?

Unfortunately not. I’ve tried moving around the reset and prepare functions, switching the order of them, removing one of them, etc. and no combination seems to get process to work at all.

Ah, after looking at the source code (JUCE/modules/juce_dsp/processors /juce_FIRFilter.h) I found the comment: “This class can only process mono signals. Use the ProcessorDuplicator class”.

After using a ProcessorDuplicator for my 2 channel audio, it works now.

juce::dsp::ProcessorDuplicator<juce::dsp::FIR::Filter<float>, juce::dsp::FIR::Coefficients<float>> filterDuplicator(coefficients.get());