SmartGuitarAmp

Guitar plugin made with JUCE that uses neural networks to emulate a tube amplifier
Log | Files | Refs | Submodules | README

commit f4014f9b6cadd047c497859f927b398666292192
parent 0a3ea07e0360de0c7e82a07a9649b4520d86ad5b
Author: Keith <smartguitarml@gmail.com>
Date:   Tue, 30 Aug 2022 17:57:36 -0500

Updated graphics, param handling

Diffstat:
Mresources/amp_clean.jpg | 0
Mresources/amp_lead.jpg | 0
Mresources/amp_off.jpg | 0
Mresources/amp_pic.png | 0
Msrc/CMakeLists.txt | 2++
Msrc/PluginEditor.cpp | 128+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/PluginEditor.h | 4++--
Msrc/PluginProcessor.cpp | 82++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/PluginProcessor.h | 12------------
9 files changed, 108 insertions(+), 120 deletions(-)

diff --git a/resources/amp_clean.jpg b/resources/amp_clean.jpg Binary files differ. diff --git a/resources/amp_lead.jpg b/resources/amp_lead.jpg Binary files differ. diff --git a/resources/amp_off.jpg b/resources/amp_off.jpg Binary files differ. diff --git a/resources/amp_pic.png b/resources/amp_pic.png Binary files differ. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -9,6 +9,8 @@ target_sources(SmartAmp PRIVATE ConvolutionLayer.h ConvolutionStack.cpp ConvolutionStack.h + Eq4Band.cpp + Eq4Band.h myLookAndFeel.cpp myLookAndFeel.h PluginEditor.cpp diff --git a/src/PluginEditor.cpp b/src/PluginEditor.cpp @@ -153,19 +153,19 @@ WaveNetVaAudioProcessorEditor::WaveNetVaAudioProcessorEditor (WaveNetVaAudioProc //ampLeadGainKnob.setNumDecimalPlacesToDisplay(1); ampLeadGainKnob.setDoubleClickReturnValue(true, 0.5); - ampMasterSliderAttach = std::make_unique<AudioProcessorValueTreeState::SliderAttachment>(processor.treeState, MASTER_ID, ampMasterKnob); + masterSliderAttach = std::make_unique<AudioProcessorValueTreeState::SliderAttachment>(processor.treeState, MASTER_ID, ampMasterKnob); addAndMakeVisible(ampMasterKnob); ampMasterKnob.setLookAndFeel(&ampSilverKnobLAF); ampMasterKnob.addListener(this); //ampMasterKnob.setRange(-24.0, 0.0); //ampMasterKnob.setValue(processor.ampMasterKnobState); ampMasterKnob.setSliderStyle(juce::Slider::SliderStyle::RotaryVerticalDrag); - //ampMasterKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20 ); - ampMasterKnob.setNumDecimalPlacesToDisplay(1); + ampMasterKnob.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::NoTextBox, false, 50, 20 ); + //ampMasterKnob.setNumDecimalPlacesToDisplay(1); ampMasterKnob.setDoubleClickReturnValue(true, 0.5); // Size of plugin GUI - setSize (1085, 660); + setSize (1085, 540); // Load the preset wavenet json model from the project resources //if (processor.custom_tone == 0) { @@ -178,6 +178,16 @@ WaveNetVaAudioProcessorEditor::WaveNetVaAudioProcessorEditor (WaveNetVaAudioProc WaveNetVaAudioProcessorEditor::~WaveNetVaAudioProcessorEditor() { + ampPresenceKnob.setLookAndFeel(nullptr); + ampCleanBassKnob.setLookAndFeel(nullptr); + ampCleanMidKnob.setLookAndFeel(nullptr); + ampCleanTrebleKnob.setLookAndFeel(nullptr); + ampCleanGainKnob.setLookAndFeel(nullptr); + ampLeadBassKnob.setLookAndFeel(nullptr); + ampLeadMidKnob.setLookAndFeel(nullptr); + ampLeadTrebleKnob.setLookAndFeel(nullptr); + ampLeadGainKnob.setLookAndFeel(nullptr); + ampMasterKnob.setLookAndFeel(nullptr); } //============================================================================== @@ -185,13 +195,13 @@ void WaveNetVaAudioProcessorEditor::paint (Graphics& g) { // Workaround for graphics on Windows builds (clipping code doesn't work correctly on Windows) - #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) - g.drawImageAt(background_clean, 0, 0); // Debug Line: Redraw entire background image - #else - // Redraw only the clipped part of the background image - juce::Rectangle<int> ClipRect = g.getClipBounds(); - g.drawImage(background_clean, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight()); - #endif +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) + g.drawImageAt(background_set, 0, 0); // Debug Line: Redraw entire background image +#else +// Redraw only the clipped part of the background image + juce::Rectangle<int> ClipRect = g.getClipBounds(); + g.drawImage(background_set, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight()); +#endif } @@ -200,43 +210,25 @@ void WaveNetVaAudioProcessorEditor::resized() // This is generally where you'll want to lay out the positions of any // subcomponents in your editor.. - loadButton.setBounds(50, 40, 125, 25); - modelLabel.setBounds(50, 65, 400, 25); // Amp Widgets - ampPresenceKnob.setBounds(97, 495, 75, 105); - ampCleanBassKnob.setBounds(197, 495, 75, 105); - ampCleanMidKnob.setBounds(280, 495, 75, 105); - ampCleanTrebleKnob.setBounds(378, 495, 75, 105); - ampCleanGainKnob.setBounds(456, 495, 75, 105); - ampLeadBassKnob.setBounds(553, 495, 75, 105); - ampLeadMidKnob.setBounds(636, 495, 75, 105); - ampLeadTrebleKnob.setBounds(726, 495, 75, 105); - ampLeadGainKnob.setBounds(806, 495, 75, 105); - ampMasterKnob.setBounds(903, 495, 75, 105); - - ampOnButton.setBounds(9, 495, 35, 45); - ampCleanLeadButton.setBounds(959, 495, 15, 25); - - ampLED.setBounds(975, 160, 15, 25); + ampPresenceKnob.setBounds(97, 375, 75, 105); + ampCleanBassKnob.setBounds(197, 375, 75, 105); + ampCleanMidKnob.setBounds(280, 375, 75, 105); + ampCleanTrebleKnob.setBounds(378, 375, 75, 105); + ampCleanGainKnob.setBounds(456, 375, 75, 105); + ampLeadBassKnob.setBounds(553, 375, 75, 105); + ampLeadMidKnob.setBounds(636, 375, 75, 105); + ampLeadTrebleKnob.setBounds(726, 375, 75, 105); + ampLeadGainKnob.setBounds(806, 375, 75, 105); + ampMasterKnob.setBounds(903, 375, 75, 105); + + ampOnButton.setBounds(9, 375, 35, 45); + ampCleanLeadButton.setBounds(959, 375, 15, 25); + + ampLED.setBounds(975, 40, 15, 25); } -/* -void WaveNetVaAudioProcessorEditor::loadButtonClicked() -{ - FileChooser chooser("Select a .json tone...", - {}, - "*.json"); - if (chooser.browseForFileToOpen()) - { - File file = chooser.getResult(); - processor.loadConfig(file); - fname = file.getFileName(); - modelLabel.setText(fname, juce::NotificationType::dontSendNotification); - processor.loaded_tone = file; - processor.loaded_tone_name = fname; - processor.custom_tone = 1; - } -} + void WaveNetVaAudioProcessorEditor::buttonClicked(juce::Button* button) { @@ -244,11 +236,9 @@ void WaveNetVaAudioProcessorEditor::buttonClicked(juce::Button* button) ampOnButtonClicked(); } else if (button == &ampCleanLeadButton) { ampCleanLeadButtonClicked(); - } else if (button == &loadButton) { - loadButtonClicked(); } } -*/ + void WaveNetVaAudioProcessorEditor::ampOnButtonClicked() { if (processor.amp_state == 0) { @@ -258,44 +248,44 @@ void WaveNetVaAudioProcessorEditor::ampOnButtonClicked() { processor.amp_state = 0; } resetImages(); - repaint(); } + void WaveNetVaAudioProcessorEditor::ampCleanLeadButtonClicked() { - if (processor.amp_lead == 0) { - processor.amp_lead = 1; + if (processor.amp_lead == 1) { + processor.amp_lead = 0; processor.loadConfigAmp(); processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue()); } - else if (processor.amp_lead == 1) { - processor.amp_lead = 0; + else { + processor.amp_lead = 1; processor.loadConfigAmp(); processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue()); } - modelLabel.setText("", juce::NotificationType::dontSendNotification); - processor.loaded_tone_name = ""; - processor.custom_tone = 0; resetImages(); - repaint(); } void WaveNetVaAudioProcessorEditor::sliderValueChanged(Slider* slider) { // Amp - - if (slider == &ampLeadBassKnob || slider == &ampLeadMidKnob || slider == &ampLeadTrebleKnob) { + + if (slider == &ampCleanBassKnob || slider == &ampCleanMidKnob || slider == &ampCleanTrebleKnob) { if (processor.amp_lead == 0) + processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue()); + // Set knob states for saving positions when closing/reopening GUI + + } + else if (slider == &ampLeadBassKnob || slider == &ampLeadMidKnob || slider == &ampLeadTrebleKnob) { + if (processor.amp_lead == 1) processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue()); // Set knob states for saving positions when closing/reopening GUI - processor.ampLeadBassKnobState = ampLeadBassKnob.getValue(); - processor.ampLeadMidKnobState = ampLeadMidKnob.getValue(); - processor.ampLeadTrebleKnobState = ampLeadTrebleKnob.getValue(); + } else if (slider == &ampPresenceKnob) { - if (processor.amp_lead == 1) + if (processor.amp_lead == 0) processor.set_ampEQ(ampCleanBassKnob.getValue(), ampCleanMidKnob.getValue(), ampCleanTrebleKnob.getValue(), ampPresenceKnob.getValue()); - else if (processor.amp_lead == 0) + else if (processor.amp_lead == 1) processor.set_ampEQ(ampLeadBassKnob.getValue(), ampLeadMidKnob.getValue(), ampLeadTrebleKnob.getValue(), ampPresenceKnob.getValue()); } @@ -303,6 +293,13 @@ void WaveNetVaAudioProcessorEditor::sliderValueChanged(Slider* slider) void WaveNetVaAudioProcessorEditor::resetImages() { + if (processor.amp_state == 1 && processor.amp_lead == 1 ) { + background_set = background_lead; + } else if (processor.amp_state == 1 && processor.amp_lead == 0) { + background_set = background_clean; + } else { + background_set = background_off; + } // Set On/Off amp graphic if (processor.amp_state == 0) { ampOnButton.setImages(true, true, true, @@ -329,7 +326,7 @@ void WaveNetVaAudioProcessorEditor::resetImages() 0.0); } // Set clean/lead switch graphic - if (processor.amp_lead == 0) { + if (processor.amp_lead == 1) { ampCleanLeadButton.setImages(true, true, true, ImageCache::getFromMemory(BinaryData::power_switch_down_png, BinaryData::power_switch_down_pngSize), 1.0, Colours::transparentWhite, Image(), 1.0, Colours::transparentWhite, @@ -343,4 +340,5 @@ void WaveNetVaAudioProcessorEditor::resetImages() ImageCache::getFromMemory(BinaryData::power_switch_up_png, BinaryData::power_switch_up_pngSize), 1.0, Colours::transparentWhite, 0.0); } + repaint(); } diff --git a/src/PluginEditor.h b/src/PluginEditor.h @@ -30,7 +30,7 @@ public: void paint (Graphics&) override; void resized() override; - + void resetImages(); private: // This reference is provided as a quick way for your editor to @@ -60,6 +60,7 @@ private: Image background_clean = ImageCache::getFromMemory(BinaryData::amp_clean_jpg, BinaryData::amp_clean_jpgSize); Image background_lead = ImageCache::getFromMemory(BinaryData::amp_lead_jpg, BinaryData::amp_lead_jpgSize); Image background_off = ImageCache::getFromMemory(BinaryData::amp_off_jpg, BinaryData::amp_off_jpgSize); + Image background_set = ImageCache::getFromMemory(BinaryData::amp_clean_jpg, BinaryData::amp_clean_jpgSize); int current_background = 1; TextButton loadButton; @@ -70,7 +71,6 @@ private: virtual void sliderValueChanged(Slider* slider) override; void ampOnButtonClicked(); void ampCleanLeadButtonClicked(); - void resetImages(); public: std::unique_ptr <AudioProcessorValueTreeState::SliderAttachment> cleanGainSliderAttach; diff --git a/src/PluginProcessor.cpp b/src/PluginProcessor.cpp @@ -28,7 +28,7 @@ WaveNetVaAudioProcessor::WaveNetVaAudioProcessor() std::make_unique<AudioParameterFloat>(CLEAN_MID_ID, CLEAN_MID_NAME, NormalisableRange<float>(-8.0f, 8.0f, 0.01f), 0.0f), std::make_unique<AudioParameterFloat>(CLEAN_TREBLE_ID, CLEAN_TREBLE_NAME, NormalisableRange<float>(-8.0f, 8.0f, 0.01f), 0.0f), - std::make_unique<AudioParameterFloat>(LEAD_GAIN_ID, LEAD_GAIN_NAME, NormalisableRange<float>(-10.0f, 10.0f, 0.01f), 0.0f), + std::make_unique<AudioParameterFloat>(LEAD_GAIN_ID, LEAD_GAIN_NAME, NormalisableRange<float>(0.0f, 1.0f, 0.01f), 0.5f), std::make_unique<AudioParameterFloat>(LEAD_BASS_ID, LEAD_BASS_NAME, NormalisableRange<float>(-8.0f, 8.0f, 0.01f), 0.0f), std::make_unique<AudioParameterFloat>(LEAD_MID_ID, LEAD_MID_NAME, NormalisableRange<float>(-8.0f, 8.0f, 0.01f), 0.0f), std::make_unique<AudioParameterFloat>(LEAD_TREBLE_ID, LEAD_TREBLE_NAME, NormalisableRange<float>(-8.0f, 8.0f, 0.01f), 0.0f), @@ -38,6 +38,8 @@ WaveNetVaAudioProcessor::WaveNetVaAudioProcessor() #endif { + loadConfigAmp(); + cleanBassParam = treeState.getRawParameterValue (CLEAN_BASS_ID); cleanMidParam = treeState.getRawParameterValue (CLEAN_MID_ID); cleanTrebleParam = treeState.getRawParameterValue (CLEAN_TREBLE_ID); @@ -48,6 +50,23 @@ WaveNetVaAudioProcessor::WaveNetVaAudioProcessor() leadTrebleParam = treeState.getRawParameterValue (LEAD_TREBLE_ID); presenceParam = treeState.getRawParameterValue (PRESENCE_ID); masterParam = treeState.getRawParameterValue (MASTER_ID); + + + auto cleanBassValue = static_cast<float> (cleanBassParam->load()); + auto cleanMidValue = static_cast<float> (cleanMidParam->load()); + auto cleanTrebleValue = static_cast<float> (cleanTrebleParam->load()); + + auto leadBassValue = static_cast<float> (leadBassParam->load()); + auto leadMidValue = static_cast<float> (leadMidParam->load()); + auto leadTrebleValue = static_cast<float> (leadTrebleParam->load()); + + auto presenceValue = static_cast<float> (presenceParam->load()); + + if (amp_lead == 0) { + eq4band.setParameters(cleanBassValue, cleanMidValue, cleanTrebleValue, presenceValue); + } else { + eq4band.setParameters(leadBassValue, leadMidValue, leadTrebleValue, presenceValue); + } } WaveNetVaAudioProcessor::~WaveNetVaAudioProcessor() @@ -162,15 +181,27 @@ void WaveNetVaAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuff const int numSamples = buffer.getNumSamples(); const int numInputChannels = getTotalNumInputChannels(); + auto cleanGainValue = static_cast<float> (cleanGainParam->load()); + auto cleanBassValue = static_cast<float> (cleanBassParam->load()); + auto cleanMidValue = static_cast<float> (cleanMidParam->load()); + auto cleanTrebleValue = static_cast<float> (cleanTrebleParam->load()); + + auto leadGainValue = static_cast<float> (leadGainParam->load()); + auto leadBassValue = static_cast<float> (leadBassParam->load()); + auto leadMidValue = static_cast<float> (leadMidParam->load()); + auto leadTrebleValue = static_cast<float> (leadTrebleParam->load()); + + auto presenceValue = static_cast<float> (presenceParam->load()); + auto masterValue = static_cast<float> (masterParam->load()); // Amp ============================================================================= if (amp_state == 1) { - if (amp_lead == 1) {// if clean channel eq/gain - buffer.applyGain(ampCleanDrive); + if (amp_lead == 0) {// if clean channel eq/gain + buffer.applyGain(cleanGainValue * 8.0); } else {// else lead channel eq/gain - buffer.applyGain(ampLeadDrive); + buffer.applyGain(leadGainValue * 8.0); } // Wavenet, load json for waveNet2 based on lead/clean switch @@ -179,12 +210,12 @@ void WaveNetVaAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuff eq4band.process(buffer, midiMessages, numSamples, numInputChannels); // Master Volume - buffer.applyGain(ampMaster); + buffer.applyGain(masterValue); // Apply levelAdjust from model param (for adjusting quiet or loud models) - //if ( waveNet.levelAdjust != 0.0 ) { - // buffer.applyGain(waveNet.levelAdjust); - //} + if ( waveNet.levelAdjust != 0.0 ) { + buffer.applyGain(waveNet.levelAdjust); + } } @@ -242,7 +273,7 @@ void WaveNetVaAudioProcessor::loadConfigAmp() // Load Second Wavenet this->suspendProcessing(true); - if (amp_lead == 0) { // if lead on + if (amp_lead == 1) { // if lead on WaveNetLoader loader2(BinaryData::bluej_fullD_p0153_json); float levelAdjust = loader2.levelAdjust; int numChannels2 = loader2.numChannels; @@ -271,44 +302,13 @@ void WaveNetVaAudioProcessor::loadConfigAmp() this->suspendProcessing(false); } -/* -float WaveNetVaAudioProcessor::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); - float a = y_max / exp(b * x_max); - float converted_value = a * exp(b * in_value); - return converted_value; -} - -void WaveNetVaAudioProcessor::set_ampCleanDrive(float db_ampCleanDrive) -{ - ampCleanDrive = decibelToLinear(db_ampCleanDrive); - ampCleanGainKnobState = db_ampCleanDrive; -} - -void WaveNetVaAudioProcessor::set_ampLeadDrive(float db_ampLeadDrive) -{ - ampLeadDrive = decibelToLinear(db_ampLeadDrive); - ampLeadGainKnobState = db_ampLeadDrive; -} -void WaveNetVaAudioProcessor::set_ampMaster(float db_ampMaster) -{ - ampMaster = decibelToLinear(db_ampMaster); - ampMasterKnobState = db_ampMaster; -} -*/ void WaveNetVaAudioProcessor::set_ampEQ(float bass_slider, float mid_slider, float treble_slider, float presence_slider) { eq4band.setParameters(bass_slider, mid_slider, treble_slider, presence_slider); - - ampPresenceKnobState = presence_slider; } -//float WaveNetVaAudioProcessor::decibelToLinear(float dbValue) -//{ -// return powf(10.0, dbValue/20.0); -//} + //============================================================================== // This creates new instances of the plugin.. diff --git a/src/PluginProcessor.h b/src/PluginProcessor.h @@ -106,18 +106,6 @@ public: AudioProcessorValueTreeState treeState; - // Amp knob states - //float ampPresenceKnobState = 0.0; - //float ampCleanBassKnobState = 0.0; - //float ampCleanMidKnobState = 0.0; - //float ampCleanTrebleKnobState = 0.0; - //float ampCleanGainKnobState = 10.0; - //float ampLeadBassKnobState = 0.0; - //float ampLeadMidKnobState = 0.0; - //float ampLeadTrebleKnobState = 0.0; - //float ampLeadGainKnobState = 10.0; - //float ampMasterKnobState = -12.0; - private: WaveNet waveNet; // Amp Clean Channel / Lead Channel Eq4Band eq4band; // Amp EQ