Finish UI

This commit is contained in:
Roland Rabien 2023-08-31 11:17:49 -07:00
commit 7311a258c9
13 changed files with 164 additions and 66 deletions

View file

@ -4,7 +4,7 @@ cmake_minimum_required (VERSION 3.24.0 FATAL_ERROR)
# Set for each plugin
#
set (PLUGIN_NAME Wavetable)
set (PLUGIN_VERSION 1.0.0)
set (PLUGIN_VERSION 0.0.1)
set (BUNDLE_ID com.socalabs.Wavetable)
set (AU_ID WavetableAU)
set (LV2_URI "https://socalabs.com/wavetable/")
@ -96,6 +96,7 @@ set_property (DIRECTORY APPEND PROPERTY LABELS Assets)
juce_add_binary_data (${PLUGIN_NAME}_Assets SOURCES
"./plugin/Resources/layout.json"
"./plugin/Resources/Wavetables/Analog/Analog Classic.wav"
"./plugin/Resources/Wavetables/Analog/Analog PWM Square 03.wav"
"./plugin/Resources/Wavetables/Analog/Analog PWM Sub 06.wav"
"./plugin/Resources/Wavetables/Analog/Analog PWM Sub 07.wav"

@ -1 +1 @@
Subproject commit 61a4618d11e8049365000a0027e57edd24de86cf
Subproject commit 3ed8ab15c16bbee9ddf6f96612fe1999baa395d6

Binary file not shown.

View file

@ -2,27 +2,128 @@
"children":
[
{ "id": "osc[1..2]", "x": "0,prevR()+1", "y": 0, "w": "parW()/2", "h": 163 },
{ "id": "flt", "x": "0", "y": "prevB()+1", "w": 400, "h": 163, "children":
{ "id": "noise", "x": "0", "y": "prevB()+1", "w": 120, "h": 163, "children":
[
{ "id": "Level", "x": 0, "y": "23 + 35", "w": 56, "h": 70 },
{ "id": "Pan", "x": "prevR()", "y": "prevY()", "w": 56, "h": 70 }
]
},
{ "id": "sub", "x": "prevR()+1", "y": "prevY()", "w": 112, "h": 163, "children":
[
{ "id": "Wave", "x": 0, "y": 23, "w": 56, "h": 70 },
{ "id": "Tune", "x": "prevR()", "y": 23, "w": 56, "h": 70 },
{ "id": "Level", "x": 0, "y": "prevB()", "w": 56, "h": 70 },
{ "id": "Pan", "x": "prevR()", "y": "prevY()", "w": 56, "h": 70 }
]
},
{ "id": "flt", "x": "prevR()+1", "y": "prevY()", "w": 336, "h": 163, "children":
[
{ "id": "FLT WT1", "x": 24, "y": 6, "w": 12, "h": 12 },
{ "id": "FLT WT2", "x": "prevR()+6", "y": 6, "w": 12, "h": 12 },
{ "id": "FLT sub", "x": "prevR()+6", "y": 6, "w": 12, "h": 12 },
{ "id": "FLT noise", "x": "prevR()+6", "y": 6, "w": 12, "h": 12 }
{ "id": "FLT noise", "x": "prevR()+6", "y": 6, "w": 12, "h": 12 },
{ "id": "Type", "x": 0, "y": 23, "w": 56, "h": 70 },
{ "id": "Freq", "x": "prevR()", "y": 23, "w": 56, "h": 70 },
{ "id": "Res", "x": "prevR()", "y": 23, "w": 56, "h": 70 },
{ "id": "Key", "x": 0, "y": "prevB()", "w": 56, "h": 70 },
{ "id": "Vel", "x": "prevR()", "y": "prevY()", "w": 56, "h": 70 },
{ "id": "Amnt", "x": "prevR()", "y": "prevY()", "w": 56, "h": 70 },
{ "id": "A", "x": "prevR()", "y": "prevY() + 13", "w": 42, "h": 57 },
{ "id": "D", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "S", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "R", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "adsr", "x": "getX('A')", "y": "getY('Res')", "r": "getR('R')", "b": "getY('A')" }
]
},
{ "id": "adsr", "x": "prevR()+1", "y": "prevY()", "w": 240, "h": 163 },
{ "id": "noise", "x": "prevR()+1", "y": "prevY()", "w": 120, "h": 163 },
{ "id": "sub", "x": "prevR()+1", "y": "prevY()", "w": 120, "h": 163 },
{ "id": "lfo[1..3]", "x": 0, "y": "prevB()+1,prevY()", "w": 340, "h": 163 },
{ "id": "env[1..3]", "x": "getR('lfo1')+1", "y": "prevY()", "w": 240, "h": 163 },
{ "id": "step", "x": "prevR()+1", "y": "prevY()", "w": 240, "h": 163 },
{ "id": "mod", "x": "prevR()+1", "y": "prevY()", "w": 240, "h": 163 },
{ "id": "gate", "x": "0", "y": "prevB()+1", "w": 240, "h": 163 },
{ "id": "chorus", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "distort", "x": "prevR()+1", "y": "prevY()", "w": 100, "h": 163 },
{ "id": "delay", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "reverb", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "global", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "scope", "x": 0, "y": "prevB()+1", "w": "parW()-2", "b": "parH()-1" }
{ "id": "adsr", "x": "prevR()+1", "y": "prevY()", "w": "210 + 118", "h": 163, "children":
[
{ "id": "A", "x": "118/2", "y": 106, "w": 42, "h": 57 },
{ "id": "D", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "S", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "R", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Vel", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "adsr", "x": 0, "y": 23, "r": "parW()", "b": "getY('A')" }
] },
{ "id": "lfo[1..3]", "x": 0, "y": "prevB()+1,prevY()", "w": 280, "h": 163, "children":
[
{ "id": "Sync", "x": 0, "y": 23, "w": 56, "h": 70 },
{ "id": "Beat", "x": "prevR()", "y": 23, "w": 56, "h": 70 },
{ "id": "Rate", "x": "prevX()", "y": 23, "w": 56, "h": 70 },
{ "id": "Wave", "x": 0, "y": "prevB()", "w": 56, "h": 70 },
{ "id": "Depth", "x": "prevR()", "y": "prevY()", "w": 56, "h": 70 },
{ "id": "Offset", "x": "prevR()", "y": "prevY() + 13", "w": 42, "h": 57 },
{ "id": "Phase", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Delay", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Fade", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "lfo", "x": "getX('Offset')", "y": "getY('Rate')", "r": "getR('Fade')", "b": "getY('Fade')" }
] },
{ "id": "env[1..3]", "x": "getR('lfo1')+1", "y": "prevY()", "w": "168 + 50", "h": 163, "children":
[
{ "id": "A", "x": 25, "y": 106, "w": 42, "h": 57 },
{ "id": "D", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "S", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "R", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "adsr", "x": 0, "y": 23, "r": "parW()", "b": "getY('A')" }
] },
{ "id": "step", "x": "prevR()+1", "y": "prevY()", "w": 218, "h": 163, "children":
[
{ "id": "step", "x": 0, "y": 23, "r": "parW()", "h": 83 },
{ "id": "Beat", "x": 67, "y": 106, "w": 42, "h": 57 },
{ "id": "Length", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
] },
{ "id": "mod", "x": "prevR()+1", "y": "prevY()", "r": "parW()", "h": 163, "children":
[
{ "id": "modlist", "x": 0, "y": 23, "r": "parW()", "b": "parH()" }
] },
{ "id": "gate", "x": "0", "y": "prevB()+1", "w": 290, "h": 137, "children":
[
{ "id": "Beat", "x": 61, "y": 30, "w": 42, "h": 57 },
{ "id": "Length", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "A", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "R", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "pattern", "x": 2, "y": "prevB() + 5", "w": "parW() - 6", "b": "parH() - 15" }
]
},
{ "id": "chorus", "x": "prevR()+1", "y": "prevY()", "w": 126, "h": 137, "children":
[
{ "id": "Delay", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Speed", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Depth", "x": 21, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Width", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
]
},
{ "id": "distort", "x": "prevR()+1", "y": "prevY()", "w": 100, "h": 137, "children":
[
{ "id": "Amount", "x": 22, "y": "23 + 22", "w": 56, "h": 70 }
]
},
{ "id": "delay", "x": "prevR()+1", "y": "prevY()", "w": 126, "h": 137, "children":
[
{ "id": "Sync", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Delay1", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Delay2", "x": "prevX()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "FB", "x": 21, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "CF", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
] },
{ "id": "reverb", "x": "prevR()+1", "y": "prevY()", "w": 126, "h": 137, "children":
[
{ "id": "Size", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Decay", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Lowpass", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Damping", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Predelay", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Mix", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
] },
{ "id": "global", "x": "prevR()+1", "y": "prevY()", "w": 126, "h": 137, "children":
[
{ "id": "Legato", "x": 0, "y": 23, "w": 42, "h": 57 },
{ "id": "Glide", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Rate", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Mono", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Voices", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Level", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 }
] }
]
}

View file

@ -19,7 +19,6 @@ Editor::Editor (WavetableAudioProcessor& proc_)
addAndMakeVisible (distort);
addAndMakeVisible (delay);
addAndMakeVisible (reverb);
addAndMakeVisible (scope);
addAndMakeVisible (effects);

View file

@ -35,7 +35,6 @@ private:
DistortBox distort { proc };
DelayBox delay { proc };
ReverbBox reverb { proc };
ScopeArea scope { proc };
gin::BoxArea lfoBox;
gin::BoxArea effects;

View file

@ -33,6 +33,8 @@ public:
addControl (new gin::Select (osc.voices), 0, 1);
addControl (detune = new gin::Knob (osc.detune), 1, 1);
addControl (spread = new gin::Knob (osc.spread), 2, 1);
addControl (new gin::Knob (osc.formant, true), 3, 1);
addControl (new gin::Knob (osc.bend, true), 4, 1);
watchParam (osc.voices);
@ -95,6 +97,7 @@ public:
}
juce::PopupMenu m;
m.setLookAndFeel (&getLookAndFeel());
for (auto itr : menus)
m.addSubMenu (itr.first, itr.second);
@ -195,10 +198,11 @@ public:
adsr->setParams (preset.attack, preset.decay, preset.sustain, preset.release);
addControl (adsr, 0, 0, 4, 1);
addControl (a = new gin::Knob (preset.attack), 0, 1);
addControl (d = new gin::Knob (preset.decay), 1, 1);
addControl (s = new gin::Knob (preset.sustain), 2, 1);
addControl (r = new gin::Knob (preset.release), 3, 1);
addControl (new gin::Knob (preset.attack), 0, 1);
addControl (new gin::Knob (preset.decay), 1, 1);
addControl (new gin::Knob (preset.sustain), 2, 1);
addControl (new gin::Knob (preset.release), 3, 1);
addControl (new gin::Knob (preset.velocityTracking), 4, 1);
}
WavetableAudioProcessor& proc;
@ -385,7 +389,7 @@ public:
addModSource (new gin::ModulationSourceButton (proc.modMatrix, proc.modSrcStep, true));
addModSource (new gin::ModulationSourceButton (proc.modMatrix, proc.modSrcMonoStep, false));
addControl (new gin::Knob (prs.beat), 0, 1);
addControl (new gin::Select (prs.beat), 0, 1);
addControl (new gin::Knob (prs.length), 1, 1);
auto g = new gin::StepLFOComponent (Cfg::numStepLFOSteps);
@ -524,6 +528,9 @@ public:
addControl (new gin::Switch (proc.delayParams.sync), 0, 1);
addControl (new gin::Knob (proc.delayParams.mix), 1.5f, 1.0f);
t->setName ("Delay1");
b->setName ("Delay2");
watchParam (proc.delayParams.sync);
setSize (168, 163);
@ -564,30 +571,3 @@ public:
WavetableAudioProcessor& proc;
};
//==============================================================================
class ScopeArea : public gin::ParamArea
{
public:
ScopeArea (WavetableAudioProcessor& proc_)
: gin::ParamArea ("Scope"), proc (proc_)
{
setName ("scope");
scope = new gin::TriggeredScope (proc.scopeFifo);
scope->setNumChannels (2);
scope->setTriggerMode (gin::TriggeredScope::TriggerMode::Up);
scope->setColour (gin::TriggeredScope::lineColourId, juce::Colours::transparentBlack);
addControl (scope);
setSize (272, 163);
}
void resized() override
{
scope->setBounds (getLocalBounds().withSizeKeepingCentre (getWidth(), 140));
}
WavetableAudioProcessor& proc;
gin::TriggeredScope* scope;
};

View file

@ -5,9 +5,18 @@
WavetableAudioProcessorEditor::WavetableAudioProcessorEditor (WavetableAudioProcessor& p)
: ProcessorEditor (p), vaProc (p)
{
addAndMakeVisible (editor);
scope.setName ("scope");
scope.setNumChannels (2);
scope.setTriggerMode (gin::TriggeredScope::TriggerMode::Up);
scope.setColour (gin::TriggeredScope::traceColourId + 0, findColour(gin::PluginLookAndFeel::accentColourId, true).withAlpha (0.7f));
scope.setColour (gin::TriggeredScope::traceColourId + 1, findColour(gin::PluginLookAndFeel::accentColourId, true).withAlpha (0.7f));
scope.setColour (gin::TriggeredScope::lineColourId, juce::Colours::transparentBlack);
setSize (901, 753);
addAndMakeVisible (editor);
addAndMakeVisible (scope);
scope.setBounds (674, 5, 177, 30);
setSize (901, 671);
}
WavetableAudioProcessorEditor::~WavetableAudioProcessorEditor()

View file

@ -21,6 +21,7 @@ public:
private:
WavetableAudioProcessor& vaProc;
gin::TriggeredScope scope { vaProc.scopeFifo };
Editor editor { vaProc };
#if JUCE_DEBUG

View file

@ -110,6 +110,8 @@ void WavetableAudioProcessor::OSCParams::setup (WavetableAudioProcessor& p, int
detune = p.addExtParam (id + "detune", nm + "Detune", "Detune", "", { 0.0, 0.5, 0.0, 1.0 }, 0.0, 0.0f);
spread = p.addExtParam (id + "spread", nm + "Spread", "Spread", "%", { -100.0, 100.0, 0.0, 1.0 }, 0.0, 0.0f);
pan = p.addExtParam (id + "pan", nm + "Pan", "Pan", "", { -1.0, 1.0, 0.0, 1.0 }, 0.0, 0.0f);
formant = p.addExtParam (id + "formant", nm + "Formant", "Formant", "", { -1.0, 1.0, 0.0, 1.0 }, 0.0, 0.0f);
bend = p.addExtParam (id + "bend", nm + "Bend", "Bend", "", { -1.0, 1.0, 0.0, 1.0 }, 0.0, 0.0f);
level->conversionFunction = [] (float in) { return juce::Decibels::decibelsToGain (in); };
}
@ -354,7 +356,7 @@ static bool loadWaveTable (juce::OwnedArray<gin::BandLimitedLookupTable>& table,
}
//==============================================================================
WavetableAudioProcessor::WavetableAudioProcessor()
WavetableAudioProcessor::WavetableAudioProcessor() : gin::Processor (false)
{
lf = std::make_unique<gin::CopperLookAndFeel>();
@ -398,6 +400,7 @@ WavetableAudioProcessor::WavetableAudioProcessor()
}
setupModMatrix();
init();
}
WavetableAudioProcessor::~WavetableAudioProcessor()
@ -683,7 +686,9 @@ gin::WTOscillator::Params WavetableAudioProcessor::getLiveWTParams (int osc)
return vav->getLiveWTParams (osc);
gin::WTOscillator::Params p;
p.pw = oscParams[osc].pos->getValue();
p.position = oscParams[osc].pos->getUserValue() / 100.0f;
p.formant = oscParams[osc].formant->getUserValue();
p.bend = oscParams[osc].bend->getUserValue();
return p;
}

View file

@ -48,7 +48,7 @@ public:
{
OSCParams() = default;
gin::Parameter::Ptr enable, voices, tune, finetune, level, pos, detune, spread, pan;
gin::Parameter::Ptr enable, voices, tune, finetune, level, pos, detune, spread, pan, bend, formant;
void setup (WavetableAudioProcessor& p, int idx);

View file

@ -211,14 +211,15 @@ void WavetableVoice::updateParams (int blockSize)
currentMidiNotes[i] += float (note.totalPitchbendInSemitones);
currentMidiNotes[i] += getValue (proc.oscParams[i].tune) + getValue (proc.oscParams[i].finetune) / 100.0f;
oscParams[i].wave = gin::Wave::wavetable;
oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue());
oscParams[i].vcTrns = 0;
oscParams[i].pw = getValue (proc.oscParams[i].pos) / 100.0f;
oscParams[i].pan = getValue (proc.oscParams[i].pan);
oscParams[i].spread = getValue (proc.oscParams[i].spread) / 100.0f;
oscParams[i].detune = getValue (proc.oscParams[i].detune);
oscParams[i].gain = getValue (proc.oscParams[i].level);
oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue());
oscParams[i].vcTrns = 0;
oscParams[i].position = getValue (proc.oscParams[i].pos) / 100.0f;
oscParams[i].pan = getValue (proc.oscParams[i].pan);
oscParams[i].spread = getValue (proc.oscParams[i].spread) / 100.0f;
oscParams[i].detune = getValue (proc.oscParams[i].detune);
oscParams[i].gain = getValue (proc.oscParams[i].level);
oscParams[i].formant = getValue (proc.oscParams[i].formant);
oscParams[i].bend = getValue (proc.oscParams[i].bend);
}
if (proc.subParams.enable->isOn())
@ -412,6 +413,8 @@ float WavetableVoice::getFilterCutoffNormalized()
gin::WTOscillator::Params WavetableVoice::getLiveWTParams (int osc)
{
gin::WTOscillator::Params p;
p.pw = getValue (proc.oscParams[osc].pos) / 100.0f;
p.position = getValue (proc.oscParams[osc].pos) / 100.0f;
p.formant = getValue (proc.oscParams[osc].formant);
p.bend = getValue (proc.oscParams[osc].bend);
return p;
}

View file

@ -49,7 +49,7 @@ private:
gin::AnalogADSR adsr;
float currentMidiNotes[Cfg::numOSCs];
gin::WTVoicedStereoOscillator::Params oscParams[Cfg::numOSCs];
gin::WTVoicedStereoOscillatorParams oscParams[Cfg::numOSCs];
float subNote = 0.0f;
gin::StereoOscillator::Params subParams;