Add drag to reorder fx

This commit is contained in:
Roland Rabien 2023-10-08 14:31:14 -07:00
commit 8a793ba5b4
7 changed files with 179 additions and 55 deletions

@ -1 +1 @@
Subproject commit 33d8c95b10958b79c2a018ba4cb73e99c2e2b528
Subproject commit f79efd9b83a7a546df4ba8c437cc7d487144aa89

View file

@ -104,7 +104,9 @@
{ "id": "matrix", "x": 0, "y": 23, "r": "parW()", "b": "parH()" }
]
},
{ "id": "gate", "x": "0", "y": "prevB()+1", "w": 290, "h": 137, "children":
{ "id": "fx", "x": 0, "y": "prevB()+1", "w": "parW() - 169", "h": 137, "children":
[
{ "id": "gate", "x": "0", "y": 0, "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 },
@ -144,7 +146,10 @@
{ "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": 168, "h": 137, "children":
[
{ "id": "Mono", "x": 0, "y": 23, "w": 42, "h": 57 },
@ -154,6 +159,7 @@
{ "id": "PB Range", "x": 0, "y": "prevB()", "w": 42, "h": 57 },
{ "id": "Voices", "x": "prevR()", "y": "prevY()", "w": 42, "h": 57 },
{ "id": "Level", "x": "prevR() + 42", "y": "prevY()", "w": 42, "h": 57 }
] }
]
}
]
}

View file

@ -15,13 +15,78 @@ Editor::Editor (WavetableAudioProcessor& proc_)
addAndMakeVisible (mod);
addAndMakeVisible (mtx);
addAndMakeVisible (global);
addAndMakeVisible (gate);
addAndMakeVisible (chorus);
addAndMakeVisible (distort);
addAndMakeVisible (delay);
addAndMakeVisible (reverb);
fx.addAndMakeVisible (gate);
fx.addAndMakeVisible (chorus);
fx.addAndMakeVisible (distort);
fx.addAndMakeVisible (delay);
fx.addAndMakeVisible (reverb);
fx.onDragStart = [] (const juce::MouseEvent& e)
{
if (dynamic_cast<gin::ParamHeader*> (e.originalComponent))
return true;
return false;
};
fx.onOrderChanged = [this]
{
proc.fxParams.fx1->setUserValue (fx.getChildComponent(0)->getProperties()["fxId"]);
proc.fxParams.fx2->setUserValue (fx.getChildComponent(1)->getProperties()["fxId"]);
proc.fxParams.fx3->setUserValue (fx.getChildComponent(2)->getProperties()["fxId"]);
proc.fxParams.fx4->setUserValue (fx.getChildComponent(3)->getProperties()["fxId"]);
proc.fxParams.fx5->setUserValue (fx.getChildComponent(4)->getProperties()["fxId"]);
handleAsyncUpdate();
};
proc.fxParams.fx1->addListener (this);
proc.fxParams.fx2->addListener (this);
proc.fxParams.fx3->addListener (this);
proc.fxParams.fx4->addListener (this);
proc.fxParams.fx5->addListener (this);
addAndMakeVisible (fx);
setupCallbacks();
handleAsyncUpdate();
}
Editor::~Editor()
{
proc.fxParams.fx1->removeListener (this);
proc.fxParams.fx2->removeListener (this);
proc.fxParams.fx3->removeListener (this);
proc.fxParams.fx4->removeListener (this);
proc.fxParams.fx5->removeListener (this);
}
void Editor::handleAsyncUpdate()
{
if (fx.isDragInProgress())
return;
fx.removeAllChildren();
auto getComp = [this] (int fxId) -> juce::Component*
{
if (fxId == fxGate) return &gate;
if (fxId == fxChorus) return &chorus;
if (fxId == fxDistort) return &distort;
if (fxId == fxDelay) return &delay;
if (fxId == fxReverb) return &reverb;
jassertfalse;
return nullptr;
};
fx.addAndMakeVisible (getComp (proc.fxParams.fx1->getUserValueInt()));
fx.addAndMakeVisible (getComp (proc.fxParams.fx2->getUserValueInt()));
fx.addAndMakeVisible (getComp (proc.fxParams.fx3->getUserValueInt()));
fx.addAndMakeVisible (getComp (proc.fxParams.fx4->getUserValueInt()));
fx.addAndMakeVisible (getComp (proc.fxParams.fx5->getUserValueInt()));
if (fx.getWidth() > 0)
fx.resized();
}
void Editor::setupCallbacks()

View file

@ -5,15 +5,21 @@
#include "Panels.h"
//==============================================================================
class Editor : public juce::Component
class Editor : public juce::Component,
private gin::Parameter::ParameterListener,
private juce::AsyncUpdater
{
public:
Editor (WavetableAudioProcessor& proc_);
~Editor() override;
void setupCallbacks();
void resized() override;
private:
void valueUpdated (gin::Parameter*) override { triggerAsyncUpdate(); }
void handleAsyncUpdate() override;
WavetableAudioProcessor& proc;
OscillatorBox oscillators[Cfg::numOSCs] { { "oscillator 1", proc, 0 }, { "oscillator 2", proc, 1 } };
@ -36,5 +42,7 @@ private:
DelayBox delay { proc };
ReverbBox reverb { proc };
gin::ComponentGrid fx { "fx" };
gin::Layout layout { *this };
};

View file

@ -635,6 +635,7 @@ public:
: gin::ParamBox ("Gate"), proc (proc_)
{
setName ("gate");
getProperties().set ("fxId", fxGate);
addEnable (proc.gateParams.enable);
@ -659,6 +660,7 @@ public:
: gin::ParamBox ("Chorus"), proc (proc_)
{
setName ("chorus");
getProperties().set ("fxId", fxChorus);
addEnable (proc.chorusParams.enable);
@ -681,6 +683,7 @@ public:
: gin::ParamBox ("Distort"), proc (proc_)
{
setName ("distort");
getProperties().set ("fxId", fxDistort);
addEnable (proc.distortionParams.enable);
@ -698,6 +701,7 @@ public:
: gin::ParamBox ("Delay"), proc (proc_)
{
setName ("delay");
getProperties().set ("fxId", fxDelay);
addEnable (proc.delayParams.enable);
@ -735,6 +739,7 @@ public:
: gin::ParamBox ("Reverb"), proc (proc_)
{
setName ("reverb");
getProperties().set ("fxId", fxReverb);
addEnable (proc.reverbParams.enable);

View file

@ -362,6 +362,16 @@ void WavetableAudioProcessor::ReverbParams::setup (WavetableAudioProcessor& p)
mix = p.addExtParam ("rvbMix", "Mix", "", "", {0.0f, 1.0f, 0.0f, 1.0f}, 0.0f, 0.0f);
}
//==============================================================================
void WavetableAudioProcessor::FXParams::setup (WavetableAudioProcessor& p)
{
fx1 = p.addIntParam ("fxOrder1", "FX1", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxGate, 0.0f);
fx2 = p.addIntParam ("fxOrder2", "FX2", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxChorus, 0.0f);
fx3 = p.addIntParam ("fxOrder3", "FX3", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDistort, 0.0f);
fx4 = p.addIntParam ("fxOrder4", "FX4", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxDelay, 0.0f);
fx5 = p.addIntParam ("fxOrder5", "FX5", "", "", { 0.0, 4.0, 1.0, 1.0 }, fxReverb, 0.0f);
}
#if 0
void convertWavetables()
{
@ -498,6 +508,7 @@ WavetableAudioProcessor::WavetableAudioProcessor()
distortionParams.setup (*this);
delayParams.setup (*this);
reverbParams.setup (*this);
fxParams.setup (*this);
for (int i = 0; i < 50; i++)
{
@ -861,25 +872,25 @@ gin::WTOscillator::Params WavetableAudioProcessor::getLiveWTParams (int osc)
return p;
}
void WavetableAudioProcessor::applyEffects (juce::AudioSampleBuffer& buffer)
void WavetableAudioProcessor::applyEffect (juce::AudioSampleBuffer& buffer, int fxId)
{
// Apply gate
if (gateParams.enable->isOn())
if (fxId == fxGate && gateParams.enable->isOn())
gate.process (buffer, noteOnIndex, noteOffIndex);
// Apply Chorus
if (chorusParams.enable->isOn())
if (fxId == fxChorus && chorusParams.enable->isOn())
chorus.process (buffer);
// Apply Distortion
if (distortionParams.enable->isOn())
if (fxId == fxDistort && distortionParams.enable->isOn())
{
auto clip = 1.0f / (2.0f * distortionVal);
gin::Distortion::processBlock (buffer, distortionVal, -clip, clip);
}
// Apply Delay
if (delayParams.enable->isOn())
if (fxId == fxDelay && delayParams.enable->isOn())
{
if (delayParams.sync->isOn())
stereoDelay.process (buffer);
@ -888,8 +899,17 @@ void WavetableAudioProcessor::applyEffects (juce::AudioSampleBuffer& buffer)
}
// Apply Reverb
if (reverbParams.enable->isOn())
if (fxId == fxReverb && reverbParams.enable->isOn())
reverb.process (buffer.getWritePointer (0), buffer.getWritePointer (1), buffer.getNumSamples ());
}
void WavetableAudioProcessor::applyEffects (juce::AudioSampleBuffer& buffer)
{
applyEffect (buffer, fxParams.fx1->getUserValueInt());
applyEffect (buffer, fxParams.fx2->getUserValueInt());
applyEffect (buffer, fxParams.fx3->getUserValueInt());
applyEffect (buffer, fxParams.fx4->getUserValueInt());
applyEffect (buffer, fxParams.fx5->getUserValueInt());
// Output gain
outputGain.process (buffer);

View file

@ -4,6 +4,12 @@
#include "WavetableVoice.h"
constexpr auto fxGate = 0;
constexpr auto fxChorus = 1;
constexpr auto fxDistort = 2;
constexpr auto fxDelay = 3;
constexpr auto fxReverb = 4;
//==============================================================================
class WavetableAudioProcessor : public gin::Processor,
public gin::Synthesiser
@ -45,6 +51,8 @@ public:
bool loadUserWavetable (int osc, const juce::File& f, int sz);
void applyEffects (juce::AudioSampleBuffer& buffer);
void applyEffect (juce::AudioSampleBuffer& buffer, int fxId);
bool loadWaveTable (juce::OwnedArray<gin::BandLimitedLookupTable>& table, double sr, const juce::MemoryBlock& wav, const juce::String& format, int size);
// Voice Params
@ -220,6 +228,17 @@ public:
JUCE_DECLARE_NON_COPYABLE (ReverbParams)
};
struct FXParams
{
FXParams() = default;
gin::Parameter::Ptr fx1, fx2, fx3, fx4, fx5;
void setup (WavetableAudioProcessor& p);
JUCE_DECLARE_NON_COPYABLE (FXParams)
};
//==============================================================================
gin::ModSrcId modSrcPressure, modSrcTimbre, modSrcPitchbend, modScrPitchBend,
modSrcFilter, modSrcNote, modSrcVelocity, modSrcStep, modSrcMonoStep;
@ -235,6 +254,7 @@ public:
EnvParams envParams[Cfg::numENVs];
LFOParams lfoParams[Cfg::numLFOs];
StepLFOParams stepLfoParams;
FXParams fxParams;
ADSRParams adsrParams;