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) };