commit f1393acd2b9ad9d34a1d74ee4aadeafa5c1ea2ef
parent db8f783fe0c4bb49998b66f0a257ddbb860c6434
Author: keith <kbloemer89@gmail.com>
Date: Sun, 11 Jul 2021 09:12:35 -0500
Initial IR select implementation
Diffstat:
5 files changed, 170 insertions(+), 21 deletions(-)
diff --git a/Source/CabSim.h b/Source/CabSim.h
@@ -53,6 +53,15 @@ public:
processorChain.reset();
}
+ void load(File irFile) noexcept
+ {
+ auto& convolution = processorChain.template get<convolutionIndex>();
+ convolution.loadImpulseResponse(irFile,
+ juce::dsp::Convolution::Stereo::yes,
+ juce::dsp::Convolution::Trim::no,
+ 1024);
+ }
+
private:
//==============================================================================
enum
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
@@ -80,6 +80,22 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
loadButton.setColour(juce::Label::textColourId, juce::Colours::black);
loadButton.addListener(this);
+ addAndMakeVisible(irSelect);
+ irSelect.setColour(juce::Label::textColourId, juce::Colours::black);
+ int i = 1;
+ for (const auto& jsonFile : processor.irFiles) {
+ irSelect.addItem(jsonFile.getFileNameWithoutExtension(), i);
+ i += 1;
+ }
+ irSelect.onChange = [this] {irSelectChanged(); };
+ irSelect.setSelectedItemIndex(processor.current_ir_index, juce::NotificationType::dontSendNotification);
+ irSelect.setScrollWheelEnabled(true);
+
+ addAndMakeVisible(loadIR);
+ loadIR.setButtonText("Import IR");
+ loadIR.setColour(juce::Label::textColourId, juce::Colours::black);
+ loadIR.addListener(this);
+
//gainSliderAttach = std::make_unique<AudioProcessorValueTreeState::SliderAttachment>(processor.treeState, GAIN_ID, ampGainKnob);
addAndMakeVisible(ampGainKnob);
//ampGainKnob.setLookAndFeel(&SilverKnobLAF);
@@ -388,7 +404,7 @@ NeuralPiAudioProcessorEditor::NeuralPiAudioProcessorEditor (NeuralPiAudioProcess
connectSender();
// Size of plugin GUI
- setSize(276, 430);
+ setSize(276, 455);
}
@@ -415,37 +431,40 @@ void NeuralPiAudioProcessorEditor::resized()
// This is generally where you'll want to lay out the positions of any
// subcomponents in your editor..
modelSelect.setBounds(19, 10, 234, 25);
- loadButton.setBounds(19, 42, 100, 25);
+ loadButton.setBounds(19, 74, 100, 25);
modelKnob.setBounds(140, 40, 75, 95);
+ irSelect.setBounds(19, 42, 234, 25);
+ loadIR.setBounds(125, 74, 100, 25);
+
// Amp Widgets
- ampGainKnob.setBounds(15, 90, 75, 95);
- ampMasterKnob.setBounds(100, 90, 75, 95);
- ampBassKnob.setBounds(15, 225, 75, 95);
- ampMidKnob.setBounds(100, 225, 75, 95);
- ampTrebleKnob.setBounds(185, 225, 75, 95);
- ampPresenceKnob.setBounds(185, 90, 75, 95);
-
- GainLabel.setBounds(11, 78, 80, 10);
- LevelLabel.setBounds(98, 78, 80, 10);
- BassLabel.setBounds(11, 213, 80, 10);
- MidLabel.setBounds(97, 213, 80, 10);
- TrebleLabel.setBounds(183, 213, 80, 10);
- PresenceLabel.setBounds(183, 78, 80, 10);
+ ampGainKnob.setBounds(15, 120, 75, 95);
+ ampMasterKnob.setBounds(100, 120, 75, 95);
+ ampBassKnob.setBounds(15, 250, 75, 95);
+ ampMidKnob.setBounds(100, 250, 75, 95);
+ ampTrebleKnob.setBounds(185, 250, 75, 95);
+ ampPresenceKnob.setBounds(185, 120, 75, 95);
+
+ GainLabel.setBounds(11, 108, 80, 10);
+ LevelLabel.setBounds(98, 108, 80, 10);
+ BassLabel.setBounds(11, 238, 80, 10);
+ MidLabel.setBounds(97, 238, 80, 10);
+ TrebleLabel.setBounds(183, 238, 80, 10);
+ PresenceLabel.setBounds(183, 108, 80, 10);
addAndMakeVisible(ampNameLabel);
ampNameField.setEditable(true, true, true);
addAndMakeVisible(ampNameField);
// IP controls:
- ipField.setBounds(150, 340, 100, 25);
- ipLabel.setBounds(15, 340, 150, 25);
+ ipField.setBounds(150, 365, 100, 25);
+ ipLabel.setBounds(15, 365, 150, 25);
// Port controls:
- outPortNumberLabel.setBounds(15, 370, 150, 25);
- outPortNumberField.setBounds(160, 370, 75, 25);
- inPortNumberLabel.setBounds(15, 400, 150, 25);
- inPortNumberField.setBounds(160, 400, 75, 25);
+ outPortNumberLabel.setBounds(15, 395, 150, 25);
+ outPortNumberField.setBounds(160, 395, 75, 25);
+ inPortNumberLabel.setBounds(15, 425, 150, 25);
+ inPortNumberField.setBounds(160, 425, 75, 25);
}
void NeuralPiAudioProcessorEditor::modelSelectChanged()
@@ -460,6 +479,18 @@ void NeuralPiAudioProcessorEditor::modelSelectChanged()
//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();
+ }
+ //auto newValue = static_cast<float>(processor.current_ir_index / (processor.num_irs - 1.0));
+ //modelKnob.setValue(newValue);
+ //modelKnob.setValue(processor.current_model_index);
+}
+
void NeuralPiAudioProcessorEditor::loadButtonClicked()
{
FileChooser chooser("Select one or more .json tone files to import",
@@ -495,12 +526,51 @@ void NeuralPiAudioProcessorEditor::loadButtonClicked()
}
}
+void NeuralPiAudioProcessorEditor::loadIRClicked()
+{
+ FileChooser chooser("Select one or more .wav IR files to import",
+ {},
+ "*.wav");
+ if (chooser.browseForMultipleFilesToOpen())
+ {
+ int import_fail = 1;
+ Array<File> files = chooser.getResults();
+ for (auto file : files) {
+ File fullpath = processor.userAppDataDirectory_irs.getFullPathName() + "/" + file.getFileName();
+ bool b = fullpath.existsAsFile();
+ if (b == false) {
+
+ processor.loadIR(file);
+ fname = file.getFileName();
+ processor.loaded_ir = file;
+ processor.loaded_ir_name = fname;
+ processor.custom_ir = 1;
+
+ // Copy selected file to model directory and load into dropdown menu
+ bool a = file.copyFileTo(fullpath);
+ if (a == true) {
+ 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;
+ }
+ // Sort jsonFiles alphabetically
+ std::sort(processor.irFiles.begin(), processor.irFiles.end());
+ }
+ }
+ }
+}
+
void NeuralPiAudioProcessorEditor::buttonClicked(juce::Button* button)
{
if (button == &loadButton) {
loadButtonClicked();
}
+ else
+ {
+ loadIRClicked();
+ }
}
diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h
@@ -75,6 +75,7 @@ private:
//ImageButton ampOnButton;
//ImageButton ampLED;
ComboBox modelSelect;
+ ComboBox irSelect;
Slider ampBassKnob;
Slider ampMidKnob;
Slider ampTrebleKnob;
@@ -91,10 +92,13 @@ private:
File model_folder;
TextButton loadButton;
+ TextButton loadIR;
juce::String fname;
virtual void buttonClicked(Button* button) override;
void modelSelectChanged();
void loadButtonClicked();
+ void irSelectChanged();
+ void loadIRClicked();
virtual void sliderValueChanged(Slider* slider) override;
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
@@ -37,6 +37,12 @@ NeuralPiAudioProcessor::NeuralPiAudioProcessor()
// Sort jsonFiles alphabetically
std::sort(jsonFiles.begin(), jsonFiles.end());
+ if (irFiles.size() > 0) {
+ loadIR(irFiles[current_ir_index]);
+ }
+ // Sort irFiles alphabetically
+ std::sort(irFiles.begin(), irFiles.end());
+
// 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));
@@ -276,6 +282,18 @@ void NeuralPiAudioProcessor::loadConfig(File configFile)
this->suspendProcessing(false);
}
+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);
+
+ this->suspendProcessing(false);
+}
+
void NeuralPiAudioProcessor::resetDirectory(const File& file)
{
jsonFiles.clear();
@@ -288,6 +306,18 @@ void NeuralPiAudioProcessor::resetDirectory(const File& file)
}
}
+void NeuralPiAudioProcessor::resetDirectoryIR(const File& file)
+{
+ irFiles.clear();
+ if (file.isDirectory())
+ {
+ juce::Array<juce::File> results;
+ file.findChildFiles(results, juce::File::findFiles, false, "*.wav");
+ for (int i = results.size(); --i >= 0;)
+ irFiles.push_back(File(results.getReference(i).getFullPathName()));
+ }
+}
+
void NeuralPiAudioProcessor::addDirectory(const File& file)
{
if (file.isDirectory())
@@ -302,6 +332,20 @@ void NeuralPiAudioProcessor::addDirectory(const File& file)
}
}
+void NeuralPiAudioProcessor::addDirectoryIR(const File& file)
+{
+ if (file.isDirectory())
+ {
+ juce::Array<juce::File> results;
+ file.findChildFiles(results, juce::File::findFiles, false, "*.wav");
+ for (int i = results.size(); --i >= 0;)
+ {
+ irFiles.push_back(File(results.getReference(i).getFullPathName()));
+ num_irs = num_irs + 1.0;
+ }
+ }
+}
+
void NeuralPiAudioProcessor::setupDataDirectories()
{
// User app data directory
@@ -309,6 +353,7 @@ void NeuralPiAudioProcessor::setupDataDirectories()
File userAppDataTempFile_tones = userAppDataDirectory_tones.getChildFile("tmp.pdl");
+ File userAppDataTempFile_irs = userAppDataDirectory_irs.getChildFile("tmp.pdl");
// Create (and delete) temp file if necessary, so that user doesn't have
// to manually create directories
@@ -326,9 +371,17 @@ void NeuralPiAudioProcessor::setupDataDirectories()
userAppDataTempFile_tones.deleteFile();
}
+ if (!userAppDataDirectory_irs.exists()) {
+ userAppDataTempFile_irs.create();
+ }
+ if (userAppDataTempFile_irs.existsAsFile()) {
+ userAppDataTempFile_irs.deleteFile();
+ }
+
// Add the tones directory and update tone list
addDirectory(userAppDataDirectory_tones);
+ addDirectoryIR(userAppDataDirectory_irs);
}
void NeuralPiAudioProcessor::installTones()
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
@@ -79,6 +79,7 @@ public:
bool compareFunction(juce::File a, juce::File b);
int getModelIndex(float model_param);
void loadConfig(File configFile);
+ void loadIR(File irFile);
void setupDataDirectories();
void installTones();
@@ -89,11 +90,15 @@ public:
float decibelToLinear(float dbValue);
void addDirectory(const File& file);
+ void addDirectoryIR(const File& file);
void resetDirectory(const File& file);
+ void resetDirectoryIR(const File& file);
std::vector<File> jsonFiles;
+ std::vector<File> irFiles;
File currentDirectory = File::getCurrentWorkingDirectory().getFullPathName();
File userAppDataDirectory = File::getSpecialLocation(File::userDocumentsDirectory).getChildFile(JucePlugin_Manufacturer).getChildFile(JucePlugin_Name);
File userAppDataDirectory_tones = userAppDataDirectory.getFullPathName() + "/tones";
+ File userAppDataDirectory_irs = userAppDataDirectory.getFullPathName() + "/irs";
// Pedal/amp states
int amp_state = 1; // 0 = off, 1 = on
@@ -106,6 +111,14 @@ public:
float num_models = 0.0;
int model_index = 0; // Used in processBlock when converting slider param to model index
+ juce::String loaded_ir_name;
+ float num_irs = 0.0;
+ int ir_loaded = 0;
+ int custom_ir = 0; // 0 = custom tone loaded, 1 = default channel tone
+ File loaded_ir;
+
+ int current_ir_index = 0;
+
RT_LSTM LSTM;
private: