Convolution plugin audiobuffer problems

Hi there! This is my first post and it’s my first week coding Juce (or anything C at all), so excuse me if it is too obvious.

I’m making a binaural convolution plugin, meaning I have to do two stereo convolutions in parallel and then merge them into the main buffer.

For the moment I have this in ProcessBlock:

juce::AudioProcessor::setLatencySamples (4096);
buffer.applyGain(0.85f);
const auto BLength = buffer.getNumSamples();

bufferL.copyFrom(0, 0, buffer, 0, 0, BLength);
bufferL.copyFrom(1, 0, buffer, 0, 0, BLength);
bufferR.copyFrom(0, 0, buffer, 1, 0, BLength);
bufferR.copyFrom(1, 0, buffer, 1, 0, BLength);

juce::dsp::AudioBlock<float> blockL (bufferL);
juce::dsp::AudioBlock<float> blockR (bufferR);
convL.process (juce::dsp::ProcessContextReplacing<float> (blockL) );
convR.process (juce::dsp::ProcessContextReplacing<float> (blockR) );

bufferF.copyFrom(0, 0, bufferL, 0, 0, BLength);
bufferF.copyFrom(1, 0, bufferL, 1, 0, BLength);
bufferF.addFrom(0, 0, bufferR, 0, 0, BLength);
bufferF.addFrom(1, 0, bufferR, 1, 0, BLength);

for(int sample=0; sample < buffer.getNumSamples(); ++sample)
{
    for(int channel=0; channel<buffer.getNumChannels(); ++channel)
    {
        float* channelData = buffer.getWritePointer(channel);
        const float* outData = bufferF.getReadPointer(channel);
        channelData[sample] = outData[sample];
    }
}

It works nice in DAWs like Studio One and Reaper, but if I try to load it into Rogue Amoeba’s SoundSource, terrible sounds happen, like some feedback clipping the channels. If I bypass the convolution it works (with no processing of course). What I am missing?

Many thanks!

I tried using DryWetMixer to mix to buffer without creating a loop. It still makes the same error, clipping like crazy. There is something crashing by mixing the two convolutions… any tips?

juce::AudioProcessor::setLatencySamples (4096);
const auto BLength = buffer.getNumSamples();

//buffer copy to bufferL
bufferL.copyFrom(0, 0, buffer, 0, 0, BLength);
bufferL.copyFrom(1, 0, buffer, 0, 0, BLength);

//buffer channel L = R
buffer.copyFrom(0, 0, buffer, 1, 0, BLength);

mixer.setWetMixProportion(0.5);
mixer.setWetLatency (convR.getLatency()-convL.getLatency());

//conv L
juce::dsp::AudioBlock<float> blockL (bufferL);
juce::dsp::ProcessContextReplacing<float> context1 (blockL);
convL.process (context1);
mixer.pushDrySamples(context1.getOutputBlock());

//conv R in the buffer
juce::dsp::AudioBlock<float> blockR (buffer);
juce::dsp::ProcessContextReplacing<float> context2 (blockR);
convR.process (context2);

//mixing both to buffer and breaking something in some plugin hosts :(
mixer.mixWetSamples(context2.getOutputBlock());

Hi There,

Some things to check in case you still have these problems:

Call prepare(spec) to the convolvers and mixer, and resize the aux buffers (I believe you have buffer L and R) correspondingly in prepareToPlay also.

Hope it helps, greetings from Uruguay

1 Like

¡Hola Joaquin!

Thanks for taking your time to answer. My prepareToPlay is as follows:

juce::dsp::ProcessSpec spec;
spec.maximumBlockSize = samplesPerBlock;
spec.sampleRate = sampleRate;
spec.numChannels = 2;

bufferL.setSize(2, samplesPerBlock);
bufferR.setSize(2, samplesPerBlock);

convL.reset();
convR.reset();
mixer.reset();

convL.prepare (spec);
convR.prepare (spec);
mixer.prepare (spec);

convL.loadImpulseResponse (BinaryData::asL_wav,//LR!
                           BinaryData::asL_wavSize,
                           juce::dsp::Convolution::Stereo::yes,
                           juce::dsp::Convolution::Trim::no,
                           0,
                           juce::dsp::Convolution::Normalise::no);
convR.loadImpulseResponse (BinaryData::asR_wav, //LR!
                           BinaryData::asR_wavSize,
                           juce::dsp::Convolution::Stereo::yes,
                           juce::dsp::Convolution::Trim::no,
                           0,
                           juce::dsp::Convolution::Normalise::no);

I was already preparing and resizing. Correctly, I think.
I’m still getting the same results, and stopped trying - the plug is working under Reaper, but crashing SoundSource and not loading in Logic.

My only new discover is that the problem is when I mix the convolutions: if I process them but don’t mix, it’s ok. If I mix two buffers (not convoluted), it’s ok. But if I mix two convolutions - by using DryWetMixer or a loop summing the convolution buffers, it crashes.

I couldn’t code the ProcessorChain as you tipped in the other topic, because I could only understand some code using the PluginProcessor and PluginEditor structure. I’m too newbie for that, and gave up :grimacing:

Thanks again and keep safe on your side of the frontera! Cheers from Brazil!

Hi Paulo,

Try resizing your auxiliary buffers inside processBlock
method (just after you apply the 0.85f gain). You are correctly setting its size in prepare to play, but the size could be nonconstant between the differents calls to process.


int numChannels = 1;
int numSamples = buffer.getNumSamples();

bufferL.setSize(numChannels,numSamples,false,false,true);
bufferR.setSize(numChannels,numSamples,false,false,true);

Include that bools options to avoid realocating.

Hope it helps.

Regards.

1 Like

Hi Joaquin,

You just made me not giving up on coding :sweat_smile:

Thanks a lot, it worked like a charm - from your code, I only had to change the numChannels to 2 - both convolutions are stereo.

Best regards and cheers again from Brazil!

Hi Paulo,

Great to hear that! It’s a pleasure to help when I can.

Saudações!

1 Like