Cannot make a delay that doesn't feedback


#1

In the juce plugin demo I found this piece:

template <typename FloatType>
void JuceDemoPluginAudioProcessor::applyDelay (AudioBuffer<FloatType>& buffer, AudioBuffer<FloatType>& delayBuffer)
{
    const int numSamples = buffer.getNumSamples();
    const float delayLevel = *delayParam;

    int delayPos = 0;

    for (int channel = 0; channel < getTotalNumInputChannels(); ++channel)
    {
        FloatType* const channelData = buffer.getWritePointer (channel);
        FloatType* const delayData = delayBuffer.getWritePointer (jmin (channel, delayBuffer.getNumChannels() - 1));
        delayPos = delayPosition;

        for (int i = 0; i < numSamples; ++i)
        {
            const FloatType in = channelData[i];
            channelData[i] += delayData[delayPos];
            delayData[delayPos] = (/*delayData[delayPos] +*/ in) * delayLevel;

            if (++delayPos >= delayBuffer.getNumSamples())
                delayPos = 0;
        }
    }

    delayPosition = delayPos;
}

So of course, when delayData[delayPos] is commented out like above, only one delay 'tap' will sound, with zero feedback.

But when I implemented my own starter delay plugin, and used almost the exact same code:

float DelayProtoAudioProcessor::linixp(float a, float b, float x)
{
    return a + (b - a)*x;
}

void DelayProtoAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& /*midiMessages*/)
{
    const int numSamples = buffer.getNumSamples();
    const float delayLevel = intparams[Balance];
    int countertmp = 0;

    for (int channel = 0; channel < getTotalNumInputChannels(); channel++)
    {
        float* const channelData = buffer.getWritePointer (channel);
        float* const delayData = ringbuffer2.getWritePointer (jmin (channel, ringbuffer2.getNumChannels() - 1));
        countertmp = counter;

        for (int i = 0; i < numSamples; i++)
        {
            const float in = channelData[i];
            channelData[i] += delayData[countertmp];
            delayData[countertmp] = in * delayLevel;

            if (++countertmp >= ringbuffer2.getNumSamples())
                countertmp = 0;
        }
    }

    counter = countertmp;
}

No matter what I do, mess around with parameters et cetera, it will keep having feedback. The weird thing is, the feedback does decay, even though I haven't specified anything of the sort (feeding back nor applying gain). What's going on? How can I further analyse this? I have tried step debugging, it seems to not add anything to the delay ring buffer. I must be doing something very obviously wrong, ha. I started out with a real ringbuffer implementation, where the delay time is not always the exact length of the buffer. I have drawn the signal flow out. I'm exhausted out of ideas.. how could this code possibly render a decaying, feeding back, delay?


#2

Could it be that you have less channels in your ringbuffer than your buffer? If you had two channels on the buffer and only one on the ringBuffer and the two signals on the buffer were identical then I can imagine that would result in feedback.


#3

As soon as you post it on a forum.. it's gonna be alright. Not sure what happened here though. I now tested within a host instead of Juce Plugin Host..