commit be2c6621628db1cb578776db61f9da04c3790f64
parent 575a04b5984f9808089903174b8c6235cde63471
Author: keith <kbloemer89@gmail.com>
Date: Thu, 17 Jun 2021 16:19:44 -0500
Added EQ controls
Diffstat:
8 files changed, 537 insertions(+), 16 deletions(-)
diff --git a/NeuralPi.jucer b/NeuralPi.jucer
@@ -15,6 +15,8 @@
<GROUP id="{70CE292C-E9C5-C029-B95A-F7DF41E5F74C}" name="Source">
<FILE id="VgCJPH" name="AmpOSCReceiver.h" compile="0" resource="0"
file="Source/AmpOSCReceiver.h"/>
+ <FILE id="s1HQuK" name="Eq4Band.cpp" compile="1" resource="0" file="Source/Eq4Band.cpp"/>
+ <FILE id="xtLEtv" name="Eq4Band.h" compile="0" resource="0" file="Source/Eq4Band.h"/>
<FILE id="hNjQV9" name="PluginEditor.cpp" compile="1" resource="0"
file="Source/PluginEditor.cpp"/>
<FILE id="BweFTe" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
diff --git a/Source/AmpOSCReceiver.h b/Source/AmpOSCReceiver.h
@@ -24,6 +24,26 @@ public:
return masterValue;
}
+ Value& getBassValue()
+ {
+ return bassValue;
+ }
+
+ Value& getMidValue()
+ {
+ return midValue;
+ }
+
+ Value& getTrebleValue()
+ {
+ return trebleValue;
+ }
+
+ Value& getPresenceValue()
+ {
+ return presenceValue;
+ }
+
Value& getModelValue()
{
return modelValue;
@@ -59,6 +79,10 @@ private:
{
gainAddressPattern = "/parameter/" + ampName + "/Gain";
masterAddressPattern = "/parameter/" + ampName + "/Master";
+ bassAddressPattern = "/parameter/" + ampName + "/Bass";
+ midAddressPattern = "/parameter/" + ampName + "/Mid";
+ trebleAddressPattern = "/parameter/" + ampName + "/Treble";
+ presenceAddressPattern = "/parameter/" + ampName + "/Presence";
modelAddressPattern = "/parameter/" + ampName + "/Model";
}
@@ -78,6 +102,24 @@ private:
{
masterValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
}
+
+ if (message.getAddressPattern().matches(bassAddressPattern))
+ {
+ bassValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
+ }
+ else if (message.getAddressPattern().matches(midAddressPattern))
+ {
+ midValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
+ }
+
+ if (message.getAddressPattern().matches(trebleAddressPattern))
+ {
+ trebleValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
+ }
+ else if (message.getAddressPattern().matches(presenceAddressPattern))
+ {
+ presenceValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
+ }
else if (message.getAddressPattern().matches(modelAddressPattern))
{
modelValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
@@ -91,10 +133,18 @@ private:
String ampName {"NeuralPi"};
String gainAddressPattern {"/parameter/elk_juce_example/Gain"};
String masterAddressPattern {"/parameter/elk_juce_example/Master"};
+ String bassAddressPattern {"/parameter/elk_juce_example/Bass"};
+ String midAddressPattern {"/parameter/elk_juce_example/Mid"};
+ String trebleAddressPattern {"/parameter/elk_juce_example/Treble"};
+ String presenceAddressPattern {"/parameter/elk_juce_example/Presence"};
String modelAddressPattern {"/parameter/elk_juce_example/Model"};
- Value gainValue {0.0f};
- Value masterValue {0.0f};
+ Value gainValue {0.5f};
+ Value masterValue {0.5f};
+ Value bassValue {0.5f};
+ Value midValue {0.5f};
+ Value trebleValue {0.5f};
+ Value presenceValue {0.5f};
Value modelValue {0.0f};
diff --git a/Source/Eq4Band.cpp b/Source/Eq4Band.cpp
@@ -0,0 +1,76 @@
+/*
+ ==============================================================================
+
+ Eq4Band
+
+ ==============================================================================
+*/
+
+#include "Eq4Band.h"
+
+Eq4Band::Eq4Band()
+{
+ setParameters(0.0, 0.0, 0.0, 0.0);
+}
+
+void Eq4Band::process (const float* inData, float* outData,
+ MidiBuffer& midiMessages,
+ const int numSamples,
+ const int numInputChannels,
+ const int sampleRate)
+{
+ // Reset params if new sampleRate detected
+ if (srate != sampleRate) {
+ srate = sampleRate;
+ resetSampleRate();
+ }
+ for (int sample = 0; sample < numSamples; ++sample) {
+ spl0 = inData[sample];
+ s0 = spl0;
+ low0 = (tmplMID = a0MID * s0 - b1MID * tmplMID + cDenorm);
+ spl0 = (tmplLOW = a0LOW * low0 - b1LOW * tmplLOW + cDenorm);
+ lowS0 = low0 - spl0;
+ hi0 = s0 - low0;
+ midS0 = (tmplHI = a0HI * hi0 - b1HI * tmplHI + cDenorm);
+ highS0 = hi0 - midS0;
+ spl0 = (spl0 * lVol + lowS0 * lmVol + midS0 * hmVol + highS0 * hVol);// * outVol;
+
+ outData[sample] = spl0;
+ }
+}
+
+void Eq4Band::setParameters(float bass_slider, float mid_slider, float treble_slider, float presence_slider)
+{
+ lVol = exp(bass_slider / cAmpDB);
+ lmVol = exp(mid_slider / cAmpDB);
+ hmVol = exp(treble_slider / cAmpDB);
+ hVol = exp(presence_slider / cAmpDB);
+ outVol = exp(0.0 / cAmpDB);
+
+ xHI = exp(-2.0 * pi * treble_frequency / srate);
+ a0HI = 1.0 - xHI;
+ b1HI = -xHI;
+
+ xMID = exp(-2.0 * pi * mid_frequency / srate);
+ a0MID = 1.0 - xMID;
+ b1MID = -xMID;
+
+ xLOW = exp(-2.0 * pi * bass_frequency / srate);
+ a0LOW = 1.0 - xLOW;
+ b1LOW = -xLOW;
+}
+
+void Eq4Band::resetSampleRate()
+{
+ xHI = exp(-2.0 * pi * treble_frequency / srate);
+ a0HI = 1.0 - xHI;
+ b1HI = -xHI;
+
+ xMID = exp(-2.0 * pi * mid_frequency / srate);
+ a0MID = 1.0 - xMID;
+ b1MID = -xMID;
+
+ xLOW = exp(-2.0 * pi * bass_frequency / srate);
+ a0LOW = 1.0 - xLOW;
+ b1LOW = -xLOW;
+}
+\ No newline at end of file
diff --git a/Source/Eq4Band.h b/Source/Eq4Band.h
@@ -0,0 +1,68 @@
+/*
+ ==============================================================================
+
+ Eq4Band
+
+ ==============================================================================
+*/
+
+#pragma once
+
+#include "../JuceLibraryCode/JuceHeader.h"
+
+
+//==============================================================================
+
+class Eq4Band
+{
+public:
+ Eq4Band();
+ void process (const float* inData, float* outData, MidiBuffer& midiMessages, const int numSamples, const int numInputChannels, const int sampleRate);
+ void setParameters(float bass_slider, float mid_slider, float treble_slider, float presence_slider);
+ void resetSampleRate();
+
+private:
+ // Tone Knob related variables
+ float cDenorm = 10e-30;
+ float cAmpDB = 8.65617025;
+
+ int bass_frequency = 200;
+ int mid_frequency = 2000;
+ int treble_frequency = 5000;
+ //int presence_frequency = 5500;
+
+ int srate = 44100; // Set default
+
+ float pi = 3.1415926;
+
+ float outVol;
+ float xHI = 0.0;//
+ float a0HI = 0.0;//
+ float b1HI = 0.0;
+ float xMID = 0.0;
+ float a0MID = 0.0;
+ float b1MID = 0.0;
+ float xLOW = 0.0;
+ float a0LOW = 0.0;
+ float b1LOW = 0.0;
+
+ float lVol = 0.0;
+ float lmVol = 0.0;
+ float hmVol = 0.0;
+ float hVol = 0.0;
+
+ float s0 = 0.0;
+ float low0 = 0.0;
+ float tmplMID = 0.0;
+ float spl0 = 0.0;
+ float hi0 = 0.0;
+ float midS0 = 0.0;
+ float highS0 = 0.0;
+ float tmplHI = 0.0;
+ float lowS0 = 0.0;
+ float tmplLOW = 0.0;
+
+
+ //==============================================================================
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Eq4Band)
+};
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
@@ -159,18 +159,188 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
}
};
+
+ addAndMakeVisible(ampBassKnob);
+ ampBassKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxBelow, false, 50, 20);
+ ampBassKnob.setNumDecimalPlacesToDisplay(1);
+ ampBassKnob.addListener(this);
+ ampBassKnob.setRange(0.0, 1.0);
+ ampBassKnob.setValue(0.5);
+ ampBassKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
+ ampBassKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
+ ampBassKnob.setNumDecimalPlacesToDisplay(1);
+ ampBassKnob.setDoubleClickReturnValue(true, 0.5);
+
+ auto bassValue = getParameterValue(bassName);
+ Slider& bassSlider = getBassSlider();
+ bassSlider.setValue(bassValue, NotificationType::dontSendNotification);
+
+ ampBassKnob.onValueChange = [this]
+ {
+ const float sliderValue = static_cast<float> (getBassSlider().getValue());
+ const float bassValue = getParameterValue(bassName);
+
+ if (!approximatelyEqual(bassValue, sliderValue))
+ {
+ setParameterValue(bassName, sliderValue);
+
+ // create and send an OSC message with an address and a float value:
+ float value = static_cast<float> (getBassSlider().getValue());
+
+ if (!oscSender.send(bassAddressPattern, value))
+ {
+ updateOutConnectedLabel(false);
+ }
+ else
+ {
+ DBG("Sent value " + String(value) + " to AP " + bassAddressPattern);
+ }
+ }
+ };
+
+ addAndMakeVisible(ampMidKnob);
+ ampMidKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxBelow, false, 50, 20);
+ ampMidKnob.setNumDecimalPlacesToDisplay(1);
+ ampMidKnob.addListener(this);
+ ampMidKnob.setRange(0.0, 1.0);
+ ampMidKnob.setValue(0.5);
+ ampMidKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
+ ampMidKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
+ ampMidKnob.setNumDecimalPlacesToDisplay(1);
+ ampMidKnob.setDoubleClickReturnValue(true, 0.5);
+
+ auto midValue = getParameterValue(midName);
+ Slider& midSlider = getMidSlider();
+ midSlider.setValue(midValue, NotificationType::dontSendNotification);
+
+ ampMidKnob.onValueChange = [this]
+ {
+ const float sliderValue = static_cast<float> (getMidSlider().getValue());
+ const float midValue = getParameterValue(midName);
+
+ if (!approximatelyEqual(midValue, sliderValue))
+ {
+ setParameterValue(midName, sliderValue);
+
+ // create and send an OSC message with an address and a float value:
+ float value = static_cast<float> (getMidSlider().getValue());
+
+ if (!oscSender.send(midAddressPattern, value))
+ {
+ updateOutConnectedLabel(false);
+ }
+ else
+ {
+ DBG("Sent value " + String(value) + " to AP " + midAddressPattern);
+ }
+ }
+ };
+
+ addAndMakeVisible(ampTrebleKnob);
+ ampTrebleKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxBelow, false, 50, 20);
+ ampTrebleKnob.setNumDecimalPlacesToDisplay(1);
+ ampTrebleKnob.addListener(this);
+ ampTrebleKnob.setRange(0.0, 1.0);
+ ampTrebleKnob.setValue(0.5);
+ ampTrebleKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
+ ampTrebleKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
+ ampTrebleKnob.setNumDecimalPlacesToDisplay(1);
+ ampTrebleKnob.setDoubleClickReturnValue(true, 0.5);
+
+ auto trebleValue = getParameterValue(trebleName);
+ Slider& trebleSlider = getTrebleSlider();
+ trebleSlider.setValue(trebleValue, NotificationType::dontSendNotification);
+
+ ampTrebleKnob.onValueChange = [this]
+ {
+ const float sliderValue = static_cast<float> (getTrebleSlider().getValue());
+ const float trebleValue = getParameterValue(trebleName);
+
+ if (!approximatelyEqual(trebleValue, sliderValue))
+ {
+ setParameterValue(trebleName, sliderValue);
+
+ // create and send an OSC message with an address and a float value:
+ float value = static_cast<float> (getTrebleSlider().getValue());
+
+ if (!oscSender.send(trebleAddressPattern, value))
+ {
+ updateOutConnectedLabel(false);
+ }
+ else
+ {
+ DBG("Sent value " + String(value) + " to AP " + trebleAddressPattern);
+ }
+ }
+ };
+
+ addAndMakeVisible(ampPresenceKnob);
+ ampPresenceKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxBelow, false, 50, 20);
+ ampPresenceKnob.setNumDecimalPlacesToDisplay(1);
+ ampPresenceKnob.addListener(this);
+ ampPresenceKnob.setRange(0.0, 1.0);
+ ampPresenceKnob.setValue(0.5);
+ ampPresenceKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
+ ampPresenceKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
+ ampPresenceKnob.setNumDecimalPlacesToDisplay(1);
+ ampPresenceKnob.setDoubleClickReturnValue(true, 0.5);
+
+ auto presenceValue = getParameterValue(trebleName);
+ Slider& presenceSlider = getPresenceSlider();
+ trebleSlider.setValue(presenceValue, NotificationType::dontSendNotification);
+
+ ampPresenceKnob.onValueChange = [this]
+ {
+ const float sliderValue = static_cast<float> (getPresenceSlider().getValue());
+ const float presenceValue = getParameterValue(presenceName);
+
+ if (!approximatelyEqual(presenceValue, sliderValue))
+ {
+ setParameterValue(presenceName, sliderValue);
+
+ // create and send an OSC message with an address and a float value:
+ float value = static_cast<float> (getPresenceSlider().getValue());
+
+ if (!oscSender.send(presenceAddressPattern, value))
+ {
+ updateOutConnectedLabel(false);
+ }
+ else
+ {
+ DBG("Sent value " + String(value) + " to AP " + presenceAddressPattern);
+ }
+ }
+ };
+
addAndMakeVisible(GainLabel);
GainLabel.setText("Gain", juce::NotificationType::dontSendNotification);
GainLabel.setJustificationType(juce::Justification::centred);
addAndMakeVisible(LevelLabel);
LevelLabel.setText("Level", juce::NotificationType::dontSendNotification);
LevelLabel.setJustificationType(juce::Justification::centred);
+
+ addAndMakeVisible(BassLabel);
+ BassLabel.setText("Bass", juce::NotificationType::dontSendNotification);
+ BassLabel.setJustificationType(juce::Justification::centred);
+ addAndMakeVisible(MidLabel);
+ MidLabel.setText("Mid", juce::NotificationType::dontSendNotification);
+ MidLabel.setJustificationType(juce::Justification::centred);
+ addAndMakeVisible(TrebleLabel);
+ TrebleLabel.setText("Treble", juce::NotificationType::dontSendNotification);
+ TrebleLabel.setJustificationType(juce::Justification::centred);
+ addAndMakeVisible(PresenceLabel);
+ PresenceLabel.setText("Presence", juce::NotificationType::dontSendNotification);
+ PresenceLabel.setJustificationType(juce::Justification::centred);
+
auto font = GainLabel.getFont();
float height = font.getHeight();
font.setHeight(height); // 0.75);
GainLabel.setFont(font);
LevelLabel.setFont(font);
-
+ BassLabel.setFont(font);
+ MidLabel.setFont(font);
+ TrebleLabel.setFont(font);
+ PresenceLabel.setFont(font);
// Name controls:
addAndMakeVisible(ampNameLabel);
@@ -204,6 +374,11 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
oscReceiver.getGainValue().addListener(this);
oscReceiver.getMasterValue().addListener(this);
+ oscReceiver.getBassValue().addListener(this);
+ oscReceiver.getMidValue().addListener(this);
+ oscReceiver.getTrebleValue().addListener(this);
+ oscReceiver.getPresenceValue().addListener(this);
+
oscReceiver.getModelValue().addListener(this);
updateInConnectedLabel();
@@ -211,7 +386,7 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
connectSender();
// Size of plugin GUI
- setSize(250, 350);
+ setSize(250, 430);
}
@@ -235,24 +410,33 @@ void NeuralPiAudioProcessorEditor::resized()
modelKnob.setBounds(140, 40, 75, 95);
// Amp Widgets
- ampGainKnob.setBounds(30, 85, 75, 95);
- ampMasterKnob.setBounds(140, 85, 75, 95);
- GainLabel.setBounds(28, 163, 80, 10);
- LevelLabel.setBounds(138, 163, 80, 10);
+ ampGainKnob.setBounds(30, 72, 75, 95);
+ ampMasterKnob.setBounds(140, 72, 75, 95);
+ ampBassKnob.setBounds(30, 155, 75, 95);
+ ampMidKnob.setBounds(140, 155, 75, 95);
+ ampTrebleKnob.setBounds(30, 235, 75, 95);
+ ampPresenceKnob.setBounds(140, 235, 75, 95);
+
+ GainLabel.setBounds(28, 150, 80, 10);
+ LevelLabel.setBounds(138, 150, 80, 10);
+ BassLabel.setBounds(28, 233, 80, 10);
+ MidLabel.setBounds(138, 233, 80, 10);
+ TrebleLabel.setBounds(28, 313, 80, 10);
+ PresenceLabel.setBounds(138, 313, 80, 10);
addAndMakeVisible(ampNameLabel);
ampNameField.setEditable(true, true, true);
addAndMakeVisible(ampNameField);
// IP controls:
- ipField.setBounds(150, 220, 100, 25);
- ipLabel.setBounds(15, 220, 150, 25);
+ ipField.setBounds(150, 330, 100, 25);
+ ipLabel.setBounds(15, 330, 150, 25);
// Port controls:
- outPortNumberLabel.setBounds(15, 260, 150, 25);
- outPortNumberField.setBounds(160, 260, 75, 25);
- inPortNumberLabel.setBounds(15, 300, 150, 25);
- inPortNumberField.setBounds(160, 300, 75, 25);
+ outPortNumberLabel.setBounds(15, 365, 150, 25);
+ outPortNumberField.setBounds(160, 365, 75, 25);
+ inPortNumberLabel.setBounds(15, 400, 150, 25);
+ inPortNumberField.setBounds(160, 400, 75, 25);
}
void NeuralPiAudioProcessorEditor::modelSelectChanged()
@@ -316,8 +500,22 @@ void NeuralPiAudioProcessorEditor::sliderValueChanged(Slider* slider)
if (slider == &modelKnob)
if (slider->getValue() >= 0 && slider->getValue() < processor.jsonFiles.size()) {
modelSelect.setSelectedItemIndex(processor.getModelIndex(slider->getValue()), juce::NotificationType::dontSendNotification);
- }
+ }
}
+/*
+ else if (slider == &BassKnob || slider == &MidKnob || slider == &TrebleKnob) {
+ processor.set_ampEQ(ampBassKnob.getValue(), ampMidKnob.getValue(), ampTrebleKnob.getValue(), ampPresenceKnob.getValue());
+ // Set knob states for saving positions when closing/reopening GUI
+ processor.ampBassKnobState = ampBassKnob.getValue();
+ processor.ampMidKnobState = ampMidKnob.getValue();
+ processor.ampTrebleKnobState = ampTrebleKnob.getValue();
+ }
+ else if (slider == &PresenceKnob) {
+ processor.set_ampEQ(ampBassKnob.getValue(), ampMidKnob.getValue(), ampTrebleKnob.getValue(), ampPresenceKnob.getValue());
+ }
+}
+*/
+
// OSC Messages
Slider& NeuralPiAudioProcessorEditor::getGainSlider()
@@ -330,6 +528,26 @@ Slider& NeuralPiAudioProcessorEditor::getMasterSlider()
return ampMasterKnob;
}
+Slider& NeuralPiAudioProcessorEditor::getBassSlider()
+{
+ return ampBassKnob;
+}
+
+Slider& NeuralPiAudioProcessorEditor::getMidSlider()
+{
+ return ampMidKnob;
+}
+
+Slider& NeuralPiAudioProcessorEditor::getTrebleSlider()
+{
+ return ampTrebleKnob;
+}
+
+Slider& NeuralPiAudioProcessorEditor::getPresenceSlider()
+{
+ return ampPresenceKnob;
+}
+
Slider& NeuralPiAudioProcessorEditor::getModelSlider()
{
return modelKnob;
@@ -370,6 +588,10 @@ void NeuralPiAudioProcessorEditor::buildAddressPatterns()
{
gainAddressPattern = "/parameter/" + ampName + "/Gain";
masterAddressPattern = "/parameter/" + ampName + "/Master";
+ bassAddressPattern = "/parameter/" + ampName + "/Bass";
+ midAddressPattern = "/parameter/" + ampName + "/Mid";
+ trebleAddressPattern = "/parameter/" + ampName + "/Treble";
+ presenceAddressPattern = "/parameter/" + ampName + "/Presence";
modelAddressPattern = "/parameter/" + ampName + "/Model";
}
@@ -470,6 +692,38 @@ void NeuralPiAudioProcessorEditor::valueChanged(Value& value)
NotificationType::sendNotification);
}
}
+ if (value.refersToSameSourceAs(oscReceiver.getBassValue()))
+ {
+ if (!approximatelyEqual(static_cast<double> (value.getValue()), getBassSlider().getValue()))
+ {
+ getBassSlider().setValue(static_cast<double> (value.getValue()),
+ NotificationType::sendNotification);
+ }
+ }
+ else if (value.refersToSameSourceAs(oscReceiver.getMidValue()))
+ {
+ if (!approximatelyEqual(static_cast<double> (value.getValue()), getMidSlider().getValue()))
+ {
+ getMidSlider().setValue(static_cast<double> (value.getValue()),
+ NotificationType::sendNotification);
+ }
+ }
+ if (value.refersToSameSourceAs(oscReceiver.getTrebleValue()))
+ {
+ if (!approximatelyEqual(static_cast<double> (value.getValue()), getTrebleSlider().getValue()))
+ {
+ getTrebleSlider().setValue(static_cast<double> (value.getValue()),
+ NotificationType::sendNotification);
+ }
+ }
+ else if (value.refersToSameSourceAs(oscReceiver.getPresenceValue()))
+ {
+ if (!approximatelyEqual(static_cast<double> (value.getValue()), getPresenceSlider().getValue()))
+ {
+ getPresenceSlider().setValue(static_cast<double> (value.getValue()),
+ NotificationType::sendNotification);
+ }
+ }
else if (value.refersToSameSourceAs(oscReceiver.getModelValue()))
{
if (!approximatelyEqual(static_cast<double> (value.getValue()), getModelSlider().getValue()))
@@ -484,6 +738,10 @@ void NeuralPiAudioProcessorEditor::timerCallback()
{
getGainSlider().setValue(getParameterValue(gainName), NotificationType::dontSendNotification);
getMasterSlider().setValue(getParameterValue(masterName), NotificationType::dontSendNotification);
+ getBassSlider().setValue(getParameterValue(bassName), NotificationType::dontSendNotification);
+ getMidSlider().setValue(getParameterValue(midName), NotificationType::dontSendNotification);
+ getTrebleSlider().setValue(getParameterValue(trebleName), NotificationType::dontSendNotification);
+ getPresenceSlider().setValue(getParameterValue(presenceName), NotificationType::dontSendNotification);
getModelSlider().setValue(getParameterValue(modelName), NotificationType::dontSendNotification);
}
diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h
@@ -46,9 +46,17 @@ public:
String gainAddressPattern{ "/parameter/NeuralPi/Gain" };
String masterAddressPattern{ "/parameter/NeuralPi/Master" };
String modelAddressPattern{ "/parameter/NeuralPi/Model" };
+ String bassAddressPattern{ "/parameter/NeuralPi/Bass" };
+ String midAddressPattern{ "/parameter/NeuralPi/Mid" };
+ String trebleAddressPattern{ "/parameter/NeuralPi/Treble" };
+ String presenceAddressPattern{ "/parameter/NeuralPi/Presence" };
const String gainName{ "gain" };
const String masterName{ "master" };
+ const String bassName{ "bass" };
+ const String midName{ "mid" };
+ const String trebleName{ "treble" };
+ const String presenceName{ "presence" };
const String modelName{ "model" };
@@ -65,8 +73,17 @@ private:
//ImageButton ampOnButton;
//ImageButton ampLED;
ComboBox modelSelect;
+ Slider ampBassKnob;
+ Slider ampMidKnob;
+ Slider ampTrebleKnob;
+ Slider ampPresenceKnob;
+
Label GainLabel;
Label LevelLabel;
+ Label BassLabel;
+ Label MidLabel;
+ Label TrebleLabel;
+ Label PresenceLabel;
File test_file;
File model_folder;
@@ -103,6 +120,11 @@ private:
Slider& getGainSlider();
Slider& getMasterSlider();
Slider& getModelSlider();
+ Slider& getBassSlider();
+ Slider& getMidSlider();
+ Slider& getTrebleSlider();
+ Slider& getPresenceSlider();
+
Label& getOutPortNumberField();
Label& getInPortNumberField();
Label& getIPField();
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
@@ -40,6 +40,10 @@ NeuralPiAudioProcessor::NeuralPiAudioProcessor()
// initialize parameters:
addParameter(gainParam = new AudioParameterFloat(GAIN_ID, GAIN_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
addParameter(masterParam = new AudioParameterFloat(MASTER_ID, MASTER_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
+ addParameter(bassParam = new AudioParameterFloat(BASS_ID, BASS_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
+ addParameter(midParam = new AudioParameterFloat(MID_ID, MID_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
+ addParameter(trebleParam = new AudioParameterFloat(TREBLE_ID, TREBLE_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
+ addParameter(presenceParam = new AudioParameterFloat(PRESENCE_ID, PRESENCE_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f));
addParameter(modelParam = new AudioParameterFloat(MODEL_ID, MODEL_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.001f), 0.0f));
}
@@ -156,17 +160,26 @@ void NeuralPiAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffe
// Setup Audio Data
const int numSamples = buffer.getNumSamples();
const int numInputChannels = getTotalNumInputChannels();
+ const int sampleRate = getSampleRate();
// Amp =============================================================================
if (amp_state == 1) {
auto gain = static_cast<float> (gainParam->get());
auto master = static_cast<float> (masterParam->get());
+ // Note: Default 0.0 -> 1.0 param range is converted to +-8.0 here
+ auto bass = (static_cast<float> (bassParam->get() - 0.5) * 8.0);
+ auto mid = (static_cast<float> (midParam->get() - 0.5) * 8.0);
+ auto treble = (static_cast<float> (trebleParam->get() - 0.5) * 8.0);
+ auto presence = (static_cast<float> (presenceParam->get() - 0.5) * 8.0);
+
auto model = static_cast<float> (modelParam->get());
model_index = getModelIndex(model);
buffer.applyGain(gain);
+ eq4band.setParameters(bass, mid, treble, presence);// Better to move this somewhere else? Only need to set when value changes
+ eq4band.process(buffer.getReadPointer(0), buffer.getWritePointer(0), midiMessages, numSamples, numInputChannels, sampleRate);
- // Apply LSTM model
+ // Apply LSTM model
if (model_loaded == 1) {
if (current_model_index != model_index) {
loadConfig(jsonFiles[model_index]);
@@ -201,6 +214,10 @@ void NeuralPiAudioProcessor::getStateInformation(MemoryBlock& destData)
stream.writeFloat(*gainParam);
stream.writeFloat(*masterParam);
+ stream.writeFloat(*bassParam);
+ stream.writeFloat(*midParam);
+ stream.writeFloat(*trebleParam);
+ stream.writeFloat(*presenceParam);
stream.writeFloat(*modelParam);
}
@@ -210,6 +227,10 @@ void NeuralPiAudioProcessor::setStateInformation(const void* data, int sizeInByt
gainParam->setValueNotifyingHost(stream.readFloat());
masterParam->setValueNotifyingHost(stream.readFloat());
+ bassParam->setValueNotifyingHost(stream.readFloat());
+ midParam->setValueNotifyingHost(stream.readFloat());
+ trebleParam->setValueNotifyingHost(stream.readFloat());
+ presenceParam->setValueNotifyingHost(stream.readFloat());
modelParam->setValueNotifyingHost(stream.readFloat());
}
@@ -225,6 +246,7 @@ void NeuralPiAudioProcessor::loadConfig(File configFile)
model_loaded = 1;
String path = configFile.getFullPathName();
char_filename = path.toUTF8();
+ // TODO Add check here for invalid files
LSTM.load_json(char_filename);
@@ -322,6 +344,11 @@ void NeuralPiAudioProcessor::installTones()
}
+void NeuralPiAudioProcessor::set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider)
+{
+ eq4band.setParameters(bass_slider, mid_slider, treble_slider, presence_slider);
+}
+
float NeuralPiAudioProcessor::convertLogScale(float in_value, float x_min, float x_max, float y_min, float y_max)
{
float b = log(y_max / y_min) / (x_max - x_min);
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
@@ -11,6 +11,7 @@
#include <nlohmann/json.hpp>
#include "RTNeuralLSTM.h"
#include "AmpOSCReceiver.h"
+#include "Eq4Band.h"
#pragma once
@@ -22,6 +23,14 @@
#define MODEL_NAME "Model"
#define MASTER_ID "master"
#define MASTER_NAME "Master"
+#define BASS_ID "bass"
+#define BASS_NAME "Bass"
+#define MID_ID "mid"
+#define MID_NAME "Mid"
+#define TREBLE_ID "treble"
+#define TREBLE_NAME "Treble"
+#define PRESENCE_ID "presence"
+#define PRESENCE_NAME "Presence"
//==============================================================================
/**
@@ -71,6 +80,8 @@ public:
void loadConfig(File configFile);
void setupDataDirectories();
void installTones();
+
+ void set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider);
// Overdrive Pedal
float convertLogScale(float in_value, float x_min, float x_max, float y_min, float y_max);
@@ -79,6 +90,7 @@ public:
/*
void set_ampDrive(float db_ampCleanDrive);
void set_ampMaster(float db_ampMaster);
+ void set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider);
*/
float decibelToLinear(float dbValue);
@@ -104,9 +116,14 @@ public:
private:
var dummyVar;
+ Eq4Band eq4band; // Amp EQ
AudioParameterFloat* gainParam;
AudioParameterFloat* masterParam;
+ AudioParameterFloat* bassParam;
+ AudioParameterFloat* midParam;
+ AudioParameterFloat* trebleParam;
+ AudioParameterFloat* presenceParam;
AudioParameterFloat* modelParam;
//==============================================================================