diff --git a/Source/DelayEngine.h b/Source/DelayEngine.h index 8c92ff4..f81d6a0 100644 --- a/Source/DelayEngine.h +++ b/Source/DelayEngine.h @@ -34,6 +34,7 @@ public: bool doubleTap = false; bool center = false; bool autoPan = false; + bool fbBoost = false; float panDepth = 1.0f; double bpm = 120.0; }; @@ -206,7 +207,7 @@ public: wetR *= gR; } - const float fb = sFeedback * 0.91f; + const float fb = sFeedback * (p.fbBoost ? 1.15f : 0.91f); const float g = fb * (1.0f + 0.1f * std::pow (fb, 4.0f)); dl.write (inL[i] + softClip (lpL.processLP (hpL.processHP (fbL * g)))); dr.write (inR[i] + softClip (lpR.processLP (hpR.processHP (fbR * g)))); diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index e6336b3..7d8ce31 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -18,6 +18,7 @@ public: doubleToggle ("DOUBLE"), centerToggle ("CENTER"), autoPanToggle ("AUTO-PAN"), + fbBoostToggle ("FB BOOST"), onToggle ("ON"), modeToggle (p.apvts), dryMeter ("DRY"), @@ -31,6 +32,7 @@ public: doubleAtt (p.apvts, ParameterIDs::doubleTap, doubleToggle), centerAtt (p.apvts, ParameterIDs::center, centerToggle), autoPanAtt (p.apvts, ParameterIDs::autopan, autoPanToggle), + fbBoostAtt (p.apvts, ParameterIDs::fbBoost, fbBoostToggle), onAtt (p.apvts, ParameterIDs::bypass, onToggle) { for (auto* c : { static_cast (&feedbackKnob), static_cast (&loCutKnob), @@ -38,13 +40,18 @@ public: static_cast (&mixKnob), static_cast (&panKnob), static_cast (&syncToggle), static_cast (&modeToggle), static_cast (&doubleToggle), static_cast (¢erToggle), - static_cast (&autoPanToggle), static_cast (&onToggle) }) + static_cast (&autoPanToggle), static_cast (&fbBoostToggle), + static_cast (&onToggle) }) addAndMakeVisible (c); addAndMakeVisible (dryMeter); addAndMakeVisible (wetMeter); - feedbackKnob.setValueTextFunction ([] (double v) { return juce::String (juce::roundToInt (v * 100.0)) + "%"; }); + feedbackKnob.setValueTextFunction ([this] (double v) + { + const double maxPct = fbBoostToggle.getToggleState() ? 115.0 : 100.0; + return juce::String (juce::roundToInt (v * maxPct)) + "%"; + }); loCutKnob.setValueTextFunction ([] (double v) { return formatHz (v); }); hiCutKnob.setValueTextFunction ([] (double v) { return formatHz (v); }); timeKnob.setValueTextFunction ([this] (double v) @@ -56,6 +63,7 @@ public: mixKnob.setValueTextFunction ([] (double v) { return juce::String (juce::roundToInt (v * 100.0)) + "%"; }); panKnob.setValueTextFunction ([] (double v) { return juce::String (juce::roundToInt (v * 100.0)) + "%"; }); onToggle.setInverted (true); + fbBoostToggle.onClick = [this] { feedbackKnob.repaint(); }; syncToggle.onClick = [this] { @@ -153,12 +161,16 @@ public: } x = margin; + const int numToggles = 7; + const int toggleW = 80; + const int toggleGap = (width - 2 * margin - numToggles * toggleW) / (numToggles - 1); for (auto* toggle : { static_cast (&onToggle), static_cast (&modeToggle), static_cast (&doubleToggle), static_cast (&syncToggle), - static_cast (&autoPanToggle), static_cast (¢erToggle) }) + static_cast (&autoPanToggle), static_cast (&fbBoostToggle), + static_cast (¢erToggle) }) { - toggle->setBounds (x, 146, knobW, 30); - x += knobW + gap; + toggle->setBounds (x, 146, toggleW, 30); + x += toggleW + toggleGap; } const int meterW = (width - 2 * margin - 20) / 2; @@ -199,12 +211,12 @@ private: static const juce::StringArray syncDivisionNames; Knob feedbackKnob, loCutKnob, hiCutKnob, timeKnob, mixKnob, panKnob; - PillToggle syncToggle, doubleToggle, centerToggle, autoPanToggle, onToggle; + PillToggle syncToggle, doubleToggle, centerToggle, autoPanToggle, fbBoostToggle, onToggle; ModeToggle modeToggle; LevelMeter dryMeter, wetMeter; SliderAttachment feedbackAtt, loCutAtt, hiCutAtt, mixAtt, panAtt; - ButtonAttachment syncAtt, doubleAtt, centerAtt, autoPanAtt, onAtt; + ButtonAttachment syncAtt, doubleAtt, centerAtt, autoPanAtt, fbBoostAtt, onAtt; std::unique_ptr timeAtt, timeSyncAtt; juce::Label buildInfo; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 0b60362..06d80cd 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -44,6 +44,7 @@ juce::AudioProcessorValueTreeState::ParameterLayout MindballAudioProcessor::crea layout.add (std::make_unique (ParameterIDs::doubleTap, "Double", false)); layout.add (std::make_unique (ParameterIDs::center, "Center", false)); layout.add (std::make_unique (ParameterIDs::autopan, "Auto-Pan", false)); + layout.add (std::make_unique (ParameterIDs::fbBoost, "FB Boost", false)); layout.add (std::make_unique ( ParameterIDs::panDepth, "Pan Depth", juce::NormalisableRange (0.0f, 1.0f, 0.001f, 1.0f), 1.0f)); @@ -135,6 +136,7 @@ void MindballAudioProcessor::processBlock (juce::AudioBuffer& buffer, juc p.doubleTap = *apvts.getRawParameterValue (ParameterIDs::doubleTap) > 0.5f; p.center = *apvts.getRawParameterValue (ParameterIDs::center) > 0.5f; p.autoPan = *apvts.getRawParameterValue (ParameterIDs::autopan) > 0.5f; + p.fbBoost = *apvts.getRawParameterValue (ParameterIDs::fbBoost) > 0.5f; p.panDepth = *apvts.getRawParameterValue (ParameterIDs::panDepth); p.bpm = bpm; diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index b465b8f..5dcc0e4 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -18,6 +18,7 @@ namespace ParameterIDs inline constexpr const char* center = "center"; inline constexpr const char* autopan = "autopan"; inline constexpr const char* panDepth = "pandepth"; + inline constexpr const char* fbBoost = "fbboost"; inline constexpr const char* bypass = "bypass"; }