Hi
I’m working on what I call a pan delay… the input signal is split into (say) 6 components, each of which then can have a separate delay time, pan in the stereo field, level and (if necessary) feedback.
I’ve only got as far as the delay part, but my code is not working as I expected. The level controls for the delay, only the last one is working. Any help would be much appreciated! (The code here only uses 3 components…)
void DelayAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
const double smoothTime = 1e-3;
paramDelayTime.reset (sampleRate, smoothTime);
paramFeedback.reset (sampleRate, smoothTime);
paramMix.reset (sampleRate, smoothTime);
paramDelayTime2.reset (sampleRate, smoothTime);
paramFeedback2.reset (sampleRate, smoothTime);
paramMix2.reset (sampleRate, smoothTime);
paramDelayTime3.reset (sampleRate, smoothTime);
paramFeedback3.reset (sampleRate, smoothTime);
paramMix3.reset (sampleRate, smoothTime);
//======================================
float maxDelayTime = paramDelayTime.maxValue;
delayBufferSamples = (int)(maxDelayTime * (float)sampleRate) + 1;
if (delayBufferSamples < 1)
delayBufferSamples = 1;
delayBufferChannels = getTotalNumInputChannels();
delayBuffer.setSize (delayBufferChannels, delayBufferSamples);
delayBuffer.clear();
delayWritePosition = 0;
float maxDelayTime2 = paramDelayTime2.maxValue;
delayBuffer2Samples = (int)(maxDelayTime2 * (float)sampleRate) + 1;
if (delayBuffer2Samples < 1)
delayBuffer2Samples = 1;
delayBuffer2Channels = getTotalNumInputChannels();
delayBuffer2.setSize (delayBuffer2Channels, delayBuffer2Samples);
delayBuffer2.clear();
delay2WritePosition = 0;
float maxDelayTime3 = paramDelayTime3.maxValue;
delayBuffer3Samples = (int)(maxDelayTime3 * (float)sampleRate) + 1;
if (delayBuffer3Samples < 1)
delayBuffer3Samples = 1;
delayBuffer3Channels = getTotalNumInputChannels();
delayBuffer3.setSize (delayBuffer3Channels, delayBuffer3Samples);
delayBuffer3.clear();
delay3WritePosition = 0;
}
void DelayAudioProcessor::releaseResources()
{
}
void DelayAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
ScopedNoDenormals noDenormals;
const int numInputChannels = getTotalNumInputChannels();
const int numOutputChannels = getTotalNumOutputChannels();
const int numSamples = buffer.getNumSamples();
//======================================
float currentDelayTime = paramDelayTime.getTargetValue() * (float)getSampleRate();
float currentDelay2Time = paramDelayTime2.getTargetValue() * (float)getSampleRate();
float currentDelay3Time = paramDelayTime3.getTargetValue() * (float)getSampleRate();
float currentFeedback = paramFeedback.getNextValue();
float currentFeedback2 = paramFeedback2.getNextValue();
float currentFeedback3 = paramFeedback3.getNextValue();
float currentMix = paramMix.getNextValue();
float currentMix2 = paramMix2.getNextValue();
float currentMix3 = paramMix3.getNextValue();
int localWritePosition, localWritePosition2, localWritePosition3;
for (int channel = 0; channel < numInputChannels; ++channel) {
float* channelData = buffer.getWritePointer (channel);
float* intermediateData = channelData;
float* intermediateData2 = channelData;
float* intermediateData3 = channelData;
float* finalData = channelData;
float* delayData = delayBuffer.getWritePointer (channel);
float* delay2Data = delayBuffer2.getWritePointer (channel);
float* delay3Data = delayBuffer3.getWritePointer (channel);
localWritePosition = delayWritePosition;
localWritePosition2 = delay2WritePosition;
localWritePosition3 = delay3WritePosition;
for (int sample = 0; sample < numSamples; ++sample) {
const float in = channelData[sample];
const float in2 = channelData[sample];
const float in3 = channelData[sample];
float out = 0.0f;
float out2 = 0.0f;
float out3 = 0.0f;
float readPosition =
fmodf ((float)localWritePosition - currentDelayTime + (float)delayBufferSamples, delayBufferSamples);
float readPosition2 =
fmodf ((float)localWritePosition2 - currentDelay2Time + (float)delayBuffer2Samples, delayBuffer2Samples);
float readPosition3 =
fmodf ((float)localWritePosition3 - currentDelay3Time + (float)delayBuffer3Samples, delayBuffer3Samples);
int localReadPosition = floorf (readPosition);
int localReadPosition2 = floorf (readPosition2);
int localReadPosition3 = floorf (readPosition3);
if (localReadPosition != localWritePosition) {
float fraction = readPosition - (float)localReadPosition;
float delayed1 = delayData[(localReadPosition + 0)];
float delayed2 = delayData[(localReadPosition + 1) % delayBufferSamples];
out = out + delayed1 + fraction * (delayed2 - delayed1);
intermediateData[sample] = in + currentMix * (out - in);
delayData[localWritePosition] = in + out * currentFeedback;
}
if (++localWritePosition >= delayBufferSamples)
localWritePosition -= delayBufferSamples;
//----------------------------
if (localReadPosition2 != localWritePosition2) {
float fraction = readPosition2 - (float)localReadPosition2;
float delayed1 = delay2Data[(localReadPosition2 + 0)];
float delayed2 = delay2Data[(localReadPosition2 + 1) % delayBuffer2Samples];
out2 = out2 + delayed1 + fraction * (delayed2 - delayed1);
intermediateData2[sample] = in2 + currentMix2 * (out2 - in2);
delay2Data[localWritePosition2] = in2 + out2 * currentFeedback2;
}
if (++localWritePosition2 >= delayBuffer2Samples)
localWritePosition2 -= delayBuffer2Samples;
//----------------------------
if (localReadPosition3 != localWritePosition3) {
float fraction = readPosition3 - (float)localReadPosition3;
float delayed1 = delay3Data[(localReadPosition3 + 0)];
float delayed2 = delay3Data[(localReadPosition3 + 1) % delayBuffer3Samples];
out3 = out3 + delayed1 + fraction * (delayed2 - delayed1);
intermediateData3[sample] = in3 + currentMix3 * (out3 - in3);
delay3Data[localWritePosition3] = in3 + out3 * currentFeedback3;
}
if (++localWritePosition3 >= delayBuffer3Samples)
localWritePosition3 -= delayBuffer3Samples;
channelData[sample] = intermediateData[sample] + intermediateData2[sample] + intermediateData3[sample];
// finalData[sample] = intermediateData[sample] + intermediateData2[sample] + intermediateData3[sample];
// channelData[sample] = finalData[sample];
/*
// swap l/r
if (channel == 0)
delayLine.pushSample (1, input);
else
delayLine.pushSample (0, input * -1.0f); // invert polarity
*/
}
}
delayWritePosition = localWritePosition;
delay2WritePosition = localWritePosition2;
delay3WritePosition = localWritePosition3;
//======================================
// for (int channel = numInputChannels; channel < numOutputChannels; ++channel)
// buffer.clear (channel, 0, numSamples);
}
Here is a screenshot of the controls:-

