commit 4c7ca0c6ede0129915b740f6a6ad6d2e6233a9c6
parent b3f649deb8108e073908e8f9ec2f103f07df15b9
Author: keith <kbloemer89@gmail.com>
Date: Sat, 17 Jul 2021 05:20:12 -0500
Updated IR for OSC messages, updated scripts for ir
Diffstat:
8 files changed, 141 insertions(+), 35 deletions(-)
diff --git a/Source/AmpOSCReceiver.h b/Source/AmpOSCReceiver.h
@@ -49,6 +49,11 @@ public:
return modelValue;
}
+ Value& getIrValue()
+ {
+ return irValue;
+ }
+
void changePort (int port)
{
if (! connect (port))
@@ -84,6 +89,7 @@ private:
trebleAddressPattern = "/parameter/" + ampName + "/Treble";
presenceAddressPattern = "/parameter/" + ampName + "/Presence";
modelAddressPattern = "/parameter/" + ampName + "/Model";
+ irAddressPattern = "/parameter/" + ampName + "/Ir";
}
void oscMessageReceived(const OSCMessage& message) override
@@ -124,6 +130,10 @@ private:
{
modelValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
}
+ else if (message.getAddressPattern().matches(irAddressPattern))
+ {
+ irValue.setValue(jlimit(0.0f, 1.0f, message[0].getFloat32()));
+ }
}
}
@@ -138,6 +148,7 @@ private:
String trebleAddressPattern {"/parameter/elk_juce_example/Treble"};
String presenceAddressPattern {"/parameter/elk_juce_example/Presence"};
String modelAddressPattern {"/parameter/elk_juce_example/Model"};
+ String irAddressPattern {"/parameter/elk_juce_example/Ir"};
Value gainValue {0.5f};
Value masterValue {0.5f};
@@ -147,6 +158,7 @@ private:
Value presenceValue {0.5f};
Value modelValue {0.0f};
+ Value irValue {0.0f};
bool connected = false;
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
@@ -80,6 +80,47 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
loadButton.setColour(juce::Label::textColourId, juce::Colours::black);
loadButton.addListener(this);
+
+ //addAndMakeVisible(irKnob);
+ //irKnob.setLookAndFeel(&SilverKnobLAF);
+ irKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxBelow, false, 50, 20);
+ irKnob.setNumDecimalPlacesToDisplay(1);
+ irKnob.addListener(this);
+ //irKnob.setRange(0, processor.irFiles.size() - 1);
+ irKnob.setRange(0.0, 1.0);
+ irKnob.setValue(0.0);
+ irKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag);
+ irKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20);
+ irKnob.setNumDecimalPlacesToDisplay(1);
+ irKnob.setDoubleClickReturnValue(true, 0.0);
+
+ auto irValue = getParameterValue(irName);
+ Slider& irSlider = getIrSlider();
+ irSlider.setValue(irValue, NotificationType::dontSendNotification);
+
+ irKnob.onValueChange = [this]
+ {
+ const float sliderValue = static_cast<float> (getIrSlider().getValue());
+ const float irValue = getParameterValue(irName);
+
+ if (!approximatelyEqual(irValue, sliderValue))
+ {
+ setParameterValue(irName, sliderValue);
+
+ // create and send an OSC message with an address and a float value:
+ float value = static_cast<float> (getIrSlider().getValue());
+
+ if (!oscSender.send(irAddressPattern, value))
+ {
+ updateOutConnectedLabel(false);
+ }
+ else
+ {
+ DBG("Sent value " + String(value) + " to AP " + irAddressPattern);
+ }
+ }
+ };
+
addAndMakeVisible(irSelect);
irSelect.setColour(juce::Label::textColourId, juce::Colours::black);
int i = 1;
@@ -409,6 +450,7 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
oscReceiver.getPresenceValue().addListener(this);
oscReceiver.getModelValue().addListener(this);
+ oscReceiver.getIrValue().addListener(this);
updateInConnectedLabel();
@@ -416,7 +458,6 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
// Size of plugin GUI
setSize(276, 455);
-
}
NeuralPiAudioProcessorEditor::~NeuralPiAudioProcessorEditor()
@@ -483,25 +524,27 @@ void NeuralPiAudioProcessorEditor::resized()
void NeuralPiAudioProcessorEditor::modelSelectChanged()
{
const int selectedFileIndex = modelSelect.getSelectedItemIndex();
+ File selectedFile = processor.userAppDataDirectory_tones.getFullPathName() + "/" + modelSelect.getText() + ".json";
if (selectedFileIndex >= 0 && selectedFileIndex < processor.jsonFiles.size()) {
- processor.loadConfig(processor.jsonFiles[selectedFileIndex]);
- processor.current_model_index = modelSelect.getSelectedItemIndex();
+ //processor.loadConfig(processor.jsonFiles[selectedFileIndex]);
+ processor.loadConfig(selectedFile);
+ processor.current_model_index = selectedFileIndex;
}
auto newValue = static_cast<float>(processor.current_model_index / (processor.num_models - 1.0));
modelKnob.setValue(newValue);
- //modelKnob.setValue(processor.current_model_index);
}
void NeuralPiAudioProcessorEditor::irSelectChanged()
{
const int selectedFileIndex = irSelect.getSelectedItemIndex();
- if (selectedFileIndex >= 0 && selectedFileIndex < processor.jsonFiles.size()) {
- processor.loadIR(processor.irFiles[selectedFileIndex]);
- processor.current_ir_index = irSelect.getSelectedItemIndex();
+ File selectedFile = processor.userAppDataDirectory_irs.getFullPathName() + "/" + irSelect.getText() + ".wav";
+ if (selectedFileIndex >= 0 && selectedFileIndex < processor.irFiles.size()) {
+ //processor.loadIR(processor.irFiles[selectedFileIndex]);
+ processor.loadIR(selectedFile);
+ processor.current_ir_index = selectedFileIndex;
}
- //auto newValue = static_cast<float>(processor.current_ir_index / (processor.num_irs - 1.0));
- //modelKnob.setValue(newValue);
- //modelKnob.setValue(processor.current_model_index);
+ auto newValue = static_cast<float>(processor.current_ir_index / (processor.num_irs - 1.0));
+ irKnob.setValue(newValue);
}
void NeuralPiAudioProcessorEditor::updateToggleState(juce::Button* button, juce::String name)
@@ -538,7 +581,7 @@ void NeuralPiAudioProcessorEditor::loadButtonClicked()
modelSelect.addItem(file.getFileNameWithoutExtension(), processor.jsonFiles.size() + 1);
modelSelect.setSelectedItemIndex(processor.jsonFiles.size(), juce::NotificationType::dontSendNotification);
processor.jsonFiles.push_back(file);
- //processor.num_models += 1;
+ processor.num_models += 1;
}
// Sort jsonFiles alphabetically
std::sort(processor.jsonFiles.begin(), processor.jsonFiles.end());
@@ -573,7 +616,7 @@ void NeuralPiAudioProcessorEditor::loadIRClicked()
irSelect.addItem(file.getFileNameWithoutExtension(), processor.irFiles.size() + 1);
irSelect.setSelectedItemIndex(processor.irFiles.size(), juce::NotificationType::dontSendNotification);
processor.irFiles.push_back(file);
- //processor.num_models += 1;
+ processor.num_irs += 1;
}
// Sort jsonFiles alphabetically
std::sort(processor.irFiles.begin(), processor.irFiles.end());
@@ -597,25 +640,16 @@ void NeuralPiAudioProcessorEditor::buttonClicked(juce::Button* button)
void NeuralPiAudioProcessorEditor::sliderValueChanged(Slider* slider)
{
- if (slider == &modelKnob)
+ 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());
+ } else if (slider == &irKnob) {
+ if (slider->getValue() >= 0 && slider->getValue() < processor.irFiles.size()) {
+ irSelect.setSelectedItemIndex(processor.getIrIndex(slider->getValue()), juce::NotificationType::dontSendNotification);
+ }
}
}
-*/
-
// OSC Messages
Slider& NeuralPiAudioProcessorEditor::getGainSlider()
@@ -653,6 +687,11 @@ Slider& NeuralPiAudioProcessorEditor::getModelSlider()
return modelKnob;
}
+Slider& NeuralPiAudioProcessorEditor::getIrSlider()
+{
+ return irKnob;
+}
+
Label& NeuralPiAudioProcessorEditor::getOutPortNumberField()
{
@@ -693,6 +732,7 @@ void NeuralPiAudioProcessorEditor::buildAddressPatterns()
trebleAddressPattern = "/parameter/" + ampName + "/Treble";
presenceAddressPattern = "/parameter/" + ampName + "/Presence";
modelAddressPattern = "/parameter/" + ampName + "/Model";
+ modelAddressPattern = "/parameter/" + ampName + "/Ir";
}
void NeuralPiAudioProcessorEditor::connectSender()
@@ -832,6 +872,14 @@ void NeuralPiAudioProcessorEditor::valueChanged(Value& value)
NotificationType::sendNotification);
}
}
+ else if (value.refersToSameSourceAs(oscReceiver.getIrValue()))
+ {
+ if (!approximatelyEqual(static_cast<double> (value.getValue()), getIrSlider().getValue()))
+ {
+ getIrSlider().setValue(static_cast<double> (value.getValue()),
+ NotificationType::sendNotification);
+ }
+ }
}
void NeuralPiAudioProcessorEditor::timerCallback()
@@ -843,6 +891,7 @@ void NeuralPiAudioProcessorEditor::timerCallback()
getTrebleSlider().setValue(getParameterValue(trebleName), NotificationType::dontSendNotification);
getPresenceSlider().setValue(getParameterValue(presenceName), NotificationType::dontSendNotification);
getModelSlider().setValue(getParameterValue(modelName), NotificationType::dontSendNotification);
+ getIrSlider().setValue(getParameterValue(irName), NotificationType::dontSendNotification);
}
AudioProcessorParameter* NeuralPiAudioProcessorEditor::getParameter(const String& paramId)
diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h
@@ -46,6 +46,7 @@ public:
String gainAddressPattern{ "/parameter/NeuralPi/Gain" };
String masterAddressPattern{ "/parameter/NeuralPi/Master" };
String modelAddressPattern{ "/parameter/NeuralPi/Model" };
+ String irAddressPattern{ "/parameter/NeuralPi/Ir" };
String bassAddressPattern{ "/parameter/NeuralPi/Bass" };
String midAddressPattern{ "/parameter/NeuralPi/Mid" };
String trebleAddressPattern{ "/parameter/NeuralPi/Treble" };
@@ -59,7 +60,7 @@ public:
const String presenceName{ "presence" };
const String modelName{ "model" };
-
+ const String irName{ "ir" };
private:
// This reference is provided as a quick way for your editor to
@@ -72,6 +73,7 @@ private:
Slider ampGainKnob;
Slider ampMasterKnob;
Slider modelKnob;
+ Slider irKnob;
//ImageButton ampOnButton;
//ImageButton ampLED;
ComboBox modelSelect;
@@ -130,6 +132,7 @@ private:
Slider& getGainSlider();
Slider& getMasterSlider();
Slider& getModelSlider();
+ Slider& getIrSlider();
Slider& getBassSlider();
Slider& getMidSlider();
Slider& getTrebleSlider();
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
@@ -51,6 +51,7 @@ NeuralPiAudioProcessor::NeuralPiAudioProcessor()
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));
+ addParameter(irParam = new AudioParameterFloat(IR_ID, IR_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.001f), 0.0f));
}
@@ -189,6 +190,9 @@ void NeuralPiAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffe
auto model = static_cast<float> (modelParam->get());
model_index = getModelIndex(model);
+ auto ir = static_cast<float> (irParam->get());
+ ir_index = getIrIndex(ir);
+
buffer.applyGain(gain * 2.0);
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);
@@ -204,6 +208,10 @@ void NeuralPiAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffe
// Process IR
if (ir_state == true) {
+ if (current_ir_index != ir_index) {
+ loadIR(irFiles[ir_index]);
+ current_ir_index = ir_index;
+ }
auto block = dsp::AudioBlock<float>(buffer).getSingleChannelBlock(0);
auto context = juce::dsp::ProcessContextReplacing<float>(block);
cabSimIR.process(context);
@@ -244,6 +252,7 @@ void NeuralPiAudioProcessor::getStateInformation(MemoryBlock& destData)
stream.writeFloat(*trebleParam);
stream.writeFloat(*presenceParam);
stream.writeFloat(*modelParam);
+ stream.writeFloat(*irParam);
}
void NeuralPiAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
@@ -257,6 +266,7 @@ void NeuralPiAudioProcessor::setStateInformation(const void* data, int sizeInByt
trebleParam->setValueNotifyingHost(stream.readFloat());
presenceParam->setValueNotifyingHost(stream.readFloat());
modelParam->setValueNotifyingHost(stream.readFloat());
+ irParam->setValueNotifyingHost(stream.readFloat());
}
int NeuralPiAudioProcessor::getModelIndex(float model_param)
@@ -271,6 +281,18 @@ int NeuralPiAudioProcessor::getModelIndex(float model_param)
return a;
}
+int NeuralPiAudioProcessor::getIrIndex(float ir_param)
+{
+ int a = static_cast<int>(round(ir_param * (num_irs - 1.0)));
+ if (a > num_irs - 1) {
+ a = num_irs - 1;
+ }
+ else if (a < 0) {
+ a = 0;
+ }
+ return a;
+}
+
void NeuralPiAudioProcessor::loadConfig(File configFile)
{
this->suspendProcessing(true);
@@ -288,8 +310,6 @@ void NeuralPiAudioProcessor::loadIR(File irFile)
{
this->suspendProcessing(true);
ir_loaded = 1;
- //String path = irFile.getFullPathName();
- //char_filename = path.toUTF8();
// TODO Add check here for invalid files
cabSimIR.load(irFile);
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
@@ -22,6 +22,8 @@
#define GAIN_NAME "Gain"
#define MODEL_ID "model"
#define MODEL_NAME "Model"
+#define IR_ID "ir"
+#define IR_NAME "Ir"
#define MASTER_ID "master"
#define MASTER_NAME "Master"
#define BASS_ID "bass"
@@ -77,6 +79,7 @@ public:
void setStateInformation (const void* data, int sizeInBytes) override;
int getModelIndex(float model_param);
+ int getIrIndex(float ir_param);
void loadConfig(File configFile);
void loadIR(File irFile);
void setupDataDirectories();
@@ -117,8 +120,8 @@ public:
int custom_ir = 0; // 0 = custom tone loaded, 1 = default channel tone
File loaded_ir;
bool ir_state = true;
-
int current_ir_index = 0;
+ int ir_index = 0;
RT_LSTM LSTM;
@@ -133,6 +136,7 @@ private:
AudioParameterFloat* trebleParam;
AudioParameterFloat* presenceParam;
AudioParameterFloat* modelParam;
+ AudioParameterFloat* irParam;
dsp::IIR::Filter<float> dcBlocker;
diff --git a/resources/npi_background.jpg b/resources/npi_background.jpg
Binary files differ.
diff --git a/scripts/update_models.bat b/scripts/update_models.bat
@@ -1,10 +1,10 @@
::############################################################################
:: NeuralPi - Update Models - Windows Script
::
-:: This script transfers models from a Windows computer to the NeuralPi,
-:: and from the NeuralPi back to the host computer. Edit the Raspberry Pi
-:: IP address (after connecting to a local Wifi Network), and run this
-:: script from a Windows computer running the NeuralPi plugin.
+:: This script transfers models and impulse responses from a Windows computer
+:: to the NeuralPi, and from the NeuralPi back to the host computer. Edit
+:: the Raspberry Pi IP address (after connecting to a local Wifi Network),
+:: and run this script from a Windows computer running the NeuralPi plugin.
::
:: Note: Ensure OpenSSH is installed. This comes installed with Windows as of 2018.
::############################################################################
@@ -17,15 +17,24 @@ set "rpi_ip_address=127.0.0.1"
:: Typical Windows 10 Path, edit <YOUR_USERNAME> with your Windows Username
set "host_model_path=C:/Users/<YOUR_USERNAME>/Documents/GuitarML/NeuralPi/tones"
+set "host_ir_path=C:/Users/<YOUR_USERNAME>/Documents/GuitarML/NeuralPi/irs"
:: Rpi with Elk OS Path (shouldn't need to change)
set "rpi_model_path=/home/mind/Documents/GuitarML/NeuralPi/tones"
+set "rpi_ir_path=/home/mind/Documents/GuitarML/NeuralPi/irs"
:: ############################################################################
:: Copy all models from local computer to Rpi
scp %host_model_path%/*.json root@%rpi_ip_address%:%rpi_model_path%/
+:: Copy all IRs from local computer to Rpi
+scp %host_ir_path%/*.wav root@%rpi_ip_address%:%rpi_ir_path%/
+
+
:: Copy all models from Rpi to local computer
scp root@%rpi_ip_address%:%rpi_model_path%/*.json %host_model_path%/
+
+:: Copy all IRs from Rpi to local computer
+scp root@%rpi_ip_address%:%rpi_ir_path%/*.wav %host_ir_path%/
diff --git a/scripts/update_models.sh b/scripts/update_models.sh
@@ -18,13 +18,22 @@ rpi_ip_address=127.0.0.1 # Update this field with the Raspberry Pi's IP address
# Uncomment the appropriate path for your computer:
host_model_path=~/Documents/GuitarML/NeuralPi/tones #Typical Mac/Linux Path (shouldn't need to change)
+host_ir_path=~/Documents/GuitarML/NeuralPi/irs #Typical Mac/Linux Path (shouldn't need to change)
rpi_model_path=/home/mind/Documents/GuitarML/NeuralPi/tones # Rpi with Elk OS Path (shouldn't need to change)
+rpi_ir_path=/home/mind/Documents/GuitarML/NeuralPi/irs # Rpi with Elk OS Path (shouldn't need to change)
#############################################################################
echo "Copying all models from local computer to Rpi.."
scp $host_model_path/*.json root@$rpi_ip_address:$rpi_model_path/
+echo "Copying all IRs from local computer to Rpi.."
+scp $host_ir_path/*.json root@$rpi_ip_address:$rpi_ir_path/
+
+
echo "Copying all models from Rpi to local computer.."
-scp root@$rpi_ip_address:$rpi_model_path/*.json $host_model_path/
+scp root@$rpi_ip_address:$rpi_model_path/*.wav $host_model_path/
+
+echo "Copying all IRs from Rpi to local computer.."
+scp root@$rpi_ip_address:$rpi_ir_path/*.wav $host_ir_path/