Chaining JUCE made VSTs with filters


#1

Hello,

I made a simple distortion effect plugin that contains a high-pass filter (juce::IIRFilter) which is always active with a default cutoff of 20Hz (the cutoff value is controlled through the GUI).

When I load an instance of my plugin in my VST host, everything works fine. However, if I load another instance of the same plugin in the host (even in another mixer channel), the output sound of the two plugins get crackling and noisy

This problem happens in Ableton as well as FL Studio (I don't have other hosts to test it though).

If I remove the high-pass processing code part (the call to "processSamples()"), then the output is clean so the issue has te be related to the filters I use.

I'm pretty new to VST development and I don't know if it's related to thread management or maybe there's something missing in my filters setup...I hope you guys will be able to give me some hints.

Thank you for you help !


#2

Hi there,

unfortunately I can't see any way to tell you what's wrong without having your code here. Maybe you have some global or static variables in your plugin — then both instances are trying to access the same variable, resulting in garbage values?


#3

Here's a sample of code of my PluginProcessor.cpp file

std::vector<juce::IIRFilter*> hpfilters; //where could I store my filters if not as a global variable?

void DStortiumAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    for(int c = 0; c < getNumInputChannels();++c) { //new filter for each channel
        hpfilters.push_back(new juce::IIRFilter());
    }
    setHPFilterCutoff(UserParams[HPF]); //default 20Hz
}


void DStortiumAudioProcessor::setHPFilterCutoff(float cutoff)
{
    for (std::vector<juce::IIRFilter*>::iterator it = hpfilters.begin() ; it != hpfilters.end(); ++it) {
        (*it)->setCoefficients(juce::IIRCoefficients::makeHighPass(getSampleRate(),cutoff));
    }
}

void DStortiumAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    long numSamples = buffer.getNumSamples();

     for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i)
           buffer.clear (i, 0, numSamples);
    
    for(int c = 0; c < getNumInputChannels();++c)
    {
        float* data = buffer.getWritePointer(c);


        //+ processing stuff...


        hpfilters[c]->processSamples(data,numSamples);


        //+ other processing stuff...

    }
}


#4

Finally got it working, I just moved the "hpfilters" variable to a private section of the header file instead of having it in the .cpp, beginner mistake here.

Thank you for your help timur!


#5

You might also want to avoid pushing back new filters each time prepareToPlay is called! It's not necessarily called only once by the host. (Maybe you are deleting the filters and clearing the vector in your releaseResources, but that might not be so optimal either...) You should check if you already have the needed number of filters in the vector and if not, then create them.


#6

Indeed! I didn't know it could be called several times. Thanks for feedback