I am doing an Echo delay where I’m copying my input Buffer to a circular Delay Buffer, reading that in that buffer from another position and copying that to the (input) Buffer again.
After that, I’m trying to use a StateVariableTPTFilter with a fixed Cutoff frequency to filter that signal per block but I get tons of artifacts. I tried to filter it sample per sampler but in that case the filter didn’t work at all.
My audioProcessorBlock is:
void CircularAudioBufferAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
auto delayBufferSize = 2.0 * (sampleRate + samplesPerBlock);
mSampleRate = sampleRate;
delayBuffer.setSize(getTotalNumInputChannels(), (int)delayBufferSize);
dsp::ProcessSpec spec; //DSP algorithm needs this info to work
spec.sampleRate = sampleRate;
spec.maximumBlockSize = samplesPerBlock;
spec.numChannels = getTotalNumInputChannels();
filter.prepare(spec);
reset();
filter.setType(dsp::StateVariableTPTFilterType::lowpass);
}
void CircularAudioBufferAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
juce::ScopedNoDenormals noDenormals;
auto totalNumInputChannels = getTotalNumInputChannels();
auto totalNumOutputChannels = getTotalNumOutputChannels();
filter.setCutoffFrequency(500.f);
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear (i, 0, buffer.getNumSamples());
auto bufferSize = buffer.getNumSamples();
auto delayBufferSize = delayBuffer.getNumSamples();
for (int channel = 0; channel < totalNumInputChannels; ++channel)
{
const float* bufferData = buffer.getReadPointer(channel);
const float* delayBufferData = delayBuffer.getReadPointer(channel);
fillDelayBuffer(channel, bufferSize, delayBufferSize, bufferData, delayBufferData);
getFromDelayBuffer(buffer, channel, bufferSize, delayBufferSize, bufferData, delayBufferData);
}
auto audioBlock = juce::dsp::AudioBlock<float>(delayBuffer); //already do both channels for the dsp process
auto context = juce::dsp::ProcessContextReplacing<float>(audioBlock);
filter.process(context);
writePos += bufferSize;
writePos %= delayBufferSize;
}
This function “fillDelayBuffer” copies the buffer data to the circular Delay Buffer.
This function “getFromDelayBuffer” copies again the data from the Delay Buffer into the ‘normal’ Buffer.
Following what I have read, the AudioBlock class to create a Context already iterates for both channels (L and R) that is why I set the filter process outside of the for channel loop. Anyway, it creates those artifacts anywhere I place it.
Could someone point me how could I filter that signal from the Delay Buffer or from the ‘normal’ Buffer without all of those artifacts?
Thank you so much.