commit 3061a7e0c009bfa29e3e751bee78d0294b41f771
parent ca0fbadf3f54fc4536aff3fd7e6e152bd26e5a31
Author: jatinchowdhury18 <[email protected]>
Date: Sun, 25 Oct 2020 13:23:48 -0700
Improvements to tone control stage (#102)
Co-authored-by: jatinchowdhury18 <[email protected]>
Diffstat:
4 files changed, 44 insertions(+), 27 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in
this file.
## [Unreleased]
+- Tone section: added transition frequency control, and made bass/treble controls more extreme
- Added coloured circle on bottom bar to visualize mix group
- Added buttons to snap tape speed to conventional values
diff --git a/Plugin/Source/GUI/Assets/gui.xml b/Plugin/Source/GUI/Assets/gui.xml
@@ -64,10 +64,12 @@
</View>
<View flex-direction="column" tab-color="" background-color="FF31323A"
padding="0" tab-caption="Tone">
- <Slider caption="Bass" parameter="h_bass" class="Slider" name="Bass"
- tooltip="Controls the bass response of the pre/post-emphasis filters."/>
- <Slider caption="Treble" parameter="h_treble" class="Slider" name="Treble"
- tooltip="Controls the treble response of the pre/post-emphasis filters."/>
+ <Slider caption="Treble" parameter="h_treble" class="Slider" name="Treble" padding="0"
+ margin="0" tooltip="Controls the treble response of the pre/post-emphasis filters."/>
+ <Slider caption="Bass" parameter="h_bass" class="Slider" name="Bass" padding="0"
+ margin="0" tooltip="Controls the bass response of the pre/post-emphasis filters."/>
+ <Slider caption="Frequency" parameter="h_tfreq" class="Slider" name="Transition Frequency" padding="0"
+ margin="0" tooltip="Controls the transition frequency between the bass and treble sections of the EQ."/>
</View>
</View>
<View display="tabbed" padding="0" background-color="FF31323A" flex-grow="1.5"
diff --git a/Plugin/Source/Processors/Hysteresis/ToneControl.cpp b/Plugin/Source/Processors/Hysteresis/ToneControl.cpp
@@ -4,7 +4,7 @@ namespace
{
constexpr double slewTime = 0.05;
constexpr float transFreq = 500.0f;
- constexpr float dbScale = 12.0f;
+ constexpr float dbScale = 18.0f;
}
ToneStage::ToneStage()
@@ -13,6 +13,7 @@ ToneStage::ToneStage()
{
lowGain[ch] = 1.0f;
highGain[ch] = 1.0f;
+ tFreq[ch] = transFreq;
}
}
@@ -22,46 +23,45 @@ void ToneStage::prepare (double sampleRate)
for (int ch = 0; ch < 2; ++ch)
{
- lowGain[ch].reset (sampleRate, slewTime);
- lowGain[ch].setCurrentAndTargetValue (lowGain[ch].getTargetValue());
- highGain[ch].reset (sampleRate, slewTime);
- highGain[ch].setCurrentAndTargetValue (highGain[ch].getTargetValue());
+ auto resetSmoothValue = [sampleRate] (SmoothGain& value)
+ {
+ value.reset (sampleRate, slewTime);
+ value.setCurrentAndTargetValue (value.getTargetValue());
+ };
+
+ resetSmoothValue (lowGain[ch]);
+ resetSmoothValue (highGain[ch]);
+ resetSmoothValue (tFreq[ch]);
tone[ch].reset();
- tone[ch].calcCoefs (lowGain[ch].getTargetValue(), highGain[ch].getTargetValue(), transFreq, fs);
+ tone[ch].calcCoefs (lowGain[ch].getTargetValue(), highGain[ch].getTargetValue(),
+ tFreq[ch].getTargetValue(), fs);
}
}
-void ToneStage::setLowGain (float lowGainDB)
+void setSmoothValues (SmoothGain values[2], float newValue)
{
- auto newLowGain = Decibels::decibelsToGain (lowGainDB);
- if (newLowGain == lowGain[0].getTargetValue())
+ if (newValue == values[0].getTargetValue())
return;
- lowGain[0].setTargetValue (newLowGain);
- lowGain[1].setTargetValue (newLowGain);
+ values[0].setTargetValue (newValue);
+ values[1].setTargetValue (newValue);
}
-void ToneStage::setHighGain (float highGainDB)
-{
- auto newHighGain = Decibels::decibelsToGain (highGainDB);
- if (newHighGain == highGain[0].getTargetValue())
- return;
-
- highGain[0].setTargetValue (newHighGain);
- highGain[1].setTargetValue (newHighGain);
-}
+void ToneStage::setLowGain (float lowGainDB) { setSmoothValues (lowGain, Decibels::decibelsToGain (lowGainDB)); }
+void ToneStage::setHighGain (float highGainDB) { setSmoothValues (highGain, Decibels::decibelsToGain (highGainDB)); }
+void ToneStage::setTransFreq (float newTFreq) { setSmoothValues (tFreq, newTFreq); }
void ToneStage::processBlock (AudioBuffer<float>& buffer)
{
for (int ch = 0; ch < buffer.getNumChannels(); ++ch)
{
- if (lowGain[ch].isSmoothing() || highGain[ch].isSmoothing())
+ if (lowGain[ch].isSmoothing() || highGain[ch].isSmoothing() || tFreq[ch].isSmoothing())
{
auto* x = buffer.getWritePointer (ch);
for (int n = 0; n < buffer.getNumSamples(); ++n)
{
- tone[ch].calcCoefs (lowGain[ch].getNextValue(), highGain[ch].getNextValue(), transFreq, fs);
+ tone[ch].calcCoefs (lowGain[ch].getNextValue(), highGain[ch].getNextValue(), tFreq[ch].getNextValue(), fs);
x[n] = tone[ch].processSample (x[n]);
}
}
@@ -77,12 +77,22 @@ ToneControl::ToneControl (AudioProcessorValueTreeState& vts)
{
bassParam = vts.getRawParameterValue ("h_bass");
trebleParam = vts.getRawParameterValue ("h_treble");
+ tFreqParam = vts.getRawParameterValue ("h_tfreq");
}
void ToneControl::createParameterLayout (std::vector<std::unique_ptr<RangedAudioParameter>>& params)
{
+ NormalisableRange freqRange { 100.0f, 4000.0f };
+ freqRange.setSkewForCentre (transFreq);
+
params.push_back (std::make_unique<AudioParameterFloat> ("h_bass", "Bass", -1.0f, 1.0f, 0.0f));
params.push_back (std::make_unique<AudioParameterFloat> ("h_treble", "Treble", -1.0f, 1.0f, 0.0f));
+ params.push_back (std::make_unique<AudioParameterFloat> ("h_tfreq", "Frequency", freqRange, transFreq,
+ String(), AudioProcessorParameter::genericParameter, [=] (float val, int) {
+ String suffix = " Hz";
+ if (val > 1000.0f) { val /= 1000.0f; suffix = " kHz"; }
+ return String (val, 2, false) + suffix;
+ }));
}
void ToneControl::prepare (double sampleRate)
@@ -95,6 +105,7 @@ void ToneControl::processBlockIn (AudioBuffer<float>& buffer)
{
toneIn.setLowGain (dbScale * bassParam->load());
toneIn.setHighGain (dbScale * trebleParam->load());
+ toneIn.setTransFreq (tFreqParam->load());
toneIn.processBlock (buffer);
}
@@ -103,6 +114,7 @@ void ToneControl::processBlockOut (AudioBuffer<float>& buffer)
{
toneOut.setLowGain (-1.0f * dbScale * bassParam->load());
toneOut.setHighGain (-1.0f * dbScale * trebleParam->load());
+ toneOut.setTransFreq (tFreqParam->load());
toneOut.processBlock (buffer);
}
diff --git a/Plugin/Source/Processors/Hysteresis/ToneControl.h b/Plugin/Source/Processors/Hysteresis/ToneControl.h
@@ -8,7 +8,7 @@ using SmoothGain = SmoothedValue<float, ValueSmoothingTypes::Multiplicative>;
struct ToneStage
{
ToneFilter tone[2];
- SmoothGain lowGain[2], highGain[2];
+ SmoothGain lowGain[2], highGain[2], tFreq[2];
float fs = 44100.0f;
ToneStage();
@@ -17,6 +17,7 @@ struct ToneStage
void processBlock (AudioBuffer<float>& buffer);
void setLowGain (float lowGainDB);
void setHighGain (float highGainDB);
+ void setTransFreq (float newTFreq);
};
class ToneControl
@@ -35,6 +36,7 @@ private:
std::atomic<float>* bassParam = nullptr;
std::atomic<float>* trebleParam = nullptr;
+ std::atomic<float>* tFreqParam = nullptr;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ToneControl)
};