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