Issues with a plug in


#1

Hi guys, i’m fairly new to coding and JUCE and have come across an issue.
I’m starting off simple and trying to create a delay plug-in and it’s almost working but not quite. I’ve set up my 4 AudioParameterFloats and they communicate back and forth, I think the issue lies in my cicular buffer.
I’ve copied my prepareToPlay and processBlock functions as I think the issue is in one of them.

The signal is delayed when the plug in is tested however the delay length seems to have no effect. This is likely due to the read and write positions though. It also feeds back when the feedback is set to 0.

Any help would be massively appreciated.


#2

Some things I noticed:

I think you would rather want to cycle one buffer size instead of the delayLength:

if (delayReadPos < 0) 
    delayReadPos += delayBuffer.getNumSamples();

You are calculating that value at the beginning anyway, so this line can go, and you can define that value inside the scope

You initialise the value just to overwrite it in the next line. Not a biggie, but pointless…

But I think the real problem comes, that you increment your delayWritePos for each channel, so it will create a mess…
You should probably better have a local variable and update the persistent one after the loop:

const auto numSamples = buffer.getNumSamples();                      // Creating an integer for the number of samples in the buffer.

for (int channel = 0; channel < totalNumInputChannels; ++channel)       // Looping through the channels.
{
    float* channelData = buffer.getWritePointer(channel);               // Pointer to the incoming signal.
    float* delayData = delayBuffer.getWritePointer(channel);            // Pointer to the delay buffer.

    auto writePos = delayWritePos;
    auto readPos = writePos - static_cast<int> (((*delayLength) * getSampleRate()));
    if (readPos < 0)
        readPos += delayBuffer.getNumSamples();

    for (int i = 0; i < numSamples; ++i)                                // Cycling through the samples in the buffer.
    {
        const auto in = channelData[i];
        float out = (((*dryMix) * in) + ((*wetMix) * delayData [readPos]));

        delayData [writePos] = in + (delayData [readPos] * (*feedback)); // Writing the input plus any feedback into the delay buffer.
        channelData[i] = out;

        if (++readPos >= delayBufferLength)            //If the read position exceeds the size of the buffer it returns to 0, creating a circular buffer.
            readPos = 0;
        if (++writePos >= delayBufferLength)           //If the write position exceeds the size of the buffer it returns to 0, creating a circular buffer.
            writePos = 0;
    }
}
delayWritePos += numSamples;
if (delayWritePos > delayBuffer.getNumSamples())
    delayWritePos -= delayBuffer.getNumSamples();

I haven’t tested code…

Further reading for alternative methods:

AudioBuffer::copyFrom(): Copy many samples at once (and with less CPU cycles as well)
AbstractFifo: How to implement a circular buffer copying data block wise

It becomes a bit more tricky then, what to store to implement the feedback properly though…

HTH


#3

You sir are amazing! The main issue was the buffer resetting by a delay length and not a buffer length as well as the stereo for looping issues!
All working perfectly now!
Thanks so much for such good help!


#4

Lovely, glad it worked!