From faec8165542605e61744695adbdda8e80b79549d Mon Sep 17 00:00:00 2001 From: Alberto Roletto <73691506+sadmemelord@users.noreply.github.com> Date: Mon, 6 Feb 2023 20:28:43 +0100 Subject: [PATCH] Added Limiter module and GUI Groups --- QuasoCompressor.jucer | 3 ++ Source/GUI/Groups/Groups.cpp | 20 +++++++++++++ Source/GUI/Sliders/SliderProps.cpp | 2 ++ Source/Parameters/Parameters.cpp | 6 ++++ Source/Parameters/Parameters.h | 6 ++++ Source/PluginEditor.cpp | 47 +++++++++++++++++++++++------- Source/PluginEditor.h | 28 +++++++++++++++++- Source/PluginProcessor.cpp | 22 ++++++++++++-- Source/PluginProcessor.h | 3 ++ 9 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 Source/GUI/Groups/Groups.cpp diff --git a/QuasoCompressor.jucer b/QuasoCompressor.jucer index d4c7bc7..d3a31d7 100644 --- a/QuasoCompressor.jucer +++ b/QuasoCompressor.jucer @@ -9,6 +9,9 @@ + + + diff --git a/Source/GUI/Groups/Groups.cpp b/Source/GUI/Groups/Groups.cpp new file mode 100644 index 0000000..419416b --- /dev/null +++ b/Source/GUI/Groups/Groups.cpp @@ -0,0 +1,20 @@ +/* + ============================================================================== + + Groups.cpp + Created: 6 Feb 2023 7:43:46pm + Author: Utente + + ============================================================================== +*/ + +#include "../../PluginEditor.h" + +void QuasoCompressorAudioProcessorEditor::setGroupProps(juce::GroupComponent& group) +{ + addAndMakeVisible(group); + group.setColour(group.outlineColourId, juce::Colours::darkgrey); + ioGroup.setText("I/O"); + compressorGroup.setText("Compressor"); + limiterGroup.setText("Limiter"); +} diff --git a/Source/GUI/Sliders/SliderProps.cpp b/Source/GUI/Sliders/SliderProps.cpp index c36b9d6..0991d5c 100644 --- a/Source/GUI/Sliders/SliderProps.cpp +++ b/Source/GUI/Sliders/SliderProps.cpp @@ -47,6 +47,8 @@ void QuasoCompressorAudioProcessorEditor::attachSliders() ratioAttach = std::make_unique(audioProcessor.apvts, ratioID, ratioDial); attackAttach = std::make_unique(audioProcessor.apvts, attackID, attackDial); releaseAttach = std::make_unique(audioProcessor.apvts, releaseID, releaseDial); + limThreshAttach = std::make_unique(audioProcessor.apvts, limThreshID, limThreshDial); + limReleaseAttach = std::make_unique(audioProcessor.apvts, limReleaseID, limReleaseDial); outputAttach = std::make_unique(audioProcessor.apvts, outputID, outputDial); } diff --git a/Source/Parameters/Parameters.cpp b/Source/Parameters/Parameters.cpp index 9a86d10..63a7e60 100644 --- a/Source/Parameters/Parameters.cpp +++ b/Source/Parameters/Parameters.cpp @@ -25,5 +25,11 @@ const juce::String attackName = "Attack"; const juce::String releaseID = "release"; const juce::String releaseName = "Release"; +const juce::String limThreshID = "limThresh"; +const juce::String limThreshName = "Limiter Thresh"; + +const juce::String limReleaseID = "limRelease"; +const juce::String limReleaseName = "Limiter Release"; + const juce::String outputID = "output"; const juce::String outputName = "Output"; diff --git a/Source/Parameters/Parameters.h b/Source/Parameters/Parameters.h index e47ffe9..6ec6304 100644 --- a/Source/Parameters/Parameters.h +++ b/Source/Parameters/Parameters.h @@ -26,5 +26,11 @@ extern const juce::String attackName; extern const juce::String releaseID; extern const juce::String releaseName; +extern const juce::String limThreshID; +extern const juce::String limThreshName; + +extern const juce::String limReleaseID; +extern const juce::String limReleaseName; + extern const juce::String outputID; extern const juce::String outputName; diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index d0830a1..7269aba 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -20,6 +20,8 @@ QuasoCompressorAudioProcessorEditor::QuasoCompressorAudioProcessorEditor (QuasoC 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 @@ -30,13 +32,24 @@ QuasoCompressorAudioProcessorEditor::QuasoCompressorAudioProcessorEditor (QuasoC dialLabels[i]->attachToComponent(dials[i], false); } + for (int i = 0; i < groups.size(); 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.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); inputDial.setTextValueSuffix(" dB"); threshDial.setTextValueSuffix(" dB"); attackDial.setTextValueSuffix(" ms"); releaseDial.setTextValueSuffix(" ms"); - outputDial.setColour(juce::Slider::ColourIds::thumbColourId, juce::Colours::indianred.darker(0.3)); + //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"); @@ -46,7 +59,7 @@ QuasoCompressorAudioProcessorEditor::QuasoCompressorAudioProcessorEditor (QuasoC //the windows can be resized by mantaining the dafault 2:1 aspect ratio and only by 25% bigger or smaller juce::AudioProcessorEditor::setResizable(true,true); - juce::AudioProcessorEditor::setResizeLimits(getWidth() * 0.75, getHeight() * 0.75, getWidth() * 1.25, getHeight() * 1.25); + juce::AudioProcessorEditor::setResizeLimits(getWidth(), getHeight(), getWidth() * 1.25, getHeight() * 1.25); juce::AudioProcessorEditor::getConstrainer()->setFixedAspectRatio(2.0); } @@ -73,10 +86,11 @@ void QuasoCompressorAudioProcessorEditor::paint (juce::Graphics& g) void QuasoCompressorAudioProcessorEditor::resized() { - auto dialSize = getWidth() * 0.15; - auto mainLeftMargin = getWidth() * 0.25; - auto leftMargin = getWidth() * 0.02; - auto secondRowHeight = 1.5; + auto dialSize = getWidth() * 0.18; + auto mainLeftMargin = getWidth() * 0.3; + auto leftMargin = getWidth() * 0.03; + auto secondRowHeight = 1.3; + auto limiterMargin = 1.45; ////first row of GUI with input, thresh and ratio //juce::FlexBox flexboxRowOne; @@ -105,13 +119,26 @@ void QuasoCompressorAudioProcessorEditor::resized() // //flexboxRowTwo.items = itemArrayRowTwo; //flexboxRowTwo.performLayout(getLocalBounds().withY(getHeight() * 0.5).withHeight(getHeight()*0.5)); - inputDial.setBounds(leftMargin, 75, dialSize, dialSize); - threshDial.setBounds(mainLeftMargin, 75, dialSize, dialSize); - ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 75, dialSize, dialSize); + inputDial.setBounds(leftMargin, 50, dialSize, dialSize); + threshDial.setBounds(mainLeftMargin, 50, dialSize, dialSize); + ratioDial.setBounds(threshDial.getX() + threshDial.getWidth(), 50, dialSize, dialSize); + + ioGroup.setBounds(inputDial.getX(), inputDial.getY() * 0.1, inputDial.getWidth(), + inputDial.getY() + inputDial.getHeight() * 2.4); outputDial.setBounds(leftMargin, inputDial.getY() + inputDial.getHeight() *secondRowHeight, 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); + + 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); + + } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index cf80cef..4e37e34 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -36,6 +36,8 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor juce::Slider ratioDial; juce::Slider attackDial; juce::Slider releaseDial; + juce::Slider limThreshDial; + juce::Slider limReleaseDial; juce::Slider outputDial; //using custom look and feel @@ -53,16 +55,22 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor &ratioDial, &attackDial, &releaseDial, + &limThreshDial, + &limReleaseDial, &outputDial }; + //labels juce::Label inputDialLabel; juce::Label threshDialLabel; juce::Label ratioDialLabel; juce::Label attackDialLabel; juce::Label releaseDialLabel; + juce::Label limThreshDialLabel; + juce::Label limReleaseDialLabel; juce::Label outputDialLabel; + //labels vector std::vector dialLabels = { &inputDialLabel, @@ -70,12 +78,28 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor &ratioDialLabel, &attackDialLabel, &releaseDialLabel, + &limThreshDialLabel, + &limReleaseDialLabel, &outputDialLabel }; - //method to set some properties common to every silder and label + //groups + juce::GroupComponent ioGroup; + juce::GroupComponent compressorGroup; + juce::GroupComponent limiterGroup; + + //groups vector + std::vector groups = + { + &ioGroup, + &compressorGroup, + &limiterGroup + }; + + //method to set some properties common to every silder, label and group void setCommonSliderProps(juce::Slider& slider); void setCommonLabelProps(juce::Label& label); + void setGroupProps(juce::GroupComponent& group); //setting up attachment using Attachment = std::unique_ptr; @@ -85,6 +109,8 @@ class QuasoCompressorAudioProcessorEditor : public juce::AudioProcessorEditor Attachment ratioAttach; Attachment attackAttach; Attachment releaseAttach; + Attachment limThreshAttach; + Attachment limReleaseAttach; Attachment outputAttach; //method to attach sliders to the apvts diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index 5995f01..9e624e2 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -32,6 +32,8 @@ QuasoCompressorAudioProcessor::QuasoCompressorAudioProcessor() apvts.addParameterListener(ratioID, this); apvts.addParameterListener(attackID, this); apvts.addParameterListener(releaseID, this); + apvts.addParameterListener(limThreshID, this); + apvts.addParameterListener(limReleaseID, this); apvts.addParameterListener(outputID, this); } @@ -43,6 +45,8 @@ QuasoCompressorAudioProcessor::~QuasoCompressorAudioProcessor() apvts.removeParameterListener(ratioID, this); apvts.removeParameterListener(attackID, this); apvts.removeParameterListener(releaseID, this); + apvts.removeParameterListener(limThreshID, this); + apvts.removeParameterListener(limReleaseID, this); apvts.removeParameterListener(outputID, this); } @@ -60,20 +64,27 @@ juce::AudioProcessorValueTreeState::ParameterLayout QuasoCompressorAudioProcesso juce::NormalisableRange releaseRange = juce::NormalisableRange( 5.0f, 5000.0f, 1.0f); releaseRange.setSkewForCentre(160.0f); + juce::NormalisableRange limReleaseRange = juce::NormalisableRange(1.0f, 1000.0f, 1.0f); + releaseRange.setSkewForCentre(250.0f); + //parameters are created auto pInput = std::make_unique(inputID, inputName, -60.0f, 24.0f, 0.0f); - auto pThresh = std::make_unique(threshID, threshName, -60.0f, 10.0f, 0.0f); + 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 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(pThresh)); params.push_back(std::move(pRatio)); params.push_back(std::move(pAttack)); params.push_back(std::move(pRelease)); + params.push_back(std::move(pLimThresh)); + params.push_back(std::move(pLimRelease)); params.push_back(std::move(pOutput)); @@ -95,6 +106,8 @@ void QuasoCompressorAudioProcessor::updateParameters() compressorModule.setRatio(apvts.getRawParameterValue(ratioID)->load()); compressorModule.setAttack(apvts.getRawParameterValue(attackID)->load()); compressorModule.setRelease(apvts.getRawParameterValue(releaseID)->load()); + limiterModule.setThreshold(apvts.getRawParameterValue(limThreshID)->load()); + limiterModule.setRelease(apvts.getRawParameterValue(limReleaseID)->load()); outputModule.setGainDecibels(apvts.getRawParameterValue(outputID)->load()); } @@ -180,6 +193,8 @@ void QuasoCompressorAudioProcessor::prepareToPlay (double sampleRate, int sample outputModule.prepare(spec); compressorModule.prepare(spec); + + limiterModule.prepare(spec); updateParameters(); } @@ -222,11 +237,12 @@ void QuasoCompressorAudioProcessor::processBlock (juce::AudioBuffer& buff auto totalNumInputChannels = getTotalNumInputChannels(); auto totalNumOutputChannels = getTotalNumOutputChannels(); - juce::dsp::AudioBlock block{ buffer }; + auto block = juce::dsp::AudioBlock(buffer); //process DSP modules inputModule.process(juce::dsp::ProcessContextReplacing(block)); compressorModule.process(juce::dsp::ProcessContextReplacing(block)); + limiterModule.process(juce::dsp::ProcessContextReplacing(block)); outputModule.process(juce::dsp::ProcessContextReplacing(block)); diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 984af8a..9147ae8 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -72,6 +72,9 @@ class QuasoCompressorAudioProcessor : public juce::AudioProcessor, juce::AudioP //the dsp module also implements a compressor module juce::dsp::Compressor compressorModule; + //limiter module + juce::dsp::Limiter limiterModule; + //method to set the various parameters void updateParameters();