From 04b1131d9728c6ab1cdc20dea3f9a26c02439a05 Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Tue, 24 Oct 2023 13:18:19 +0100 Subject: [PATCH 01/14] Custom Components Added to Delay Module To Allow Tempo Sync Delay Time Option --- src/processors/other/Delay.cpp | 139 ++++++++++++++++++++++++++++++--- src/processors/other/Delay.h | 6 +- 2 files changed, 133 insertions(+), 12 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 4c62a325..618f8fc2 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -1,24 +1,35 @@ #include "Delay.h" #include "../ParameterHelpers.h" +#include "gui/utils/ModulatableSlider.h" namespace { const String delayTypeTag = "delay_type"; const String pingPongTag = "ping_pong"; +const String freqTag = "freq"; +const String feedBackTag = "feedback"; +const String mixTag = "mix"; + +const String delayTimeMsTag = "time_ms"; +const String tempoSyncTag = "tempo_sync"; +const String tempoSyncAmountTag = "delay_time_type"; } // namespace DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um) { using namespace ParameterHelpers; - loadParameterPointer (delayTimeMsParam, vts, "time_ms"); - loadParameterPointer (freqParam, vts, "freq"); - loadParameterPointer (feedbackParam, vts, "feedback"); - loadParameterPointer (mixParam, vts, "mix"); + loadParameterPointer (freqParam, vts, freqTag); + loadParameterPointer (feedbackParam, vts, feedBackTag); + loadParameterPointer (mixParam, vts, mixTag); + loadParameterPointer (delayTimeMsParam, vts, delayTimeMsTag); + delayTimeTempoSyncParam = vts.getRawParameterValue (tempoSyncAmountTag); + tempoSyncOnOffParam = vts.getRawParameterValue (tempoSyncTag); delayTypeParam = vts.getRawParameterValue (delayTypeTag); pingPongParam = vts.getRawParameterValue (pingPongTag); addPopupMenuParameter (delayTypeTag); addPopupMenuParameter (pingPongTag); + addPopupMenuParameter (tempoSyncTag); uiOptions.backgroundColour = Colours::cyan.darker (0.1f); uiOptions.powerColour = Colours::gold; @@ -31,12 +42,17 @@ ParamLayout DelayModule::createParameterLayout() using namespace ParameterHelpers; auto params = createBaseParams(); - createTimeMsParameter (params, "time_ms", "Delay Time", createNormalisableRange (20.0f, 2000.0f, 200.0f), 100.0f); - - createFreqParameter (params, "freq", "Cutoff", 500.0f, 10000.0f, 4000.0f, 10000.0f); - createPercentParameter (params, "feedback", "Feedback", 0.0f); - createPercentParameter (params, "mix", "Mix", 0.5f); - + createTimeMsParameter (params, delayTimeMsTag, "Delay Time", createNormalisableRange (20.0f, 2000.0f, 200.0f), 100.0f); + createFreqParameter (params, freqTag, "Cutoff", 500.0f, 10000.0f, 4000.0f, 10000.0f); + createPercentParameter (params, feedBackTag, "Feedback", 0.0f); + createPercentParameter (params, mixTag, "Mix", 0.5f); + + emplace_param (params, + tempoSyncAmountTag, + "Tempo Sync", + StringArray { "1/2", "1/4", "1/8" }, + 0); + emplace_param (params, tempoSyncTag, "Tempo Sync Delay", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); emplace_param (params, pingPongTag, "Ping-Pong", false); @@ -218,10 +234,11 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); - delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); + delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) freqSmooth.setTargetValue (*freqParam); const auto delayTypeIndex = (int) *delayTypeParam; + const auto tempoSyncAmountIndex = (int) *delayTimeTempoSyncParam; if (delayTypeIndex != prevDelayTypeIndex) { cleanDelayLine.reset(); @@ -261,3 +278,103 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } + +bool DelayModule::getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) +{ + using namespace chowdsp::ParamUtils; + class DelayTimeModeControl : public Slider + { + public: + DelayTimeModeControl (AudioProcessorValueTreeState& vtState, chowdsp::HostContextProvider& hcp) + : vts (vtState), + tempoSyncSelectorAttach (vts, tempoSyncAmountTag, tempoSyncSelector), + delayTimeSlider (*getParameterPointer (vts, delayTimeMsTag), hcp), + delayTimeAttach(vts, delayTimeMsTag, delayTimeSlider), + tempoSyncOnOffAttach ( + *vts.getParameter (tempoSyncTag), + [this] (float newValue) + { updateControlVisibility (newValue == 1.0f); }, + vts.undoManager) + { + addChildComponent (tempoSyncSelector); + addChildComponent (delayTimeSlider); + + const auto* modeChoiceParam = getParameterPointer (vts, tempoSyncAmountTag); + tempoSyncSelector.addItemList (modeChoiceParam->choices, 1); + tempoSyncSelector.setSelectedItemIndex (0); + tempoSyncSelector.setScrollWheelEnabled (true); + hcp.registerParameterComponent (tempoSyncSelector, *modeChoiceParam); + + hcp.registerParameterComponent (delayTimeSlider, delayTimeSlider.getParameter()); + + this->setName (tempoSyncAmountTag + "__" + delayTimeMsTag + "__"); + } + + void colourChanged() override + { + for (auto colourID : { Slider::textBoxOutlineColourId, + Slider::textBoxTextColourId, + Slider::textBoxBackgroundColourId, + Slider::textBoxHighlightColourId, + Slider::thumbColourId }) + { + delayTimeSlider.setColour (colourID, findColour (colourID, false)); + } + + for (auto colourID : { ComboBox::outlineColourId, + ComboBox::textColourId, + ComboBox::arrowColourId }) + { + tempoSyncSelector.setColour (colourID, findColour (Slider::textBoxTextColourId, false)); + } + } + + void updateControlVisibility (bool tempoSyncOn) + { + tempoSyncSelector.setVisible (tempoSyncOn); + delayTimeSlider.setVisible (!tempoSyncOn); + + setName (vts.getParameter (tempoSyncOn ? tempoSyncAmountTag : delayTimeMsTag)->name); + if (auto* parent = getParentComponent()) + parent->repaint(); + } + + void visibilityChanged() override + { + updateControlVisibility (vts.getRawParameterValue (tempoSyncTag)->load() == 1.0f); + } + + void resized() override + { + delayTimeSlider.setSliderStyle (getSliderStyle()); + delayTimeSlider.setTextBoxStyle (getTextBoxPosition(), false, getTextBoxWidth(), getTextBoxHeight()); + + const auto bounds = getLocalBounds(); + tempoSyncSelector.setBounds (bounds.proportionOfWidth(0.15f), + bounds.proportionOfHeight(0.1f), + bounds.proportionOfWidth(0.7f), + bounds.proportionOfHeight(0.25f)); + delayTimeSlider.setBounds (bounds); + } + + private: + using SliderAttachment = AudioProcessorValueTreeState::SliderAttachment; + using BoxAttachment = AudioProcessorValueTreeState::ComboBoxAttachment; + + AudioProcessorValueTreeState& vts; + + ComboBox tempoSyncSelector; + BoxAttachment tempoSyncSelectorAttach; + + ModulatableSlider delayTimeSlider; + SliderAttachment delayTimeAttach; + + ParameterAttachment tempoSyncOnOffAttach; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DelayTimeModeControl) + }; + + customComps.add (std::make_unique (vts, hcp)); + + return false; +} \ No newline at end of file diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index 0804f788..6c43125d 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -9,6 +9,7 @@ class DelayModule : public BaseProcessor ProcessorType getProcessorType() const override { return Other; } static ParamLayout createParameterLayout(); + bool getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) override; void prepare (double sampleRate, int samplesPerBlock) override; void releaseMemory() override; @@ -21,13 +22,16 @@ class DelayModule : public BaseProcessor template void processPingPongDelay (AudioBuffer& buffer, DelayType& delayLine); - chowdsp::FloatParameter* delayTimeMsParam = nullptr; chowdsp::FloatParameter* freqParam = nullptr; chowdsp::FloatParameter* feedbackParam = nullptr; chowdsp::FloatParameter* mixParam = nullptr; std::atomic* delayTypeParam = nullptr; std::atomic* pingPongParam = nullptr; + chowdsp::FloatParameter* delayTimeMsParam = nullptr; + std::atomic* delayTimeTempoSyncParam = nullptr; + std::atomic* tempoSyncOnOffParam = nullptr; + dsp::DryWetMixer dryWetMixer; dsp::DryWetMixer dryWetMixerMono; From 26f3b4c148e2e44daff877d06be16ebbf36384e2 Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Tue, 24 Oct 2023 17:34:30 +0100 Subject: [PATCH 02/14] Rough Plan for Tempo Sync Delay Calculation --- src/processors/other/Delay.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 618f8fc2..5caba783 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -50,7 +50,7 @@ ParamLayout DelayModule::createParameterLayout() emplace_param (params, tempoSyncAmountTag, "Tempo Sync", - StringArray { "1/2", "1/4", "1/8" }, + StringArray { "1/2", "1/4", "1/8" , "1/8 dotted"}, 0); emplace_param (params, tempoSyncTag, "Tempo Sync Delay", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); @@ -234,7 +234,26 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); - delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) + + if (!tempoSyncOnOffParam) + { + std::cout << "Delay Time In Ms..." << std::endl; + delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) + } + else + { + std::cout << "Delay Time In Notes..." << std::endl; + //calculate delay time based on delayTimeTempoSyncParam + auto noteDivision = (int)*delayTimeTempoSyncParam; + if (noteDivision == 0) + std::cout<< "1/2 note delay" << std::endl; + else if (noteDivision == 1) + std::cout<< "1/4 note delay" << std::endl; + else if (noteDivision == 2) + std::cout<< "1/8 note delay" << std::endl; + else if (noteDivision == 3) + std::cout<< "1/8 note dottod delay" << std::endl; + } freqSmooth.setTargetValue (*freqParam); const auto delayTypeIndex = (int) *delayTypeParam; From 021416ae69dbfa5af7ef5f88dcd255f3bbe89604 Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Wed, 25 Oct 2023 00:07:39 +0100 Subject: [PATCH 03/14] Intital Tempo Sync Delay Implementation --- src/processors/other/Delay.cpp | 40 +++++++++++++++++++++++++++------- src/processors/other/Delay.h | 10 +++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 5caba783..e48d902f 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -234,30 +234,45 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); - - if (!tempoSyncOnOffParam) + auto tempoSync = (int)*tempoSyncOnOffParam; + if (!tempoSync) { std::cout << "Delay Time In Ms..." << std::endl; delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) } else { + float delayInSamples = fs * 200 * 0.001f ; std::cout << "Delay Time In Notes..." << std::endl; - //calculate delay time based on delayTimeTempoSyncParam + auto positionInfo = audioPlayHead.getPosition(); +// auto hardcodedBpm = 120; + auto bpm = positionInfo->getBpm(); auto noteDivision = (int)*delayTimeTempoSyncParam; if (noteDivision == 0) - std::cout<< "1/2 note delay" << std::endl; + { + delayInSamples = calculateTempoSyncDelayTime(2.0f, *bpm); + std::cout << "1/2 Note Delay..." << std::endl; + } else if (noteDivision == 1) - std::cout<< "1/4 note delay" << std::endl; + { + delayInSamples = calculateTempoSyncDelayTime(1.0f, *bpm); + std::cout << "1/4 Note Delay..." << std::endl; + } else if (noteDivision == 2) - std::cout<< "1/8 note delay" << std::endl; + { + delayInSamples = calculateTempoSyncDelayTime (0.5f, *bpm); + std::cout << "1/8 Note Delay..." << std::endl; + } else if (noteDivision == 3) - std::cout<< "1/8 note dottod delay" << std::endl; + { + delayInSamples = calculateTempoSyncDelayTime (0.75f, *bpm); + std::cout << "1/8 Note Dotted Delay..." << std::endl; + } + delaySmooth.setTargetValue (delayInSamples); } freqSmooth.setTargetValue (*freqParam); const auto delayTypeIndex = (int) *delayTypeParam; - const auto tempoSyncAmountIndex = (int) *delayTimeTempoSyncParam; if (delayTypeIndex != prevDelayTypeIndex) { cleanDelayLine.reset(); @@ -298,6 +313,15 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } +float DelayModule::calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const +{ + //calculate tempo sync delay in samples + auto beatsPerSecond = static_cast (bpm / 60); + auto secondsPerBeat = 1/beatsPerSecond; + + return floor(noteDuration * secondsPerBeat * fs); +} + bool DelayModule::getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) { using namespace chowdsp::ParamUtils; diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index 6c43125d..55cb232b 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -15,6 +15,7 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; + float calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const; private: template @@ -22,6 +23,15 @@ class DelayModule : public BaseProcessor template void processPingPongDelay (AudioBuffer& buffer, DelayType& delayLine); + struct SimpleAudioPlayHead : juce::AudioPlayHead { + juce::Optional getPosition() const override { + PositionInfo info; + return info; + } + }; + + SimpleAudioPlayHead audioPlayHead; + chowdsp::FloatParameter* freqParam = nullptr; chowdsp::FloatParameter* feedbackParam = nullptr; chowdsp::FloatParameter* mixParam = nullptr; From e13032ceab0efb5d55f541944f1881d9119837bd Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Wed, 25 Oct 2023 18:03:51 +0100 Subject: [PATCH 04/14] Tempo Sync Calculation For Number of Samples of Delay Added --- src/processors/other/Delay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index e48d902f..7de578d7 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -242,7 +242,7 @@ void DelayModule::processAudio (AudioBuffer& buffer) } else { - float delayInSamples = fs * 200 * 0.001f ; + float delayInSamples = fs * 200 * 0.001f; //fallback delay std::cout << "Delay Time In Notes..." << std::endl; auto positionInfo = audioPlayHead.getPosition(); // auto hardcodedBpm = 120; From 00bd58c4b9b78b50cb49e3fc76910e93890c02ad Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Wed, 1 Nov 2023 16:59:56 +0000 Subject: [PATCH 05/14] PlayheadHelpers Added to Manage the AudioPlayHead Object --- src/BYOD.cpp | 7 ++- src/BYOD.h | 5 +- src/processors/BaseProcessor.cpp | 8 +++ src/processors/BaseProcessor.h | 5 ++ src/processors/PlayheadHelpers.h | 25 ++++++++ src/processors/chain/ProcessorChain.cpp | 8 +++ src/processors/chain/ProcessorChain.h | 2 + src/processors/other/Delay.cpp | 81 +++++++++++++++---------- src/processors/other/Delay.h | 3 + 9 files changed, 110 insertions(+), 34 deletions(-) create mode 100644 src/processors/PlayheadHelpers.h diff --git a/src/BYOD.cpp b/src/BYOD.cpp index 5a6dcc3f..9221f8aa 100644 --- a/src/BYOD.cpp +++ b/src/BYOD.cpp @@ -24,10 +24,11 @@ BYOD::BYOD() : chowdsp::PluginBase (&undoManager), pluginSettings->initialise (settingsFilePath); procs = std::make_unique (procStore, vts, presetManager, paramForwarder, [&] (int l) - { updateSampleLatency (l); }); + { updateSampleLatency (l); }); //make unique paramForwarder = std::make_unique (vts, *procs); presetManager = std::make_unique (procs.get(), vts); stateManager = std::make_unique (vts, *procs, *presetManager); +// playheadHelper = std::make_unique (); #if JUCE_IOS LookAndFeel::setDefaultLookAndFeel (lnfAllocator->getLookAndFeel()); @@ -66,6 +67,10 @@ void BYOD::processBlock (AudioBuffer& buffer, MidiBuffer& midi) const juce::ScopedNoDenormals noDenormals {}; AudioProcessLoadMeasurer::ScopedTimer loadTimer { loadMeasurer, buffer.getNumSamples() }; + //get playhead + playheadHelper.process(getPlayHead(), buffer.getNumSamples()); + procs->setPlayheadHelpersReference(playheadHelper); + // push samples into bypass delay bypassScratchBuffer.makeCopyOf (buffer, true); processBypassDelay (bypassScratchBuffer); diff --git a/src/BYOD.h b/src/BYOD.h index afe3174a..df99c854 100644 --- a/src/BYOD.h +++ b/src/BYOD.h @@ -2,6 +2,7 @@ #include "processors/ProcessorStore.h" #include "processors/chain/ProcessorChain.h" +#include "processors/PlayheadHelpers.h" #include "state/ParamForwardManager.h" #include "state/StateManager.h" @@ -54,7 +55,7 @@ class BYOD : public chowdsp::PluginBase [[maybe_unused]] chowdsp::SharedLNFAllocator lnfAllocator; // keep alive! ProcessorStore procStore; - std::unique_ptr procs; + std::unique_ptr procs; //ptrs to processor chain [[maybe_unused]] std::unique_ptr paramForwarder; AudioBuffer bypassScratchBuffer; @@ -68,6 +69,8 @@ class BYOD : public chowdsp::PluginBase std::unique_ptr openGLHelper = nullptr; + PlayheadHelpers playheadHelper; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BYOD) }; diff --git a/src/processors/BaseProcessor.cpp b/src/processors/BaseProcessor.cpp index c06b1bda..003b24cf 100644 --- a/src/processors/BaseProcessor.cpp +++ b/src/processors/BaseProcessor.cpp @@ -115,6 +115,14 @@ void BaseProcessor::processAudioBlock (AudioBuffer& buffer) processAudio (buffer); } +void BaseProcessor::setPlayheadHelpersReference(PlayheadHelpers& helpers) { + playheadHelpersReference = &helpers; +} + +PlayheadHelpers& BaseProcessor::getPlayheadHelpersReference() { + return *playheadHelpersReference; +} + float BaseProcessor::getInputLevelDB (int portIndex) const noexcept { jassert (isPositiveAndBelow (portIndex, numInputs)); diff --git a/src/processors/BaseProcessor.h b/src/processors/BaseProcessor.h index e0086215..b875a853 100644 --- a/src/processors/BaseProcessor.h +++ b/src/processors/BaseProcessor.h @@ -1,6 +1,7 @@ #pragma once #include "JuceProcWrapper.h" +#include "processors/PlayheadHelpers.h" enum ProcessorType { @@ -110,6 +111,8 @@ class BaseProcessor : private JuceProcWrapper void prepareProcessing (double sampleRate, int numSamples); void freeInternalMemory(); void processAudioBlock (AudioBuffer& buffer); + void setPlayheadHelpersReference(PlayheadHelpers& helpers); + PlayheadHelpers& getPlayheadHelpersReference(); // methods for working with port input levels float getInputLevelDB (int portIndex) const noexcept; @@ -302,6 +305,8 @@ class BaseProcessor : private JuceProcWrapper StringArray popupMenuParameterIDs; OwnedArray popupMenuParameterAttachments; + PlayheadHelpers* playheadHelpersReference; + const base_processor_detail::PortTypesVector inputPortTypes; const base_processor_detail::PortTypesVector outputPortTypes; diff --git a/src/processors/PlayheadHelpers.h b/src/processors/PlayheadHelpers.h new file mode 100644 index 00000000..19f4b8f3 --- /dev/null +++ b/src/processors/PlayheadHelpers.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +struct PlayheadHelpers +{ + static void prepare(double sampleRate, int maxBlockSize) + { + ignoreUnused(sampleRate, maxBlockSize); + } + + void process(AudioPlayHead* playHead, int numSamples) + { + ignoreUnused(numSamples); + if (playHead != nullptr) + { + info = *playHead->getPosition(); + bpm.store(*info.getBpm()); + } + } + + std::atomic bpm; + AudioPlayHead::PositionInfo info; +}; + diff --git a/src/processors/chain/ProcessorChain.cpp b/src/processors/chain/ProcessorChain.cpp index 7fdb0255..8d24184e 100644 --- a/src/processors/chain/ProcessorChain.cpp +++ b/src/processors/chain/ProcessorChain.cpp @@ -57,6 +57,10 @@ void ProcessorChain::createParameters (Parameters& params) ChainIOProcessor::createParameters (params); } +void ProcessorChain::setPlayheadHelpersReference(PlayheadHelpers& helpers) { + playheadHelpersReference = &helpers; +} + void ProcessorChain::initializeProcessors() { const auto osFactor = ioProcessor.getOversamplingFactor(); @@ -69,7 +73,11 @@ void ProcessorChain::initializeProcessors() for (int i = procs.size() - 1; i >= 0; --i) { if (auto* proc = procs[i]) + { + if (proc->getName() == "Delay") + proc->setPlayheadHelpersReference(*playheadHelpersReference); proc->prepareProcessing (osSampleRate, osSamplesPerBlock); + } } } diff --git a/src/processors/chain/ProcessorChain.h b/src/processors/chain/ProcessorChain.h index b34646fe..363773b7 100644 --- a/src/processors/chain/ProcessorChain.h +++ b/src/processors/chain/ProcessorChain.h @@ -27,6 +27,7 @@ class ProcessorChain : private AudioProcessorValueTreeState::Listener auto& getProcessors() { return procs; } const auto& getProcessors() const { return procs; } ProcessorStore& getProcStore() { return procStore; } + void setPlayheadHelpersReference(PlayheadHelpers& helpers); InputProcessor& getInputProcessor() { return inputProcessor; } OutputProcessor& getOutputProcessor() { return outputProcessor; } @@ -78,6 +79,7 @@ class ProcessorChain : private AudioProcessorValueTreeState::Listener std::unique_ptr& paramForwardManager; MidiBuffer internalMidiBuffer; + PlayheadHelpers* playheadHelpersReference = nullptr; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorChain) }; diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 7de578d7..3eb1c6be 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -15,7 +15,8 @@ const String tempoSyncTag = "tempo_sync"; const String tempoSyncAmountTag = "delay_time_type"; } // namespace -DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um) +DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um), + bpm(getPlayheadHelpersReference().bpm) { using namespace ParameterHelpers; loadParameterPointer (freqParam, vts, freqTag); @@ -240,37 +241,49 @@ void DelayModule::processAudio (AudioBuffer& buffer) std::cout << "Delay Time In Ms..." << std::endl; delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) } - else - { - float delayInSamples = fs * 200 * 0.001f; //fallback delay - std::cout << "Delay Time In Notes..." << std::endl; - auto positionInfo = audioPlayHead.getPosition(); -// auto hardcodedBpm = 120; - auto bpm = positionInfo->getBpm(); - auto noteDivision = (int)*delayTimeTempoSyncParam; - if (noteDivision == 0) - { - delayInSamples = calculateTempoSyncDelayTime(2.0f, *bpm); - std::cout << "1/2 Note Delay..." << std::endl; - } - else if (noteDivision == 1) - { - delayInSamples = calculateTempoSyncDelayTime(1.0f, *bpm); - std::cout << "1/4 Note Delay..." << std::endl; - } - else if (noteDivision == 2) - { - delayInSamples = calculateTempoSyncDelayTime (0.5f, *bpm); - std::cout << "1/8 Note Delay..." << std::endl; - } - else if (noteDivision == 3) - { - delayInSamples = calculateTempoSyncDelayTime (0.75f, *bpm); - std::cout << "1/8 Note Dotted Delay..." << std::endl; - } - delaySmooth.setTargetValue (delayInSamples); - } - freqSmooth.setTargetValue (*freqParam); + +// PlayheadHelpers& PlayheadHelpersRef = this->getPlayheadHelpersReference(); +// std::cout << playheadHelpersReference.bpmDouble << std::endl; +// double tempo = bpm.load(); +// std::cout << "My BPM: " << tempo << std::endl; +// int myIntVal = intRef.load(); +// std::cout << "My Int: " << myIntVal << std::endl; + + +// bpm = PlayheadHelpersRef.bpm.load(); + +// std::cout << "Playhead Helper BPM: " << bpm << std::endl; +// else +// { +// float delayInSamples = fs * 200 * 0.001f; //fallback delay +// std::cout << "Delay Time In Notes..." << std::endl; +// auto positionInfo = audioPlayHead.getPosition(); +//// auto hardcodedBpm = 120; +// auto bpm = positionInfo->getBpm(); +// auto noteDivision = (int)*delayTimeTempoSyncParam; +// if (noteDivision == 0) +// { +// delayInSamples = calculateTempoSyncDelayTime(2.0f, *bpm); +// std::cout << "1/2 Note Delay..." << std::endl; +// } +// else if (noteDivision == 1) +// { +// delayInSamples = calculateTempoSyncDelayTime(1.0f, *bpm); +// std::cout << "1/4 Note Delay..." << std::endl; +// } +// else if (noteDivision == 2) +// { +// delayInSamples = calculateTempoSyncDelayTime (0.5f, *bpm); +// std::cout << "1/8 Note Delay..." << std::endl; +// } +// else if (noteDivision == 3) +// { +// delayInSamples = calculateTempoSyncDelayTime (0.75f, *bpm); +// std::cout << "1/8 Note Dotted Delay..." << std::endl; +// } +// delaySmooth.setTargetValue (delayInSamples); +// } +// freqSmooth.setTargetValue (*freqParam); const auto delayTypeIndex = (int) *delayTypeParam; if (delayTypeIndex != prevDelayTypeIndex) @@ -313,6 +326,10 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } +//void DelayModule::setPlayheadHelpersReference(PlayheadHelpers& helpers) { +// playheadHelpersReference = &helpers; +//} + float DelayModule::calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const { //calculate tempo sync delay in samples diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index 55cb232b..a170bc0c 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -1,6 +1,7 @@ #pragma once #include "../BaseProcessor.h" +#include "processors/PlayheadHelpers.h" class DelayModule : public BaseProcessor { @@ -16,6 +17,7 @@ class DelayModule : public BaseProcessor void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; float calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const; +// void setPlayheadHelpersReference(PlayheadHelpers& helpers); private: template @@ -82,6 +84,7 @@ class DelayModule : public BaseProcessor AudioBuffer stereoBuffer; bool bypassNeedsReset = false; + std::atomic& bpm; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DelayModule) }; From 08fa4bb7d22e383995de235e29a15d98063d205a Mon Sep 17 00:00:00 2001 From: jatin Date: Wed, 1 Nov 2023 15:23:11 -0700 Subject: [PATCH 06/14] Playhead helpers re-organization --- src/BYOD.cpp | 6 ++---- src/BYOD.h | 2 -- src/processors/BaseProcessor.cpp | 8 -------- src/processors/BaseProcessor.h | 9 ++++----- src/processors/PlayheadHelpers.h | 18 +++++++----------- src/processors/chain/ProcessorChain.cpp | 6 ------ src/processors/chain/ProcessorChain.h | 5 +++-- src/processors/chain/ProcessorChainActions.cpp | 1 + src/processors/other/Delay.cpp | 11 +++++------ src/processors/other/Delay.h | 1 - 10 files changed, 22 insertions(+), 45 deletions(-) diff --git a/src/BYOD.cpp b/src/BYOD.cpp index 9221f8aa..4fc2f403 100644 --- a/src/BYOD.cpp +++ b/src/BYOD.cpp @@ -24,11 +24,10 @@ BYOD::BYOD() : chowdsp::PluginBase (&undoManager), pluginSettings->initialise (settingsFilePath); procs = std::make_unique (procStore, vts, presetManager, paramForwarder, [&] (int l) - { updateSampleLatency (l); }); //make unique + { updateSampleLatency (l); }); paramForwarder = std::make_unique (vts, *procs); presetManager = std::make_unique (procs.get(), vts); stateManager = std::make_unique (vts, *procs, *presetManager); -// playheadHelper = std::make_unique (); #if JUCE_IOS LookAndFeel::setDefaultLookAndFeel (lnfAllocator->getLookAndFeel()); @@ -68,8 +67,7 @@ void BYOD::processBlock (AudioBuffer& buffer, MidiBuffer& midi) AudioProcessLoadMeasurer::ScopedTimer loadTimer { loadMeasurer, buffer.getNumSamples() }; //get playhead - playheadHelper.process(getPlayHead(), buffer.getNumSamples()); - procs->setPlayheadHelpersReference(playheadHelper); + procs->getPlayheadHelper().process (getPlayHead(), buffer.getNumSamples()); // push samples into bypass delay bypassScratchBuffer.makeCopyOf (buffer, true); diff --git a/src/BYOD.h b/src/BYOD.h index df99c854..074eada4 100644 --- a/src/BYOD.h +++ b/src/BYOD.h @@ -69,8 +69,6 @@ class BYOD : public chowdsp::PluginBase std::unique_ptr openGLHelper = nullptr; - PlayheadHelpers playheadHelper; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BYOD) }; diff --git a/src/processors/BaseProcessor.cpp b/src/processors/BaseProcessor.cpp index 003b24cf..c06b1bda 100644 --- a/src/processors/BaseProcessor.cpp +++ b/src/processors/BaseProcessor.cpp @@ -115,14 +115,6 @@ void BaseProcessor::processAudioBlock (AudioBuffer& buffer) processAudio (buffer); } -void BaseProcessor::setPlayheadHelpersReference(PlayheadHelpers& helpers) { - playheadHelpersReference = &helpers; -} - -PlayheadHelpers& BaseProcessor::getPlayheadHelpersReference() { - return *playheadHelpersReference; -} - float BaseProcessor::getInputLevelDB (int portIndex) const noexcept { jassert (isPositiveAndBelow (portIndex, numInputs)); diff --git a/src/processors/BaseProcessor.h b/src/processors/BaseProcessor.h index b875a853..f2155156 100644 --- a/src/processors/BaseProcessor.h +++ b/src/processors/BaseProcessor.h @@ -1,7 +1,6 @@ #pragma once #include "JuceProcWrapper.h" -#include "processors/PlayheadHelpers.h" enum ProcessorType { @@ -36,6 +35,7 @@ struct ProcessorUIOptions class BaseProcessor; class ProcessorEditor; +struct PlayheadHelpers; namespace netlist { struct CircuitQuantityList; @@ -111,8 +111,6 @@ class BaseProcessor : private JuceProcWrapper void prepareProcessing (double sampleRate, int numSamples); void freeInternalMemory(); void processAudioBlock (AudioBuffer& buffer); - void setPlayheadHelpersReference(PlayheadHelpers& helpers); - PlayheadHelpers& getPlayheadHelpersReference(); // methods for working with port input levels float getInputLevelDB (int portIndex) const noexcept; @@ -200,6 +198,9 @@ class BaseProcessor : private JuceProcWrapper */ const MidiBuffer* midiBuffer = nullptr; + /** Provided by the processor chain */ + const PlayheadHelpers* playheadHelpers = nullptr; + /** Returns a tooltip string for a given port. */ virtual String getTooltipForPort (int portIndex, bool isInput); @@ -305,8 +306,6 @@ class BaseProcessor : private JuceProcWrapper StringArray popupMenuParameterIDs; OwnedArray popupMenuParameterAttachments; - PlayheadHelpers* playheadHelpersReference; - const base_processor_detail::PortTypesVector inputPortTypes; const base_processor_detail::PortTypesVector outputPortTypes; diff --git a/src/processors/PlayheadHelpers.h b/src/processors/PlayheadHelpers.h index 19f4b8f3..69d4dd95 100644 --- a/src/processors/PlayheadHelpers.h +++ b/src/processors/PlayheadHelpers.h @@ -4,22 +4,18 @@ struct PlayheadHelpers { - static void prepare(double sampleRate, int maxBlockSize) + void process (AudioPlayHead* playHead, int numSamples) { - ignoreUnused(sampleRate, maxBlockSize); - } - - void process(AudioPlayHead* playHead, int numSamples) - { - ignoreUnused(numSamples); + ignoreUnused (numSamples); if (playHead != nullptr) { - info = *playHead->getPosition(); - bpm.store(*info.getBpm()); + bpm.store (playHead->getPosition().orFallback (AudioPlayHead::PositionInfo {}).getBpm().orFallback (120.0)); + } + else + { + bpm.store (120.0); } } std::atomic bpm; - AudioPlayHead::PositionInfo info; }; - diff --git a/src/processors/chain/ProcessorChain.cpp b/src/processors/chain/ProcessorChain.cpp index 8d24184e..99fc3201 100644 --- a/src/processors/chain/ProcessorChain.cpp +++ b/src/processors/chain/ProcessorChain.cpp @@ -57,10 +57,6 @@ void ProcessorChain::createParameters (Parameters& params) ChainIOProcessor::createParameters (params); } -void ProcessorChain::setPlayheadHelpersReference(PlayheadHelpers& helpers) { - playheadHelpersReference = &helpers; -} - void ProcessorChain::initializeProcessors() { const auto osFactor = ioProcessor.getOversamplingFactor(); @@ -74,8 +70,6 @@ void ProcessorChain::initializeProcessors() { if (auto* proc = procs[i]) { - if (proc->getName() == "Delay") - proc->setPlayheadHelpersReference(*playheadHelpersReference); proc->prepareProcessing (osSampleRate, osSamplesPerBlock); } } diff --git a/src/processors/chain/ProcessorChain.h b/src/processors/chain/ProcessorChain.h index 363773b7..5ea64753 100644 --- a/src/processors/chain/ProcessorChain.h +++ b/src/processors/chain/ProcessorChain.h @@ -5,6 +5,7 @@ #include "../utility/InputProcessor.h" #include "../utility/OutputProcessor.h" +#include "processors/PlayheadHelpers.h" class ProcessorChainActionHelper; class ProcessorChainPortMagnitudesHelper; @@ -27,7 +28,6 @@ class ProcessorChain : private AudioProcessorValueTreeState::Listener auto& getProcessors() { return procs; } const auto& getProcessors() const { return procs; } ProcessorStore& getProcStore() { return procStore; } - void setPlayheadHelpersReference(PlayheadHelpers& helpers); InputProcessor& getInputProcessor() { return inputProcessor; } OutputProcessor& getOutputProcessor() { return outputProcessor; } @@ -35,6 +35,7 @@ class ProcessorChain : private AudioProcessorValueTreeState::Listener auto& getActionHelper() { return *actionHelper; } auto& getStateHelper() { return *stateHelper; } auto& getOversampling() { return ioProcessor.getOversampling(); } + auto& getPlayheadHelper() { return playheadHelper; } chowdsp::Broadcaster processorAddedBroadcaster; chowdsp::Broadcaster processorRemovedBroadcaster; @@ -79,7 +80,7 @@ class ProcessorChain : private AudioProcessorValueTreeState::Listener std::unique_ptr& paramForwardManager; MidiBuffer internalMidiBuffer; - PlayheadHelpers* playheadHelpersReference = nullptr; + PlayheadHelpers playheadHelper; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProcessorChain) }; diff --git a/src/processors/chain/ProcessorChainActions.cpp b/src/processors/chain/ProcessorChainActions.cpp index 28ff340c..f864796d 100644 --- a/src/processors/chain/ProcessorChainActions.cpp +++ b/src/processors/chain/ProcessorChainActions.cpp @@ -25,6 +25,7 @@ class ProcChainActions { Logger::writeToLog (String ("Creating processor: ") + newProc->getName()); + newProc->playheadHelpers = &chain.playheadHelper; auto osFactor = chain.ioProcessor.getOversamplingFactor(); newProc->prepareProcessing (osFactor * chain.mySampleRate, osFactor * chain.mySamplesPerBlock); diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 3eb1c6be..d276320e 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -1,6 +1,7 @@ #include "Delay.h" #include "../ParameterHelpers.h" #include "gui/utils/ModulatableSlider.h" +#include "processors/PlayheadHelpers.h" namespace { @@ -15,8 +16,7 @@ const String tempoSyncTag = "tempo_sync"; const String tempoSyncAmountTag = "delay_time_type"; } // namespace -DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um), - bpm(getPlayheadHelpersReference().bpm) +DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um) { using namespace ParameterHelpers; loadParameterPointer (freqParam, vts, freqTag); @@ -242,10 +242,9 @@ void DelayModule::processAudio (AudioBuffer& buffer) delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) } -// PlayheadHelpers& PlayheadHelpersRef = this->getPlayheadHelpersReference(); -// std::cout << playheadHelpersReference.bpmDouble << std::endl; -// double tempo = bpm.load(); -// std::cout << "My BPM: " << tempo << std::endl; + std::cout << playheadHelpers->bpm << std::endl; + double tempo = playheadHelpers->bpm.load(); + std::cout << "My BPM: " << tempo << std::endl; // int myIntVal = intRef.load(); // std::cout << "My Int: " << myIntVal << std::endl; diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index a170bc0c..9f79f6da 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -84,7 +84,6 @@ class DelayModule : public BaseProcessor AudioBuffer stereoBuffer; bool bypassNeedsReset = false; - std::atomic& bpm; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DelayModule) }; From bd093196b6921928292f5368dc63f44b0f47f827 Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Thu, 2 Nov 2023 16:04:56 +0000 Subject: [PATCH 07/14] TempoSync Delay Times Calculation Changed to use chowdsp_rhythm --- modules/CMakeLists.txt | 1 + src/processors/other/Delay.cpp | 88 ++++++++++++++-------------------- src/processors/other/Delay.h | 3 +- 3 files changed, 39 insertions(+), 53 deletions(-) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 03ed3193..a988a36b 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -34,6 +34,7 @@ target_link_libraries(juce_plugin_modules chowdsp::chowdsp_plugin_base chowdsp::chowdsp_plugin_utils chowdsp::chowdsp_reverb + chowdsp::chowdsp_rhythm chowdsp::chowdsp_presets chowdsp::chowdsp_serialization chowdsp::chowdsp_units diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index d276320e..0421e723 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -3,6 +3,8 @@ #include "gui/utils/ModulatableSlider.h" #include "processors/PlayheadHelpers.h" +using namespace chowdsp::RhythmUtils; + namespace { const String delayTypeTag = "delay_type"; @@ -234,6 +236,10 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { + std::cout << playheadHelpers->bpm << std::endl; + double tempo = playheadHelpers->bpm.load(); + std::cout << "My BPM: " << tempo << std::endl; + feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); auto tempoSync = (int)*tempoSyncOnOffParam; if (!tempoSync) @@ -241,48 +247,36 @@ void DelayModule::processAudio (AudioBuffer& buffer) std::cout << "Delay Time In Ms..." << std::endl; delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) } + else + { + float delayInSamples = fs * 200 * 0.001f; //fallback delay + std::cout << "Delay Time In Notes..." << std::endl; + auto positionInfo = audioPlayHead.getPosition(); - std::cout << playheadHelpers->bpm << std::endl; - double tempo = playheadHelpers->bpm.load(); - std::cout << "My BPM: " << tempo << std::endl; -// int myIntVal = intRef.load(); -// std::cout << "My Int: " << myIntVal << std::endl; - - -// bpm = PlayheadHelpersRef.bpm.load(); - -// std::cout << "Playhead Helper BPM: " << bpm << std::endl; -// else -// { -// float delayInSamples = fs * 200 * 0.001f; //fallback delay -// std::cout << "Delay Time In Notes..." << std::endl; -// auto positionInfo = audioPlayHead.getPosition(); -//// auto hardcodedBpm = 120; -// auto bpm = positionInfo->getBpm(); -// auto noteDivision = (int)*delayTimeTempoSyncParam; -// if (noteDivision == 0) -// { -// delayInSamples = calculateTempoSyncDelayTime(2.0f, *bpm); -// std::cout << "1/2 Note Delay..." << std::endl; -// } -// else if (noteDivision == 1) -// { -// delayInSamples = calculateTempoSyncDelayTime(1.0f, *bpm); -// std::cout << "1/4 Note Delay..." << std::endl; -// } -// else if (noteDivision == 2) -// { -// delayInSamples = calculateTempoSyncDelayTime (0.5f, *bpm); -// std::cout << "1/8 Note Delay..." << std::endl; -// } -// else if (noteDivision == 3) -// { -// delayInSamples = calculateTempoSyncDelayTime (0.75f, *bpm); -// std::cout << "1/8 Note Dotted Delay..." << std::endl; -// } -// delaySmooth.setTargetValue (delayInSamples); -// } -// freqSmooth.setTargetValue (*freqParam); + auto noteDivision = (int)*delayTimeTempoSyncParam; + if (noteDivision == 0) + { + delayInSamples = calculateTempoSyncDelayTime(HALF.getTimeSeconds(tempo), fs); + std::cout << "1/2 Note Delay..." << std::endl; + } + else if (noteDivision == 1) + { + delayInSamples = calculateTempoSyncDelayTime(QUARTER.getTimeSeconds(tempo), fs); + std::cout << "1/4 Note Delay..." << std::endl; + } + else if (noteDivision == 2) + { + delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds(tempo), fs); + std::cout << "1/8 Note Delay..." << std::endl; + } + else if (noteDivision == 3) + { + delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds(tempo), fs); + std::cout << "1/8 Note Dotted Delay..." << std::endl; + } + delaySmooth.setTargetValue (delayInSamples); + } + freqSmooth.setTargetValue (*freqParam); const auto delayTypeIndex = (int) *delayTypeParam; if (delayTypeIndex != prevDelayTypeIndex) @@ -325,17 +319,9 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } -//void DelayModule::setPlayheadHelpersReference(PlayheadHelpers& helpers) { -// playheadHelpersReference = &helpers; -//} - -float DelayModule::calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const +float DelayModule::calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) const { - //calculate tempo sync delay in samples - auto beatsPerSecond = static_cast (bpm / 60); - auto secondsPerBeat = 1/beatsPerSecond; - - return floor(noteDuration * secondsPerBeat * fs); + return static_cast (timeInSeconds * sampleRate); } bool DelayModule::getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index 9f79f6da..56a702c6 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -16,8 +16,7 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; - float calculateTempoSyncDelayTime(const float noteDuration, const double bpm) const; -// void setPlayheadHelpersReference(PlayheadHelpers& helpers); + float calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) const; private: template From 26730564d9c6b44bcbb218aa0599588bff8627dc Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Thu, 2 Nov 2023 16:08:24 +0000 Subject: [PATCH 08/14] Comments and Cout Statements Removed --- src/processors/other/Delay.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 0421e723..2bdfff14 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -236,43 +236,32 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { - std::cout << playheadHelpers->bpm << std::endl; - double tempo = playheadHelpers->bpm.load(); - std::cout << "My BPM: " << tempo << std::endl; - feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); + double tempo = playheadHelpers->bpm.load(); auto tempoSync = (int)*tempoSyncOnOffParam; if (!tempoSync) { - std::cout << "Delay Time In Ms..." << std::endl; - delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); //delay time in samples (if tempo-sync change the calculation here?) + delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); } else { - float delayInSamples = fs * 200 * 0.001f; //fallback delay - std::cout << "Delay Time In Notes..." << std::endl; - auto positionInfo = audioPlayHead.getPosition(); - + float delayInSamples = fs * 200 * 0.001f; auto noteDivision = (int)*delayTimeTempoSyncParam; if (noteDivision == 0) { delayInSamples = calculateTempoSyncDelayTime(HALF.getTimeSeconds(tempo), fs); - std::cout << "1/2 Note Delay..." << std::endl; } else if (noteDivision == 1) { delayInSamples = calculateTempoSyncDelayTime(QUARTER.getTimeSeconds(tempo), fs); - std::cout << "1/4 Note Delay..." << std::endl; } else if (noteDivision == 2) { delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds(tempo), fs); - std::cout << "1/8 Note Delay..." << std::endl; } else if (noteDivision == 3) { delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds(tempo), fs); - std::cout << "1/8 Note Dotted Delay..." << std::endl; } delaySmooth.setTargetValue (delayInSamples); } From e5ec4b5cea286cf04a93218d8fdc8a56790f74aa Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Thu, 2 Nov 2023 16:48:59 +0000 Subject: [PATCH 09/14] Delay Parameter Names Changed for Clarity --- src/processors/other/Delay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 2bdfff14..eb4e0ad3 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -15,7 +15,7 @@ const String mixTag = "mix"; const String delayTimeMsTag = "time_ms"; const String tempoSyncTag = "tempo_sync"; -const String tempoSyncAmountTag = "delay_time_type"; +const String tempoSyncAmountTag = "time_tempo_sync"; } // namespace DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParameterLayout(), um) @@ -52,10 +52,10 @@ ParamLayout DelayModule::createParameterLayout() emplace_param (params, tempoSyncAmountTag, - "Tempo Sync", + "Tempo Sync Delay", StringArray { "1/2", "1/4", "1/8" , "1/8 dotted"}, 0); - emplace_param (params, tempoSyncTag, "Tempo Sync Delay", false); + emplace_param (params, tempoSyncTag, "Tempo Sync", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); emplace_param (params, pingPongTag, "Ping-Pong", false); From 54836bf653cd18028f957fb3489ffc191af2c9f1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 2 Nov 2023 16:52:24 +0000 Subject: [PATCH 10/14] Apply clang-format --- src/BYOD.h | 2 +- src/processors/other/Delay.cpp | 30 +++++++++++++++--------------- src/processors/other/Delay.h | 8 +++++--- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/BYOD.h b/src/BYOD.h index 074eada4..e526a311 100644 --- a/src/BYOD.h +++ b/src/BYOD.h @@ -1,8 +1,8 @@ #pragma once +#include "processors/PlayheadHelpers.h" #include "processors/ProcessorStore.h" #include "processors/chain/ProcessorChain.h" -#include "processors/PlayheadHelpers.h" #include "state/ParamForwardManager.h" #include "state/StateManager.h" diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index eb4e0ad3..cd7088c9 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -53,7 +53,7 @@ ParamLayout DelayModule::createParameterLayout() emplace_param (params, tempoSyncAmountTag, "Tempo Sync Delay", - StringArray { "1/2", "1/4", "1/8" , "1/8 dotted"}, + StringArray { "1/2", "1/4", "1/8", "1/8 dotted" }, 0); emplace_param (params, tempoSyncTag, "Tempo Sync", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); @@ -238,30 +238,30 @@ void DelayModule::processAudio (AudioBuffer& buffer) { feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); double tempo = playheadHelpers->bpm.load(); - auto tempoSync = (int)*tempoSyncOnOffParam; - if (!tempoSync) + auto tempoSync = (int) *tempoSyncOnOffParam; + if (! tempoSync) { delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); } else { float delayInSamples = fs * 200 * 0.001f; - auto noteDivision = (int)*delayTimeTempoSyncParam; + auto noteDivision = (int) *delayTimeTempoSyncParam; if (noteDivision == 0) { - delayInSamples = calculateTempoSyncDelayTime(HALF.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (HALF.getTimeSeconds (tempo), fs); } else if (noteDivision == 1) { - delayInSamples = calculateTempoSyncDelayTime(QUARTER.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (QUARTER.getTimeSeconds (tempo), fs); } else if (noteDivision == 2) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds (tempo), fs); } else if (noteDivision == 3) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds (tempo), fs); } delaySmooth.setTargetValue (delayInSamples); } @@ -308,7 +308,7 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } -float DelayModule::calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) const +float DelayModule::calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) const { return static_cast (timeInSeconds * sampleRate); } @@ -323,7 +323,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd : vts (vtState), tempoSyncSelectorAttach (vts, tempoSyncAmountTag, tempoSyncSelector), delayTimeSlider (*getParameterPointer (vts, delayTimeMsTag), hcp), - delayTimeAttach(vts, delayTimeMsTag, delayTimeSlider), + delayTimeAttach (vts, delayTimeMsTag, delayTimeSlider), tempoSyncOnOffAttach ( *vts.getParameter (tempoSyncTag), [this] (float newValue) @@ -366,7 +366,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd void updateControlVisibility (bool tempoSyncOn) { tempoSyncSelector.setVisible (tempoSyncOn); - delayTimeSlider.setVisible (!tempoSyncOn); + delayTimeSlider.setVisible (! tempoSyncOn); setName (vts.getParameter (tempoSyncOn ? tempoSyncAmountTag : delayTimeMsTag)->name); if (auto* parent = getParentComponent()) @@ -384,10 +384,10 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd delayTimeSlider.setTextBoxStyle (getTextBoxPosition(), false, getTextBoxWidth(), getTextBoxHeight()); const auto bounds = getLocalBounds(); - tempoSyncSelector.setBounds (bounds.proportionOfWidth(0.15f), - bounds.proportionOfHeight(0.1f), - bounds.proportionOfWidth(0.7f), - bounds.proportionOfHeight(0.25f)); + tempoSyncSelector.setBounds (bounds.proportionOfWidth (0.15f), + bounds.proportionOfHeight (0.1f), + bounds.proportionOfWidth (0.7f), + bounds.proportionOfHeight (0.25f)); delayTimeSlider.setBounds (bounds); } diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index 56a702c6..b6843d70 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -16,7 +16,7 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; - float calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) const; + float calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) const; private: template @@ -24,8 +24,10 @@ class DelayModule : public BaseProcessor template void processPingPongDelay (AudioBuffer& buffer, DelayType& delayLine); - struct SimpleAudioPlayHead : juce::AudioPlayHead { - juce::Optional getPosition() const override { + struct SimpleAudioPlayHead : juce::AudioPlayHead + { + juce::Optional getPosition() const override + { PositionInfo info; return info; } From 68a7be31d43154144d7221c46bb9be4e6d9cebc4 Mon Sep 17 00:00:00 2001 From: rachelmaryamlocke Date: Mon, 6 Nov 2023 23:49:49 +0000 Subject: [PATCH 11/14] Custom Components First and PR Feedback Addressed --- src/processors/chain/ProcessorChain.cpp | 2 -- src/processors/other/Delay.cpp | 45 +++++++++++++------------ src/processors/other/Delay.h | 16 ++------- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/processors/chain/ProcessorChain.cpp b/src/processors/chain/ProcessorChain.cpp index 99fc3201..7fdb0255 100644 --- a/src/processors/chain/ProcessorChain.cpp +++ b/src/processors/chain/ProcessorChain.cpp @@ -69,9 +69,7 @@ void ProcessorChain::initializeProcessors() for (int i = procs.size() - 1; i >= 0; --i) { if (auto* proc = procs[i]) - { proc->prepareProcessing (osSampleRate, osSamplesPerBlock); - } } } diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index cd7088c9..1c249d1b 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -4,6 +4,7 @@ #include "processors/PlayheadHelpers.h" using namespace chowdsp::RhythmUtils; +//using namespace chowdsp::RhythmParameter; namespace { @@ -25,7 +26,7 @@ DelayModule::DelayModule (UndoManager* um) : BaseProcessor ("Delay", createParam loadParameterPointer (feedbackParam, vts, feedBackTag); loadParameterPointer (mixParam, vts, mixTag); loadParameterPointer (delayTimeMsParam, vts, delayTimeMsTag); - delayTimeTempoSyncParam = vts.getRawParameterValue (tempoSyncAmountTag); + loadParameterPointer (delayTimeRhythmParam, vts, tempoSyncAmountTag); tempoSyncOnOffParam = vts.getRawParameterValue (tempoSyncTag); delayTypeParam = vts.getRawParameterValue (delayTypeTag); pingPongParam = vts.getRawParameterValue (pingPongTag); @@ -50,11 +51,11 @@ ParamLayout DelayModule::createParameterLayout() createPercentParameter (params, feedBackTag, "Feedback", 0.0f); createPercentParameter (params, mixTag, "Mix", 0.5f); - emplace_param (params, - tempoSyncAmountTag, - "Tempo Sync Delay", - StringArray { "1/2", "1/4", "1/8", "1/8 dotted" }, - 0); + emplace_param( params, + tempoSyncAmountTag, + "Delay Rhythm", + std::initializer_list{HALF, QUARTER, EIGHTH, EIGHTH_DOT}, + HALF ); emplace_param (params, tempoSyncTag, "Tempo Sync", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); emplace_param (params, pingPongTag, "Ping-Pong", false); @@ -238,30 +239,30 @@ void DelayModule::processAudio (AudioBuffer& buffer) { feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); double tempo = playheadHelpers->bpm.load(); - auto tempoSync = (int) *tempoSyncOnOffParam; - if (! tempoSync) + const auto tempoSync = *tempoSyncOnOffParam == 1.0f; + if (!tempoSync) { delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); } else { float delayInSamples = fs * 200 * 0.001f; - auto noteDivision = (int) *delayTimeTempoSyncParam; + auto noteDivision = (int)*delayTimeRhythmParam; if (noteDivision == 0) { - delayInSamples = calculateTempoSyncDelayTime (HALF.getTimeSeconds (tempo), fs); + delayInSamples = calculateTempoSyncDelayTime(HALF.getTimeSeconds(tempo), fs); } else if (noteDivision == 1) { - delayInSamples = calculateTempoSyncDelayTime (QUARTER.getTimeSeconds (tempo), fs); + delayInSamples = calculateTempoSyncDelayTime(QUARTER.getTimeSeconds(tempo), fs); } else if (noteDivision == 2) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds (tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds(tempo), fs); } else if (noteDivision == 3) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds (tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds(tempo), fs); } delaySmooth.setTargetValue (delayInSamples); } @@ -308,7 +309,7 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } -float DelayModule::calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) const +float DelayModule::calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) { return static_cast (timeInSeconds * sampleRate); } @@ -323,7 +324,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd : vts (vtState), tempoSyncSelectorAttach (vts, tempoSyncAmountTag, tempoSyncSelector), delayTimeSlider (*getParameterPointer (vts, delayTimeMsTag), hcp), - delayTimeAttach (vts, delayTimeMsTag, delayTimeSlider), + delayTimeAttach(vts, delayTimeMsTag, delayTimeSlider), tempoSyncOnOffAttach ( *vts.getParameter (tempoSyncTag), [this] (float newValue) @@ -333,7 +334,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd addChildComponent (tempoSyncSelector); addChildComponent (delayTimeSlider); - const auto* modeChoiceParam = getParameterPointer (vts, tempoSyncAmountTag); + const auto* modeChoiceParam = getParameterPointer (vts, tempoSyncAmountTag); tempoSyncSelector.addItemList (modeChoiceParam->choices, 1); tempoSyncSelector.setSelectedItemIndex (0); tempoSyncSelector.setScrollWheelEnabled (true); @@ -366,7 +367,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd void updateControlVisibility (bool tempoSyncOn) { tempoSyncSelector.setVisible (tempoSyncOn); - delayTimeSlider.setVisible (! tempoSyncOn); + delayTimeSlider.setVisible (!tempoSyncOn); setName (vts.getParameter (tempoSyncOn ? tempoSyncAmountTag : delayTimeMsTag)->name); if (auto* parent = getParentComponent()) @@ -384,10 +385,10 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd delayTimeSlider.setTextBoxStyle (getTextBoxPosition(), false, getTextBoxWidth(), getTextBoxHeight()); const auto bounds = getLocalBounds(); - tempoSyncSelector.setBounds (bounds.proportionOfWidth (0.15f), - bounds.proportionOfHeight (0.1f), - bounds.proportionOfWidth (0.7f), - bounds.proportionOfHeight (0.25f)); + tempoSyncSelector.setBounds (bounds.proportionOfWidth(0.15f), + bounds.proportionOfHeight(0.1f), + bounds.proportionOfWidth(0.7f), + bounds.proportionOfHeight(0.25f)); delayTimeSlider.setBounds (bounds); } @@ -410,5 +411,5 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd customComps.add (std::make_unique (vts, hcp)); - return false; + return true; } \ No newline at end of file diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index b6843d70..b007f225 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -1,7 +1,6 @@ #pragma once #include "../BaseProcessor.h" -#include "processors/PlayheadHelpers.h" class DelayModule : public BaseProcessor { @@ -16,7 +15,7 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; - float calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) const; + static float calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate); private: template @@ -24,17 +23,6 @@ class DelayModule : public BaseProcessor template void processPingPongDelay (AudioBuffer& buffer, DelayType& delayLine); - struct SimpleAudioPlayHead : juce::AudioPlayHead - { - juce::Optional getPosition() const override - { - PositionInfo info; - return info; - } - }; - - SimpleAudioPlayHead audioPlayHead; - chowdsp::FloatParameter* freqParam = nullptr; chowdsp::FloatParameter* feedbackParam = nullptr; chowdsp::FloatParameter* mixParam = nullptr; @@ -42,7 +30,7 @@ class DelayModule : public BaseProcessor std::atomic* pingPongParam = nullptr; chowdsp::FloatParameter* delayTimeMsParam = nullptr; - std::atomic* delayTimeTempoSyncParam = nullptr; + chowdsp::RhythmParameter* delayTimeRhythmParam = nullptr; std::atomic* tempoSyncOnOffParam = nullptr; dsp::DryWetMixer dryWetMixer; From c8d23432b7e75237531a20f45d24fd6c39ed97e3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 8 Nov 2023 12:49:10 +0000 Subject: [PATCH 12/14] Apply clang-format --- src/processors/other/Delay.cpp | 32 ++++++++++++++++---------------- src/processors/other/Delay.h | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 1c249d1b..ef7ecb61 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -51,11 +51,11 @@ ParamLayout DelayModule::createParameterLayout() createPercentParameter (params, feedBackTag, "Feedback", 0.0f); createPercentParameter (params, mixTag, "Mix", 0.5f); - emplace_param( params, + emplace_param (params, tempoSyncAmountTag, "Delay Rhythm", - std::initializer_list{HALF, QUARTER, EIGHTH, EIGHTH_DOT}, - HALF ); + std::initializer_list { HALF, QUARTER, EIGHTH, EIGHTH_DOT }, + HALF); emplace_param (params, tempoSyncTag, "Tempo Sync", false); emplace_param (params, delayTypeTag, "Delay Type", StringArray { "Clean", "Lo-Fi" }, 0); emplace_param (params, pingPongTag, "Ping-Pong", false); @@ -240,29 +240,29 @@ void DelayModule::processAudio (AudioBuffer& buffer) feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); double tempo = playheadHelpers->bpm.load(); const auto tempoSync = *tempoSyncOnOffParam == 1.0f; - if (!tempoSync) + if (! tempoSync) { delaySmooth.setTargetValue (fs * *delayTimeMsParam * 0.001f); } else { float delayInSamples = fs * 200 * 0.001f; - auto noteDivision = (int)*delayTimeRhythmParam; + auto noteDivision = (int) *delayTimeRhythmParam; if (noteDivision == 0) { - delayInSamples = calculateTempoSyncDelayTime(HALF.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (HALF.getTimeSeconds (tempo), fs); } else if (noteDivision == 1) { - delayInSamples = calculateTempoSyncDelayTime(QUARTER.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (QUARTER.getTimeSeconds (tempo), fs); } else if (noteDivision == 2) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds (tempo), fs); } else if (noteDivision == 3) { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds(tempo), fs); + delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds (tempo), fs); } delaySmooth.setTargetValue (delayInSamples); } @@ -309,7 +309,7 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } -float DelayModule::calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate) +float DelayModule::calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) { return static_cast (timeInSeconds * sampleRate); } @@ -324,7 +324,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd : vts (vtState), tempoSyncSelectorAttach (vts, tempoSyncAmountTag, tempoSyncSelector), delayTimeSlider (*getParameterPointer (vts, delayTimeMsTag), hcp), - delayTimeAttach(vts, delayTimeMsTag, delayTimeSlider), + delayTimeAttach (vts, delayTimeMsTag, delayTimeSlider), tempoSyncOnOffAttach ( *vts.getParameter (tempoSyncTag), [this] (float newValue) @@ -367,7 +367,7 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd void updateControlVisibility (bool tempoSyncOn) { tempoSyncSelector.setVisible (tempoSyncOn); - delayTimeSlider.setVisible (!tempoSyncOn); + delayTimeSlider.setVisible (! tempoSyncOn); setName (vts.getParameter (tempoSyncOn ? tempoSyncAmountTag : delayTimeMsTag)->name); if (auto* parent = getParentComponent()) @@ -385,10 +385,10 @@ bool DelayModule::getCustomComponents (OwnedArray& customComps, chowd delayTimeSlider.setTextBoxStyle (getTextBoxPosition(), false, getTextBoxWidth(), getTextBoxHeight()); const auto bounds = getLocalBounds(); - tempoSyncSelector.setBounds (bounds.proportionOfWidth(0.15f), - bounds.proportionOfHeight(0.1f), - bounds.proportionOfWidth(0.7f), - bounds.proportionOfHeight(0.25f)); + tempoSyncSelector.setBounds (bounds.proportionOfWidth (0.15f), + bounds.proportionOfHeight (0.1f), + bounds.proportionOfWidth (0.7f), + bounds.proportionOfHeight (0.25f)); delayTimeSlider.setBounds (bounds); } diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index b007f225..c12e8b74 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -15,7 +15,7 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; - static float calculateTempoSyncDelayTime(const double timeInSeconds, const double sampleRate); + static float calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate); private: template From ec3674b0c16a0b83e253747de0d5e51ee6efd3fa Mon Sep 17 00:00:00 2001 From: jatin Date: Wed, 8 Nov 2023 09:22:36 -0800 Subject: [PATCH 13/14] Fixing headless and small delay rhythm parameter cleanup --- src/headless/CMakeLists.txt | 1 + src/processors/other/Delay.cpp | 25 ++----------------------- src/processors/other/Delay.h | 1 - 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src/headless/CMakeLists.txt b/src/headless/CMakeLists.txt index 9bee559b..64722963 100644 --- a/src/headless/CMakeLists.txt +++ b/src/headless/CMakeLists.txt @@ -42,6 +42,7 @@ target_include_directories(BYOD_headless ../../modules/chowdsp_utils/modules/gui ../../modules/chowdsp_utils/modules/plugin ../../modules/chowdsp_utils/modules/common + ../../modules/chowdsp_utils/modules/music ../../modules/JUCE/modules ../../modules/chowdsp_wdf/include ../../modules/ea_variant diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index ef7ecb61..7955baee 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -246,24 +246,8 @@ void DelayModule::processAudio (AudioBuffer& buffer) } else { - float delayInSamples = fs * 200 * 0.001f; - auto noteDivision = (int) *delayTimeRhythmParam; - if (noteDivision == 0) - { - delayInSamples = calculateTempoSyncDelayTime (HALF.getTimeSeconds (tempo), fs); - } - else if (noteDivision == 1) - { - delayInSamples = calculateTempoSyncDelayTime (QUARTER.getTimeSeconds (tempo), fs); - } - else if (noteDivision == 2) - { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH.getTimeSeconds (tempo), fs); - } - else if (noteDivision == 3) - { - delayInSamples = calculateTempoSyncDelayTime (EIGHTH_DOT.getTimeSeconds (tempo), fs); - } + const auto delayInSeconds = delayTimeRhythmParam->getRhythmTimeSeconds (tempo); + const auto delayInSamples = static_cast (delayInSeconds) * fs; delaySmooth.setTargetValue (delayInSamples); } freqSmooth.setTargetValue (*freqParam); @@ -309,11 +293,6 @@ void DelayModule::processAudioBypassed (AudioBuffer& buffer) outputBuffers.getReference (0) = &buffer; } -float DelayModule::calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate) -{ - return static_cast (timeInSeconds * sampleRate); -} - bool DelayModule::getCustomComponents (OwnedArray& customComps, chowdsp::HostContextProvider& hcp) { using namespace chowdsp::ParamUtils; diff --git a/src/processors/other/Delay.h b/src/processors/other/Delay.h index c12e8b74..03e0513d 100644 --- a/src/processors/other/Delay.h +++ b/src/processors/other/Delay.h @@ -15,7 +15,6 @@ class DelayModule : public BaseProcessor void releaseMemory() override; void processAudio (AudioBuffer& buffer) override; void processAudioBypassed (AudioBuffer& buffer) override; - static float calculateTempoSyncDelayTime (const double timeInSeconds, const double sampleRate); private: template From 930715c76c60c8ffcde45df8669a6b03acbb6dbe Mon Sep 17 00:00:00 2001 From: jatin Date: Wed, 8 Nov 2023 10:01:15 -0800 Subject: [PATCH 14/14] More unit test fixes --- src/headless/tests/UnitTests.h | 2 ++ src/processors/other/Delay.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/headless/tests/UnitTests.h b/src/headless/tests/UnitTests.h index 79c74447..5cf98d7a 100644 --- a/src/headless/tests/UnitTests.h +++ b/src/headless/tests/UnitTests.h @@ -2,6 +2,7 @@ static inline void runTestForAllProcessors (UnitTest* ut, const std::function& testFunc, const StringArray& procsToSkip = {}) { + PlayheadHelpers playheadHelper; for (auto [name, storeEntry] : ProcessorStore::getStoreMap()) { if (procsToSkip.contains (name)) @@ -11,6 +12,7 @@ static inline void runTestForAllProcessors (UnitTest* ut, const std::functionplayheadHelpers = &playheadHelper; ut->beginTest (proc->getName() + " Test"); testFunc (proc.get()); proc->freeInternalMemory(); diff --git a/src/processors/other/Delay.cpp b/src/processors/other/Delay.cpp index 7955baee..348c4e31 100644 --- a/src/processors/other/Delay.cpp +++ b/src/processors/other/Delay.cpp @@ -237,8 +237,10 @@ void DelayModule::processPingPongDelay (AudioBuffer& buffer, DelayType& d void DelayModule::processAudio (AudioBuffer& buffer) { + jassert (playheadHelpers != nullptr); + feedbackSmoothBuffer.process (std::pow (feedbackParam->getCurrentValue() * 0.67f, 0.9f), buffer.getNumSamples()); - double tempo = playheadHelpers->bpm.load(); + const auto tempo = playheadHelpers->bpm.load(); const auto tempoSync = *tempoSyncOnOffParam == 1.0f; if (! tempoSync) {