From 57e38cae1547c083e78414aec2ec06afa6a60cfc Mon Sep 17 00:00:00 2001 From: Alberto Roletto <73691506+sadmemelord@users.noreply.github.com> Date: Wed, 8 Feb 2023 18:51:16 +0100 Subject: [PATCH] cleaner GUI look and code addes comments and methods to clean up the code --- Source/DSP/CustomCompressor.cpp | 2 + Source/DSP/CustomCompressor.h | 2 +- Source/GUI/Buttons/Buttons.cpp | 2 + Source/GUI/Groups/Groups.cpp | 1 + Source/GUI/Labels/Labels.cpp | 13 ++++ Source/GUI/Sliders/SliderProps.cpp | 26 ++++++- Source/PluginEditor.cpp | 114 ++++++++++------------------- Source/PluginEditor.h | 40 ++++------ Source/PluginProcessor.cpp | 12 ++- Source/PluginProcessor.h | 13 ++-- 10 files changed, 109 insertions(+), 116 deletions(-) diff --git a/Source/DSP/CustomCompressor.cpp b/Source/DSP/CustomCompressor.cpp index 64b11ea..ea4368e 100644 --- a/Source/DSP/CustomCompressor.cpp +++ b/Source/DSP/CustomCompressor.cpp @@ -36,11 +36,13 @@ void CustomCompressor::setRatio(float newRatio) void CustomCompressor::setAttack(float newAttack) { + //attack is in expressed in milliseconds _attack = newAttack / 1000.0f; } void CustomCompressor::setRelease(float newRelease) { + //release is in expressed in milliseconds _release = newRelease / 1000.0f; } diff --git a/Source/DSP/CustomCompressor.h b/Source/DSP/CustomCompressor.h index 824e09b..ba18137 100644 --- a/Source/DSP/CustomCompressor.h +++ b/Source/DSP/CustomCompressor.h @@ -24,8 +24,8 @@ class CustomCompressor //the process method is defined in the header file //because it is passed through the translation unit //and has a better chance of being optimized + //bypassing the dsp - if (_isBypassed == true) return; diff --git a/Source/GUI/Buttons/Buttons.cpp b/Source/GUI/Buttons/Buttons.cpp index ec0d40a..410aa6f 100644 --- a/Source/GUI/Buttons/Buttons.cpp +++ b/Source/GUI/Buttons/Buttons.cpp @@ -12,6 +12,7 @@ void QuasoCompressorAudioProcessorEditor::setButtonProps(juce::ToggleButton& button) { + //setting up group properties addAndMakeVisible(button); button.setLookAndFeel(&buttonLAF); } @@ -19,6 +20,7 @@ void QuasoCompressorAudioProcessorEditor::setButtonProps(juce::ToggleButton& but void QuasoCompressorAudioProcessorEditor::attachButtons() { + //attaching the buttons to the related apvts parameters using ButtonAttachment = juce::AudioProcessorValueTreeState::ButtonAttachment; compBypassAttach = std::make_unique(audioProcessor.apvts, compBypassID, compBypassButton); } \ No newline at end of file diff --git a/Source/GUI/Groups/Groups.cpp b/Source/GUI/Groups/Groups.cpp index 419416b..45a123b 100644 --- a/Source/GUI/Groups/Groups.cpp +++ b/Source/GUI/Groups/Groups.cpp @@ -12,6 +12,7 @@ void QuasoCompressorAudioProcessorEditor::setGroupProps(juce::GroupComponent& group) { + //setting group properties addAndMakeVisible(group); group.setColour(group.outlineColourId, juce::Colours::darkgrey); ioGroup.setText("I/O"); diff --git a/Source/GUI/Labels/Labels.cpp b/Source/GUI/Labels/Labels.cpp index aabb49e..8d5e19f 100644 --- a/Source/GUI/Labels/Labels.cpp +++ b/Source/GUI/Labels/Labels.cpp @@ -17,3 +17,16 @@ void QuasoCompressorAudioProcessorEditor::setCommonLabelProps(juce::Label& label label.setFont(juce::Font("Helvetica", 16.0f, juce::Font::FontStyleFlags::bold)); label.setJustificationType(juce::Justification::centred); } + +void QuasoCompressorAudioProcessorEditor::setLabelText() +{ + //setting the text for each label + inputDialLabel.setText("Input", juce::dontSendNotification); + threshDialLabel.setText("Threshold", juce::dontSendNotification); + ratioDialLabel.setText("Ratio", juce::dontSendNotification); + attackDialLabel.setText("Attack", juce::dontSendNotification); + releaseDialLabel.setText("Release", juce::dontSendNotification); + limThreshDialLabel.setText("Threshold", juce::dontSendNotification); + limReleaseDialLabel.setText("Release", juce::dontSendNotification); + outputDialLabel.setText("Output", juce::dontSendNotification); +} diff --git a/Source/GUI/Sliders/SliderProps.cpp b/Source/GUI/Sliders/SliderProps.cpp index 92719e6..3c6a1f0 100644 --- a/Source/GUI/Sliders/SliderProps.cpp +++ b/Source/GUI/Sliders/SliderProps.cpp @@ -28,15 +28,39 @@ void QuasoCompressorAudioProcessorEditor::setCommonSliderProps(juce::Slider& sli slider.setLookAndFeel(&customDialLAF); +} + +void QuasoCompressorAudioProcessorEditor::setShadowProps(juce::Slider& slider) +{ //setting shadow properties based on the juce::shadowdrop shadowProperties.radius = 25; - shadowProperties.offset = juce::Point(0,0); + shadowProperties.offset = juce::Point(0, 0); shadowProperties.colour = juce::Colours::black.brighter(0.05); dialShadow.setShadowProperties(shadowProperties); slider.setComponentEffect(&dialShadow); } + +void QuasoCompressorAudioProcessorEditor::setUniqueSliderProps() +{ + //some properties are different between dials like the textbox suffix + inputDial.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); + inputDial.setTextValueSuffix(" dB"); + threshDial.setTextValueSuffix(" dB"); + attackDial.setTextValueSuffix(" ms"); + releaseDial.setTextValueSuffix(" ms"); + limThreshDial.setColour(juce::Slider::ColourIds::thumbColourId, + limThreshDial.findColour(juce::Slider::ColourIds::thumbColourId).withSaturation(0.85)); + limThreshDial.setTextValueSuffix(" dB"); + limReleaseDial.setColour(juce::Slider::ColourIds::thumbColourId, + limReleaseDial.findColour(juce::Slider::ColourIds::thumbColourId).withSaturation(0.85)); + limReleaseDial.setTextValueSuffix(" ms"); + outputDial.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); + outputDial.setTextValueSuffix(" dB"); + +} + void QuasoCompressorAudioProcessorEditor::attachSliders() { //method to attach dials to apvts diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index aa61220..d3a3173 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -13,51 +13,33 @@ QuasoCompressorAudioProcessorEditor::QuasoCompressorAudioProcessorEditor (QuasoCompressorAudioProcessor& p) : AudioProcessorEditor (&p), audioProcessor (p) { - - //setting the label text - inputDialLabel.setText("Input", juce::dontSendNotification); - threshDialLabel.setText("Threshold", juce::dontSendNotification); - ratioDialLabel.setText("Ratio", juce::dontSendNotification); - attackDialLabel.setText("Attack", juce::dontSendNotification); - releaseDialLabel.setText("Release", juce::dontSendNotification); - limThreshDialLabel.setText("Threshold", juce::dontSendNotification); - limReleaseDialLabel.setText("Release", juce::dontSendNotification); - outputDialLabel.setText("Output", juce::dontSendNotification); - - //setting the slider properties is called for every slider in the vector + //setting up common slider and labels props for (int i = 0; i < dials.size(); i++) { setCommonSliderProps(*dials[i]); setCommonLabelProps(*dialLabels[i]); dialLabels[i]->attachToComponent(dials[i], false); } - - for (int i = 0; i < groups.size(); i++) + //unique slider properties like suffixes and colors + setUniqueSliderProps(); + //text for each label + setLabelText(); + //toggle button properties + setButtonProps(compBypassButton); + + //shadow properties are the same for each slider + for (int i = 0; i < dials.size(); i++) { - setGroupProps(*groups[i]); + setShadowProps(*dials[i]); } - for (int i = 0; i < buttons.size(); i++) + //group properties + for (int i = 0; i < groups.size(); i++) { - setButtonProps(*buttons[i]); + setGroupProps(*groups[i]); } - //some properties are different between dials like the textbox suffix - //inputDial.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); - inputDial.setTextValueSuffix(" dB"); - threshDial.setTextValueSuffix(" dB"); - attackDial.setTextValueSuffix(" ms"); - releaseDial.setTextValueSuffix(" ms"); - //limThreshDial.setColour(juce::Slider::ColourIds::thumbColourId, - //limThreshDial.findColour(juce::Slider::ColourIds::thumbColourId).withSaturation(0.85)); - limThreshDial.setTextValueSuffix(" dB"); - //limReleaseDial.setColour(juce::Slider::ColourIds::thumbColourId, - //limReleaseDial.findColour(juce::Slider::ColourIds::thumbColourId).withSaturation(0.85)); - limReleaseDial.setTextValueSuffix(" ms"); - //outputDial.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); - outputDial.setTextValueSuffix(" dB"); - - + //methods to attach sliders and buttons the apvts parameters attachSliders(); attachButtons(); @@ -75,6 +57,7 @@ QuasoCompressorAudioProcessorEditor::~QuasoCompressorAudioProcessorEditor() { dial->setLookAndFeel(nullptr); } + //the vector is cleared and then shrinked to size zero inside the destructor dials.clear(); dials.shrink_to_fit(); @@ -92,61 +75,40 @@ void QuasoCompressorAudioProcessorEditor::paint (juce::Graphics& g) void QuasoCompressorAudioProcessorEditor::resized() { + //useful variables for placing the components in the gui auto dialSize = getWidth() * 0.18; - auto mainLeftMargin = getWidth() * 0.3; - auto leftMargin = getWidth() * 0.03; + auto mainLeftMargin = getWidth() * 0.32; + auto leftMargin = getWidth() * 0.05; auto secondRowHeight = 1.3; - auto limiterMargin = 1.45; - - ////first row of GUI with input, thresh and ratio - //juce::FlexBox flexboxRowOne; - //flexboxRowOne.flexDirection = juce::FlexBox::Direction::row; - //flexboxRowOne.flexWrap = juce::FlexBox::Wrap::noWrap; - //flexboxRowOne.alignContent = juce::FlexBox::AlignContent::center; - // - //juce::Array itemArrayRowOne; - //itemArrayRowOne.add(juce::FlexItem(dialSize, dialSize, inputDial).withMargin(juce::FlexItem::Margin(0, 0, 0, leftMargin))); - //itemArrayRowOne.add(juce::FlexItem(dialSize, dialSize, threshDial).withMargin(juce::FlexItem::Margin(0, 0, 0, mainLeftMargin))); - //itemArrayRowOne.add(juce::FlexItem(dialSize, dialSize, ratioDial).withMargin(juce::FlexItem::Margin(0, 0, 0, leftMargin))); - // - //flexboxRowOne.items = itemArrayRowOne; - //flexboxRowOne.performLayout(getLocalBounds().withY(0).withHeight(getHeight() * 0.5)); - // - ////second row of GUI with output, attack and release - //juce::FlexBox flexboxRowTwo; - //flexboxRowTwo.flexDirection = juce::FlexBox::Direction::row; - //flexboxRowTwo.flexWrap = juce::FlexBox::Wrap::noWrap; - //flexboxRowTwo.alignContent = juce::FlexBox::AlignContent::center; - // - //juce::Array itemArrayRowTwo; - //itemArrayRowTwo.add(juce::FlexItem(dialSize, dialSize, outputDial).withMargin(juce::FlexItem::Margin(0, 0, 0, leftMargin))); - //itemArrayRowTwo.add(juce::FlexItem(dialSize, dialSize, attackDial).withMargin(juce::FlexItem::Margin(0, 0, 0, mainLeftMargin))); - //itemArrayRowTwo.add(juce::FlexItem(dialSize, dialSize, releaseDial).withMargin(juce::FlexItem::Margin(0, 0, 0, leftMargin))); - // - //flexboxRowTwo.items = itemArrayRowTwo; - //flexboxRowTwo.performLayout(getLocalBounds().withY(getHeight() * 0.5).withHeight(getHeight()*0.5)); + auto limiterMargin = 1.5; + auto buttonSize = 50; + + //I/O section GUI inputDial.setBounds(leftMargin, 65, dialSize, dialSize); - threshDial.setBounds(mainLeftMargin, 65, dialSize, dialSize); - ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 65, dialSize, dialSize); + outputDial.setBounds(leftMargin, inputDial.getY() + inputDial.getHeight() * secondRowHeight, dialSize, dialSize); - ioGroup.setBounds(inputDial.getX(), inputDial.getY() * 0.1, inputDial.getWidth(), - inputDial.getY() + inputDial.getHeight() * 2.4); + ioGroup.setBounds(inputDial.getX(), inputDial.getY() * 0.1, inputDial.getWidth(), + inputDial.getY() + inputDial.getHeight() * 2.35); - outputDial.setBounds(leftMargin, inputDial.getY() + inputDial.getHeight() *secondRowHeight, dialSize, dialSize); + + //Compressor section GUI + threshDial.setBounds(mainLeftMargin, 65, dialSize, dialSize); + ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 65, dialSize, dialSize); attackDial.setBounds(threshDial.getX(), outputDial.getY(), dialSize, dialSize); releaseDial.setBounds(ratioDial.getX(), outputDial.getY(), dialSize, dialSize); - compressorGroup.setBounds(threshDial.getX(), threshDial.getY() * 0.1, threshDial.getWidth() * 2.0, - threshDial.getY() + threshDial.getHeight() * 2.4); + compressorGroup.setBounds(threshDial.getX(), threshDial.getY() * 0.1, threshDial.getWidth() * 2.0, + threshDial.getY() + threshDial.getHeight() * 2.35); + + compBypassButton.setBounds(releaseDial.getX() - 26, compressorGroup.getBottom() - 55, buttonSize, buttonSize); + + //Limiter Section GUI limThreshDial.setBounds(ratioDial.getX() + ratioDial.getWidth() * limiterMargin, inputDial.getY(), dialSize, dialSize); limReleaseDial.setBounds(limThreshDial.getX(), inputDial.getY() +limThreshDial.getHeight()*secondRowHeight, dialSize, dialSize); - limiterGroup.setBounds(limThreshDial.getX(), limThreshDial.getY() * 0.1, - limThreshDial.getWidth(), limThreshDial.getY() + limThreshDial.getHeight() * 2.4); - - compBypassButton.setBounds(compressorGroup.getRight() - 46, compressorGroup.getBottom() - 46, 50, 50); - + limiterGroup.setBounds(limThreshDial.getX(), limThreshDial.getY() * 0.1, + limThreshDial.getWidth(), limThreshDial.getY() + limThreshDial.getHeight() * 2.35); } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index e3239d3..93b858d 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -27,11 +27,11 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor void resized() override; private: - // This reference is provided as a quick way for your editor to - // access the processor object that created it. + //This reference is provided as a quick way for your editor to + //access the processor object that created it. QuasoCompressorAudioProcessor& audioProcessor; - //six dials attached to the six apvts parameters + //dials to attach to the apvts parameters juce::Slider inputDial; juce::Slider threshDial; juce::Slider ratioDial; @@ -41,11 +41,11 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor juce::Slider limReleaseDial; juce::Slider outputDial; - //using custom look and feel + //using custom look and feel for dials and button from ViatorDSP style sheet DialStyle customDialLAF; PowerToggleLAF buttonLAF; - //shadows + //shadows properties juce::DropShadow shadowProperties; juce::DropShadowEffect dialShadow; @@ -62,7 +62,7 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor &outputDial }; - //labels + //labels for each dial juce::Label inputDialLabel; juce::Label threshDialLabel; juce::Label ratioDialLabel; @@ -85,7 +85,8 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor &outputDialLabel }; - //groups + //three groups for a cleaner GUI look with + // I/O, Compressor and Limiter section juce::GroupComponent ioGroup; juce::GroupComponent compressorGroup; juce::GroupComponent limiterGroup; @@ -98,25 +99,21 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor &limiterGroup }; - //buttons + //toggle button to bypass the compressor juce::ToggleButton compBypassButton; - juce::ToggleButton limBypassButton; - //buttons vector - std::vector buttons = - { - &compBypassButton, - &limBypassButton - }; - - - //method to set some properties common to every silders, labels, groups and buttons + //method to set some properties common to every silders, labels, groups and button void setCommonSliderProps(juce::Slider& slider); void setCommonLabelProps(juce::Label& label); + void setShadowProps(juce::Slider& slider); void setGroupProps(juce::GroupComponent& group); void setButtonProps(juce::ToggleButton& button); + + //method to set unique properties + void setUniqueSliderProps(); + void setLabelText(); - //setting up attachment + //setting up attachments using ButtonAttachment = std::unique_ptr; ButtonAttachment compBypassAttach; @@ -134,10 +131,5 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor void attachSliders(); void attachButtons(); - - - - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuasoCompressorAudioProcessorEditor) }; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 958acb8..fb2f304 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -61,7 +61,7 @@ juce::AudioProcessorValueTreeState::ParameterLayout QuasoCompressorAudioProcesso //parameters of the apvts are stored in a vector as unique_pointers to RangedAudioParamter std::vector> params; - //attack and release parameters need to be skewed and not linear + //attack and release parameters are skewed and not linear juce::NormalisableRange attackRange = juce::NormalisableRange(0.0f, 200.0f, 1.0f); attackRange.setSkewForCentre(50.0f); @@ -71,26 +71,24 @@ juce::AudioProcessorValueTreeState::ParameterLayout QuasoCompressorAudioProcesso juce::NormalisableRange limReleaseRange = juce::NormalisableRange(1.0f, 1000.0f, 1.0f); releaseRange.setSkewForCentre(250.0f); - //parameters are created + //every parameter in the apvts corresponds to a parameter in the various dsp modules 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 + //parameters are pushed into a 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)); @@ -108,7 +106,8 @@ void QuasoCompressorAudioProcessor::parameterChanged(const juce::String& paramet void QuasoCompressorAudioProcessor::updateParameters() { - //the load method is needed because the raw parameters are atomic + //in this method every DSP is updated with the linked apvts alias + //load() 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()); @@ -118,7 +117,6 @@ void QuasoCompressorAudioProcessor::updateParameters() limiterModule.setThreshold(apvts.getRawParameterValue(limThreshID)->load()); limiterModule.setRelease(apvts.getRawParameterValue(limReleaseID)->load()); outputModule.setGainDecibels(apvts.getRawParameterValue(outputID)->load()); - } diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index e181ce7..b8aa86a 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -64,24 +64,23 @@ class QuasoCompressorAudioProcessor : public juce::AudioProcessor, juce::AudioP //and an overrided method to listen to parameters changed for the GUI //to do so the AudioProcessor class needs to inherit also from juce::AudioProcessorValueTreeState::Listener juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout(); + + //every time a parameter in the GUI is changed this method calls updateParameters void parameterChanged(const juce::String& parameterID, float newValue) override; + //this method updates every parameter in the apvts + void updateParameters(); + //to change the input and output gain two dsp modules are used juce::dsp::Gain inputModule; juce::dsp::Gain outputModule; - //the dsp module also implements a compressor module - juce::dsp::Compressor compressorModule; - - //custom dsp compressor module based on Eric Tarr HACK AUDIO + //custom dsp compressor module based on Eric Tarr HACK AUDIO CustomCompressor customCompressorModule; //limiter module juce::dsp::Limiter limiterModule; - //method to set the various parameters - void updateParameters(); - //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuasoCompressorAudioProcessor)