diff --git a/AudioTracks/drumLoop120BPM.wav.reapeaks b/AudioTracks/drumLoop120BPM.wav.reapeaks new file mode 100644 index 0000000..94db121 Binary files /dev/null and b/AudioTracks/drumLoop120BPM.wav.reapeaks differ diff --git a/QuasoCompressor.jucer b/QuasoCompressor.jucer index b787c15..622f4ad 100644 --- a/QuasoCompressor.jucer +++ b/QuasoCompressor.jucer @@ -27,6 +27,10 @@ + + diff --git a/Source/GUI/Buttons/Buttons.cpp b/Source/GUI/Buttons/Buttons.cpp index 46cd72d..ec0d40a 100644 --- a/Source/GUI/Buttons/Buttons.cpp +++ b/Source/GUI/Buttons/Buttons.cpp @@ -13,4 +13,12 @@ void QuasoCompressorAudioProcessorEditor::setButtonProps(juce::ToggleButton& button) { addAndMakeVisible(button); + button.setLookAndFeel(&buttonLAF); } + + +void QuasoCompressorAudioProcessorEditor::attachButtons() +{ + using ButtonAttachment = juce::AudioProcessorValueTreeState::ButtonAttachment; + compBypassAttach = std::make_unique(audioProcessor.apvts, compBypassID, compBypassButton); +} \ No newline at end of file diff --git a/Source/GUI/LookAndFeel/ToggleButtonLAF.cpp b/Source/GUI/LookAndFeel/ToggleButtonLAF.cpp new file mode 100644 index 0000000..05f0ab8 --- /dev/null +++ b/Source/GUI/LookAndFeel/ToggleButtonLAF.cpp @@ -0,0 +1,52 @@ +/* + ============================================================================== + + ToggleButtonLAF.cpp + Created: 8 Feb 2023 11:21:46am + Author: Utente + + ============================================================================== +*/ + +#include "ToggleButtonLAF.h" + +void PowerToggleLAF::drawToggleButton +( + juce::Graphics& g, + juce::ToggleButton& toggleButton, + bool shouldDrawButtonAsHighlighted, + bool shouldDrawButtonAsDown +) +{ + Path button; + + auto bounds = toggleButton.getLocalBounds(); + + auto size = jmin(bounds.getWidth(), bounds.getHeight()) - 6; + auto r = bounds.withSizeKeepingCentre(size, size).toFloat(); + + float ang = 30.f; + + size -= 9; + + + button.addCentredArc(r.getCentreX(), + r.getCentreY(), + size * 0.25, + size * 0.25, + 0.f, + degreesToRadians(ang), + degreesToRadians(360.f - ang), + true); + + button.startNewSubPath(r.getCentreX(), r.getY() + r.getHeight() * 0.21); + button.lineTo(r.getCentre()); + + PathStrokeType pst(2.5f, PathStrokeType::JointStyle::curved); + + auto color = + toggleButton.getToggleState() ? toggleButton.findColour(juce::ToggleButton::tickDisabledColourId) : toggleButton.findColour(juce::ToggleButton::tickColourId); + + g.setColour(color); + g.strokePath(button, pst); +} diff --git a/Source/GUI/LookAndFeel/ToggleButtonLAF.h b/Source/GUI/LookAndFeel/ToggleButtonLAF.h new file mode 100644 index 0000000..068c16b --- /dev/null +++ b/Source/GUI/LookAndFeel/ToggleButtonLAF.h @@ -0,0 +1,27 @@ +/* + ============================================================================== + + ToggleButtonLAF.h + Created: 8 Feb 2023 11:21:46am + Author: Utente + + ============================================================================== +*/ + +#pragma once +#include + +class PowerToggleLAF : public LookAndFeel_V4 +{ + +public: + + + void drawToggleButton + ( + juce::Graphics& g, + juce::ToggleButton& toggleButton, + bool shouldDrawButtonAsHighlighted, + bool shouldDrawButtonAsDown + ) override; +}; diff --git a/Source/Parameters/Parameters.cpp b/Source/Parameters/Parameters.cpp index 63a7e60..fc5ecde 100644 --- a/Source/Parameters/Parameters.cpp +++ b/Source/Parameters/Parameters.cpp @@ -13,6 +13,9 @@ const juce::String inputID = "input"; const juce::String inputName = "Input"; +const juce::String compBypassID = "compBypass"; +const juce::String compBypassName = "Compressor Bypass"; + const juce::String threshID = "thresh"; const juce::String threshName = "Thresh"; @@ -25,6 +28,9 @@ const juce::String attackName = "Attack"; const juce::String releaseID = "release"; const juce::String releaseName = "Release"; +const juce::String limBypassID = "limBypass"; +const juce::String limBypassName = "Limiter Bypass"; + const juce::String limThreshID = "limThresh"; const juce::String limThreshName = "Limiter Thresh"; diff --git a/Source/Parameters/Parameters.h b/Source/Parameters/Parameters.h index 6ec6304..4019647 100644 --- a/Source/Parameters/Parameters.h +++ b/Source/Parameters/Parameters.h @@ -14,6 +14,9 @@ extern const juce::String inputID; extern const juce::String inputName; +extern const juce::String compBypassID; +extern const juce::String compBypassName; + extern const juce::String threshID; extern const juce::String threshName; @@ -26,6 +29,9 @@ extern const juce::String attackName; extern const juce::String releaseID; extern const juce::String releaseName; +extern const juce::String limBypassID; +extern const juce::String limBypassName; + extern const juce::String limThreshID; extern const juce::String limThreshName; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index e5b3c32..aa61220 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -59,6 +59,7 @@ QuasoCompressorAudioProcessorEditor::QuasoCompressorAudioProcessorEditor (QuasoC attachSliders(); + attachButtons(); setSize(1000, 500); @@ -124,9 +125,9 @@ void QuasoCompressorAudioProcessorEditor::resized() // //flexboxRowTwo.items = itemArrayRowTwo; //flexboxRowTwo.performLayout(getLocalBounds().withY(getHeight() * 0.5).withHeight(getHeight()*0.5)); - inputDial.setBounds(leftMargin, 50, dialSize, dialSize); - threshDial.setBounds(mainLeftMargin, 50, dialSize, dialSize); - ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 50, dialSize, dialSize); + inputDial.setBounds(leftMargin, 65, dialSize, dialSize); + threshDial.setBounds(mainLeftMargin, 65, dialSize, dialSize); + ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 65, dialSize, dialSize); ioGroup.setBounds(inputDial.getX(), inputDial.getY() * 0.1, inputDial.getWidth(), inputDial.getY() + inputDial.getHeight() * 2.4); @@ -144,7 +145,7 @@ void QuasoCompressorAudioProcessorEditor::resized() limiterGroup.setBounds(limThreshDial.getX(), limThreshDial.getY() * 0.1, limThreshDial.getWidth(), limThreshDial.getY() + limThreshDial.getHeight() * 2.4); - compBypassButton.setBounds(ratioDial.getX() , getLocalBounds().getY() / 2, 100, 100); + compBypassButton.setBounds(compressorGroup.getRight() - 46, compressorGroup.getBottom() - 46, 50, 50); diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 2d51fb0..e3239d3 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -11,6 +11,7 @@ #include #include "PluginProcessor.h" #include "GUI/LookAndFeel/DialLAF.h" +#include "GUI/LookAndFeel/ToggleButtonLAF.h" //============================================================================== /** @@ -42,6 +43,7 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor //using custom look and feel DialStyle customDialLAF; + PowerToggleLAF buttonLAF; //shadows juce::DropShadow shadowProperties; @@ -115,19 +117,22 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor void setButtonProps(juce::ToggleButton& button); //setting up attachment - using Attachment = std::unique_ptr; - - Attachment inputAttach; - Attachment threshAttach; - Attachment ratioAttach; - Attachment attackAttach; - Attachment releaseAttach; - Attachment limThreshAttach; - Attachment limReleaseAttach; - Attachment outputAttach; + using ButtonAttachment = std::unique_ptr; + ButtonAttachment compBypassAttach; + + using SliderAttachment = std::unique_ptr; + SliderAttachment inputAttach; + SliderAttachment threshAttach; + SliderAttachment ratioAttach; + SliderAttachment attackAttach; + SliderAttachment releaseAttach; + SliderAttachment limThreshAttach; + SliderAttachment limReleaseAttach; + SliderAttachment outputAttach; //method to attach sliders to the apvts void attachSliders(); + void attachButtons(); diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 36928eb..958acb8 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -28,10 +28,12 @@ QuasoCompressorAudioProcessor::QuasoCompressorAudioProcessor() //every paramaters needs a listener inside the constructor of the main AudioProcessor class //everything the listener receives a changes from its parameter ID the parameterChanged method is called apvts.addParameterListener(inputID, this); + apvts.addParameterListener(compBypassID, this); apvts.addParameterListener(threshID, this); apvts.addParameterListener(ratioID, this); apvts.addParameterListener(attackID, this); apvts.addParameterListener(releaseID, this); + //apvts.addParameterListener(limBypassID, this); apvts.addParameterListener(limThreshID, this); apvts.addParameterListener(limReleaseID, this); apvts.addParameterListener(outputID, this); @@ -41,10 +43,12 @@ QuasoCompressorAudioProcessor::~QuasoCompressorAudioProcessor() { //the listener for each parameter has to be removed in the destructor apvts.removeParameterListener(inputID, this); + apvts.removeParameterListener(compBypassID, this); apvts.removeParameterListener(threshID, this); apvts.removeParameterListener(ratioID, this); apvts.removeParameterListener(attackID, this); apvts.removeParameterListener(releaseID, this); + //apvts.removeParameterListener(limBypassID, this); apvts.removeParameterListener(limThreshID, this); apvts.removeParameterListener(limReleaseID, this); apvts.removeParameterListener(outputID, this); @@ -69,20 +73,24 @@ juce::AudioProcessorValueTreeState::ParameterLayout QuasoCompressorAudioProcesso //parameters are created auto pInput = std::make_unique(inputID, inputName, -60.0f, 24.0f, 0.0f); + auto pBypass = std::make_unique(compBypassID, compBypassName, false); auto pThresh = std::make_unique(threshID, threshName, -60.0f, 12.0f, 0.0f); auto pRatio = std::make_unique(ratioID, ratioName, 1.0f, 20.0f, 1.0f); auto pAttack = std::make_unique(attackID, attackName, attackRange, 50.0f); auto pRelease = std::make_unique(releaseID, releaseName, releaseRange, 160.0f); + //auto pLimBypass = std::make_unique(limBypassID, limBypassName, false); auto pLimThresh = std::make_unique(limThreshID, limThreshName, -60.0f, 0.0f, 160.0f); auto pLimRelease = std::make_unique(limReleaseID, limReleaseName, limReleaseRange, 250.0f); auto pOutput = std::make_unique(outputID, outputName, -60.0f, 24.0f, 0.0f); //different type of parameters like floats or selection are pushed into the params vector params.push_back(std::move(pInput)); + params.push_back(std::move(pBypass)); params.push_back(std::move(pThresh)); params.push_back(std::move(pRatio)); params.push_back(std::move(pAttack)); params.push_back(std::move(pRelease)); + //params.push_back(std::move(pLimBypass)); params.push_back(std::move(pLimThresh)); params.push_back(std::move(pLimRelease)); params.push_back(std::move(pOutput)); @@ -102,6 +110,7 @@ void QuasoCompressorAudioProcessor::updateParameters() { //the load method is needed because the raw parameters are atomic inputModule.setGainDecibels(apvts.getRawParameterValue(inputID)->load()); + customCompressorModule.setBypass(apvts.getRawParameterValue(compBypassID)->load()); customCompressorModule.setThreshold(apvts.getRawParameterValue(threshID)->load()); customCompressorModule.setRatio(apvts.getRawParameterValue(ratioID)->load()); customCompressorModule.setAttack(apvts.getRawParameterValue(attackID)->load());