Skip to content

Commit

Permalink
Merge pull request #12 from GuitarML/v1-5-updates
Browse files Browse the repository at this point in the history
V1 5 updates
  • Loading branch information
GuitarML authored Oct 5, 2022
2 parents 1969167 + 032d88f commit 1182756
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 63 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.15)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment target")
project(SmartPedal VERSION 1.4.0)
project(SmartPedal VERSION 1.5.0)

set(CMAKE_CXX_STANDARD 17)

Expand Down Expand Up @@ -29,7 +29,7 @@ juce_add_plugin(SmartPedal
PLUGIN_CODE Sgp3
FORMATS ${JUCE_FORMATS}
ProductName "SmartPedal"
LV2_URI https://github.com/GuitarML/SmartPedal
LV2_URI https://github.com/GuitarML/SmartGuitarPedal
ICON_BIG resources/logo.png
MICROPHONE_PERMISSION_ENABLED TRUE
)
Expand Down
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,28 @@

Guitar plugin made with JUCE that uses neural network models to emulate real world hardware.

Checkout the tutorial on [YouTube](https://youtu.be/HrNf6DNRUdU) for creating your own models for the SmartPedal.
- Checkout the tutorial on [YouTube](https://youtu.be/HrNf6DNRUdU) for creating your own models for the SmartPedal.
- Visit the GuitarML [ToneLibrary Website](https://guitarml.com/tonelibrary/tonelib-sa.html) to download SmartPedal compatible models.

![app](https://github.com/GuitarML/SmartGuitarPedal/blob/master/resources/app_pic.png)

This plugin uses a WaveNet model to recreate the sound of real world hardware, such as
a TS9 Tubescreamer or Blues Jr amp. Drive and Level are used for simple ways to
control the sound. The WaveNet model is effective at emulating distortion style effects or tube amplifiers.
a TS9 Tubescreamer or Blues Jr amp. Drive and Level adjust the signal gain before and after the
WaveNet model processing. As of version 1.5, the SmartPedal can run models conditioned on a single parameter,
such as a gain control. When conditioned models are loaded, the LED graphic will change colors
from red to blue, and the Drive knob will control the conditioned parameter.

![app](https://github.com/keyth72/SmartGuitarPedal/blob/master/resources/app_pic.png)
The WaveNet model is effective at emulating distortion style effects or tube amplifiers, but cannot capture
time based effects such as reverb or delay. You can capture the sound of an amplifier either by recording with
a microphone, or direct out from a load box. When running "Direct Out" models, you will need to use an
Impulse Response plugin to accurately model the amp speaker/cabinet.

You can create your own models and load them in SmartGuitarPedal using the [PedalNetRT](https://github.com/GuitarML/PedalNetRT) repository.
You can create your own models and load them in SmartGuitarPedal using the [PedalNetRT](https://github.com/GuitarML/PedalNetRT) repository directly, or
by using the Capture Utility files (available for download at [GuitarML.com](https://guitarml.com/)) with Google Colab and following the [Video Tutorial](https://youtu.be/HrNf6DNRUdU).

Model training is done using PyTorch on pre recorded .wav samples. More info in the above repository.
To share your best models, email the json files to smartguitarml@gmail.com and they may be included
in the latest release as a downloadable zip.

in the latest [ToneLibrary](https://guitarml.com/tonelibrary/tonelib-sa.html) release.

Also see companion plugin, the [SmartGuitarAmp](https://github.com/GuitarML/SmartGuitarAmp)

Expand Down Expand Up @@ -52,3 +60,6 @@ a different model architecture and will not be compatible. Only WaveNet models t
This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details.

This project builds off the work done in the [WaveNetVA](https://github.com/damskaggep/WaveNetVA) repository.

### Special Thanks
Special thanks to Stefan Schmidt for the graphics in SmartPedal version 1.5. These were created from a Blender model and rendered using the Cycles render engine.
2 changes: 1 addition & 1 deletion installers/linux/build_deb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Set the app name and version here
app_name=SmartPedal
version=1.4
version=1.5


# 1. Create the package directory structure and control file
Expand Down
9 changes: 3 additions & 6 deletions resources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
juce_add_binary_data(BinaryData SOURCES
footswitch_down.png
footswitch_up.png
knob2.png
knob_hex.png
led_blue_off.png
led_blue_on.png
led_red_off.png
led_red_on.png
smart_pedal.jpg
background_on.jpg
background_on_blue.jpg
background_off.jpg

)

Expand Down
Binary file modified resources/app_pic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/background_off.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/background_on.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/background_on_blue.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/footswitch_down.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/footswitch_up.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/knob_hex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 35 additions & 32 deletions src/PluginEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ SmartPedalAudioProcessorEditor::SmartPedalAudioProcessorEditor (SmartPedalAudioP
addAndMakeVisible(odFootSw);
odFootSw.addListener(this);

odLED.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
0.0);
addAndMakeVisible(odLED);
//odLED.setImages(true, true, true,
// ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
// Image(), 1.0, Colours::transparentWhite,
// ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
// 0.0);
//addAndMakeVisible(odLED);

driveSliderAttach = std::make_unique<AudioProcessorValueTreeState::SliderAttachment>(processor.treeState, GAIN_ID, odDriveKnob);
addAndMakeVisible(odDriveKnob);
Expand All @@ -81,7 +81,7 @@ SmartPedalAudioProcessorEditor::SmartPedalAudioProcessorEditor (SmartPedalAudioP
odLevelKnob.setDoubleClickReturnValue(true, 0.5);

addAndMakeVisible(versionLabel);
versionLabel.setText("v1.4", juce::NotificationType::dontSendNotification);
versionLabel.setText("v1.5", juce::NotificationType::dontSendNotification);
versionLabel.setJustificationType(juce::Justification::left);
versionLabel.setColour(juce::Label::textColourId, juce::Colours::black);
//auto font = versionLabel.getFont();
Expand All @@ -105,13 +105,25 @@ SmartPedalAudioProcessorEditor::~SmartPedalAudioProcessorEditor()
void SmartPedalAudioProcessorEditor::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, 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, 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__)
if (processor.fw_state == 0) {
g.drawImageAt(background_off, 0, 0); // Debug Line: Redraw entire background image
} else if (processor.fw_state == 1 && processor.conditioned == true) {
g.drawImageAt(background_on_blue, 0, 0); // Debug Line: Redraw entire background image
} else if (processor.fw_state == 1 && processor.conditioned == false) {
g.drawImageAt(background_on, 0, 0); // Debug Line: Redraw entire background image
}
#else
// Redraw only the clipped part of the background image

juce::Rectangle<int> ClipRect = g.getClipBounds();
if (processor.fw_state == 0) {
g.drawImage(background_off, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
} else if (processor.fw_state == 1 && processor.conditioned == true) {
g.drawImage(background_on_blue, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
} else if (processor.fw_state == 1 && processor.conditioned == false)
g.drawImage(background_on, ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight(), ClipRect.getX(), ClipRect.getY(), ClipRect.getWidth(), ClipRect.getHeight());
#endif
}

void SmartPedalAudioProcessorEditor::resized()
Expand All @@ -120,16 +132,15 @@ void SmartPedalAudioProcessorEditor::resized()
// subcomponents in your editor..

//Overall Widgets
loadButton.setBounds(184, 68, 120, 20);
modelSelect.setBounds(50, 36, 400, 25);
modelLabel.setBounds(193, 12, 90, 25);
versionLabel.setBounds(465, 635, 60, 10);
loadButton.setBounds(186, 56, 120, 20);
modelSelect.setBounds(52, 26, 400, 25);
modelLabel.setBounds(197, 2, 90, 25);
versionLabel.setBounds(462, 632, 60, 10);

// Overdrive Widgets
odDriveKnob.setBounds(112, 115, 125, 145);
odLevelKnob.setBounds(283, 115, 125, 145);
odFootSw.setBounds(220, 459, 75, 105);
odLED.setBounds(239, 398, 75, 105);
odDriveKnob.setBounds(103, 97, 176, 176);
odLevelKnob.setBounds(268, 97, 176, 176);
odFootSw.setBounds(185, 416, 175, 160);
}


Expand Down Expand Up @@ -229,33 +240,25 @@ void SmartPedalAudioProcessorEditor::modelSelectChanged()
processor.loadConfig(processor.jsonFiles[selectedFileIndex]);
processor.current_model_index = selectedFileIndex;
}
repaint();
}


void SmartPedalAudioProcessorEditor::resetImages()
{
repaint();
if (processor.fw_state == 0) {
odFootSw.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::footswitch_up_png, BinaryData::footswitch_up_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
ImageCache::getFromMemory(BinaryData::footswitch_up_png, BinaryData::footswitch_up_pngSize), 1.0, Colours::transparentWhite,
0.0);
odLED.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::led_red_off_png, BinaryData::led_red_off_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
ImageCache::getFromMemory(BinaryData::led_red_off_png, BinaryData::led_red_off_pngSize), 1.0, Colours::transparentWhite,
0.0);
}
else {
odFootSw.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::footswitch_down_png, BinaryData::footswitch_down_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
ImageCache::getFromMemory(BinaryData::footswitch_down_png, BinaryData::footswitch_down_pngSize), 1.0, Colours::transparentWhite,
0.0);
odLED.setImages(true, true, true,
ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
Image(), 1.0, Colours::transparentWhite,
ImageCache::getFromMemory(BinaryData::led_red_on_png, BinaryData::led_red_on_pngSize), 1.0, Colours::transparentWhite,
0.0);
}
}
11 changes: 6 additions & 5 deletions src/PluginEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ class SmartPedalAudioProcessorEditor : public AudioProcessorEditor,
virtual void buttonClicked(Button* button) override;
void loadButtonClicked();

Image background = ImageCache::getFromMemory(BinaryData::smart_pedal_jpg, BinaryData::smart_pedal_jpgSize);

//Image background = ImageCache::getFromMemory(BinaryData::smart_pedal_jpg, BinaryData::smart_pedal_jpgSize);
// LookandFeels and Graphics
Image background_on = ImageCache::getFromMemory(BinaryData::background_on_jpg, BinaryData::background_on_jpgSize);
Image background_on_blue = ImageCache::getFromMemory(BinaryData::background_on_blue_jpg, BinaryData::background_on_blue_jpgSize);
Image background_off = ImageCache::getFromMemory(BinaryData::background_off_jpg, BinaryData::background_off_jpgSize);

// Global Widgets
Label modelLabel;
Expand All @@ -56,12 +59,10 @@ class SmartPedalAudioProcessorEditor : public AudioProcessorEditor,
Slider odDriveKnob;
Slider odLevelKnob;
ImageButton odFootSw;
ImageButton odLED;
//ImageButton odLED;


// LookandFeels
myLookAndFeel ampSilverKnobLAF;
myLookAndFeel blackSilverKnobLAF;
myLookAndFeel blackHexKnobLAF;

virtual void sliderValueChanged(Slider* slider) override;
Expand Down
42 changes: 33 additions & 9 deletions src/PluginProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,34 @@ void SmartPedalAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuf
// Overdrive Pedal ==================================================================
if (fw_state == 1) {

// Master Volume
// Apply ramped changes for gain smoothing
if (driveValue == previousDriveValue)
{
buffer.applyGain(driveValue*10.0);
}
else {
buffer.applyGainRamp(0, (int) buffer.getNumSamples(), previousDriveValue * 10.0, driveValue * 10.0);
previousDriveValue = driveValue;
if (conditioned == false) {
// Apply ramped changes for gain smoothing
if (driveValue == previousDriveValue)
{
buffer.applyGain(driveValue*20.0);
}
else {
buffer.applyGainRamp(0, (int) buffer.getNumSamples(), previousDriveValue * 20.0, driveValue * 20.0);
previousDriveValue = driveValue;
}
} else {
buffer.applyGain(10.0); // Apply default boost to help sound
float* chanBuffer1 = buffer.getWritePointer(1);

// Check for parameter changes for smoothing calculations
if (driveValue != previousDriveValue) {
steppedValue1 = (driveValue - previousDriveValue) / numSamples;
for (int i = 0; i < buffer.getNumSamples(); i++)
{
chanBuffer1[i] = previousDriveValue + (i + 1) * steppedValue1;
}
previousDriveValue = driveValue;
} else {
for (int i = 0; i < buffer.getNumSamples(); i++)
{
chanBuffer1[i] = driveValue;
}
}
}

waveNet.process(buffer.getArrayOfReadPointers(), buffer.getArrayOfWritePointers(),
Expand Down Expand Up @@ -244,6 +263,11 @@ void SmartPedalAudioProcessor::loadConfig(File configFile)
WaveNetLoader loader(configFile);
int numChannels = loader.numChannels;
int inputChannels = loader.inputChannels;
if (inputChannels > 1) {
conditioned = true;
} else {
conditioned = false;
}
int outputChannels = loader.outputChannels;
int filterWidth = loader.filterWidth;
std::vector<int> dilations = loader.dilations;
Expand Down
5 changes: 4 additions & 1 deletion src/PluginProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ class SmartPedalAudioProcessor : public AudioProcessor
File saved_model;

AudioProcessorValueTreeState treeState;


bool conditioned = false;


private:

Expand All @@ -87,6 +89,7 @@ class SmartPedalAudioProcessor : public AudioProcessor

float previousDriveValue = 0.5;
float previousMasterValue = 0.5;
float steppedValue1 = 0.0;

WaveNet waveNet;

Expand Down

0 comments on commit 1182756

Please sign in to comment.