From 58d0eeba88025b863b33446f92e3d2c6a7193b3f Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Tue, 11 Jul 2023 14:15:53 +0100 Subject: [PATCH] Envelope Filter fillLevelBuffer and processAudio Adapted for Level Tracking I/O --- src/processors/other/EnvelopeFilter.cpp | 60 +++++++++++++++---------- src/processors/other/EnvelopeFilter.h | 4 +- 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/processors/other/EnvelopeFilter.cpp b/src/processors/other/EnvelopeFilter.cpp index 0af265d0..20982661 100644 --- a/src/processors/other/EnvelopeFilter.cpp +++ b/src/processors/other/EnvelopeFilter.cpp @@ -1,4 +1,5 @@ #include "EnvelopeFilter.h" +#include "../BufferHelpers.h" #include "../ParameterHelpers.h" #include "gui/utils/ModulatableSlider.h" @@ -83,38 +84,39 @@ void EnvelopeFilter::prepare (double sampleRate, int samplesPerBlock) filter.prepare (spec); level.prepare (monoSpec); - levelBuffer.setSize (1, samplesPerBlock); + levelOutBuffer.setSize (1, samplesPerBlock); + audioOutBuffer.setSize (2, samplesPerBlock); } void EnvelopeFilter::fillLevelBuffer (AudioBuffer& buffer, bool directControlOn) { - const auto numChannels = buffer.getNumChannels(); const auto numSamples = buffer.getNumSamples(); - levelBuffer.setSize (1, numSamples, false, false, true); - levelBuffer.clear(); - - if (directControlOn) + levelOutBuffer.setSize (1, numSamples, false, false, true); + //does levelOutBuffer need clearing here? + if (directControlOn) //fill buffer with freq mod percentage (regardless of level or audio I/O) { - FloatVectorOperations::fill (levelBuffer.getWritePointer (0), *freqModParam, numSamples); + FloatVectorOperations::fill (levelOutBuffer.getWritePointer (0), *freqModParam, numSamples); } - else if (numChannels == 1) + else if (inputsConnected.contains (LevelInput)) //use level input for level buffer { - levelBuffer.copyFrom (0, 0, buffer.getReadPointer (0), numSamples); + BufferHelpers::collapseToMonoBuffer (getInputBuffer (LevelInput), levelOutBuffer); } else { - levelBuffer.copyFrom (0, 0, buffer.getReadPointer (0), numSamples); - - for (int ch = 1; ch < numChannels; ++ch) - levelBuffer.addFrom (0, 0, buffer.getReadPointer (ch), numSamples); - - levelBuffer.applyGain (1.0f / (float) numChannels); + if (inputsConnected.contains (AudioInput)) //use audio buffer for level input + { + BufferHelpers::collapseToMonoBuffer (getInputBuffer (AudioInput), levelOutBuffer); + } + else + { + levelOutBuffer.clear(); + } } auto speed = speedRange.convertFrom0to1 (1.0f - *speedParam); level.setParameters (speed, speed * 4.0f); - dsp::AudioBlock levelBlock { levelBuffer }; + dsp::AudioBlock levelBlock { levelOutBuffer }; dsp::ProcessContextReplacing levelCtx { levelBlock }; level.process (levelCtx); } @@ -156,41 +158,53 @@ void EnvelopeFilter::processAudio (AudioBuffer& buffer) const auto numSamples = buffer.getNumSamples(); bool directControlOn = *directControlParam == 1.0f; - fillLevelBuffer (buffer, directControlOn); + fillLevelBuffer (buffer, directControlOn); //returns levelOutBuffer now auto filterFreqHz = freqParam->getCurrentValue(); filter.setQValue (getQ (resParam->getCurrentValue())); auto freqModGain = directControlOn ? 10.0f : (20.0f * senseParam->getCurrentValue()); - auto* levelPtr = levelBuffer.getReadPointer (0); - FloatVectorOperations::clip (levelBuffer.getWritePointer (0), levelPtr, 0.0f, 2.0f, numSamples); + auto* levelPtr = levelOutBuffer.getReadPointer (0); + FloatVectorOperations::clip (levelOutBuffer.getWritePointer (0), levelPtr, 0.0f, 2.0f, numSamples); auto getModFreq = [=] (int i) -> float { return jlimit (20.0f, 20.0e3f, filterFreqHz + freqModGain * levelPtr[i] * filterFreqHz); }; + //use of buffer below replaced with getInputBuffer(AudioInput) + auto& audioInBuffer = getInputBuffer (AudioInput); + const auto numChannels = audioInBuffer.getNumChannels(); + audioOutBuffer.setSize (numChannels, numSamples, false, false, true); + //copy audio in to audio out (because audio in is const) + for (int ch = 0; ch < numChannels; ch++) + audioOutBuffer.copyFrom (ch, 0, audioInBuffer.getReadPointer (0), numSamples); + using SVFType = chowdsp::StateVariableFilterType; auto filterType = (int) filterTypeParam->load(); switch (filterType) { case 0: - processFilter (buffer, filter, getModFreq); + processFilter (audioOutBuffer, filter, getModFreq); break; case 1: - processFilter (buffer, filter, getModFreq); + processFilter (audioOutBuffer, filter, getModFreq); break; case 2: - processFilter (buffer, filter, getModFreq); + processFilter (audioOutBuffer, filter, getModFreq); break; default: jassertfalse; } - buffer.applyGain (Decibels::decibelsToGain (-6.0f)); + audioOutBuffer.applyGain (Decibels::decibelsToGain (-6.0f)); + + outputBuffers.getReference (AudioOutput) = &audioOutBuffer; + outputBuffers.getReference (LevelOutput) = &levelOutBuffer; + } bool EnvelopeFilter::getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) diff --git a/src/processors/other/EnvelopeFilter.h b/src/processors/other/EnvelopeFilter.h index eb22b6dc..d36f9157 100644 --- a/src/processors/other/EnvelopeFilter.h +++ b/src/processors/other/EnvelopeFilter.h @@ -43,7 +43,9 @@ class EnvelopeFilter : public BaseProcessor chowdsp::SVFMultiMode filter; - AudioBuffer levelBuffer; + AudioBuffer levelOutBuffer; + AudioBuffer audioOutBuffer; + chowdsp::LevelDetector level; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EnvelopeFilter)