mirror of
https://codeberg.org/armin/wavetable.git
synced 2026-09-01 05:50:46 +02:00
Allow selecting wavetable
This commit is contained in:
parent
3dbcbf73e5
commit
a69ef9e54c
5 changed files with 126 additions and 11 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3e758affdb87d98b1699982262082c7b4c755392
|
Subproject commit 96f0293857109e8565519b7d0016cead2d03985c
|
||||||
|
|
@ -19,7 +19,7 @@ private:
|
||||||
|
|
||||||
OscillatorBox oscillators[Cfg::numOSCs] { { "oscillator 1", proc, 0 }, { "oscillator 2", proc, 1 } };
|
OscillatorBox oscillators[Cfg::numOSCs] { { "oscillator 1", proc, 0 }, { "oscillator 2", proc, 1 } };
|
||||||
|
|
||||||
FilterBox filter { "filter 1", proc };
|
FilterBox filter { "filter", proc };
|
||||||
|
|
||||||
FilterADSRArea fltADSR { proc };
|
FilterADSRArea fltADSR { proc };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@
|
||||||
#include "Cfg.h"
|
#include "Cfg.h"
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
class OscillatorBox : public gin::ParamBox
|
class OscillatorBox : public gin::ParamBox,
|
||||||
|
public Value::Listener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OscillatorBox (const juce::String& name, WavetableAudioProcessor& proc_, int idx_)
|
OscillatorBox (const juce::String& name, WavetableAudioProcessor& proc_, int idx_)
|
||||||
|
|
@ -15,6 +16,12 @@ public:
|
||||||
|
|
||||||
auto& osc = proc.oscParams[idx];
|
auto& osc = proc.oscParams[idx];
|
||||||
|
|
||||||
|
setTitle (idx == 0 ? proc.osc1Table.toString() : proc.osc2Table.toString());
|
||||||
|
if (idx == 0)
|
||||||
|
proc.osc1Table.addListener (this);
|
||||||
|
else
|
||||||
|
proc.osc2Table.addListener (this);
|
||||||
|
|
||||||
addEnable (osc.enable);
|
addEnable (osc.enable);
|
||||||
|
|
||||||
addControl (new gin::Knob (osc.pos), 0, 0);
|
addControl (new gin::Knob (osc.pos), 0, 0);
|
||||||
|
|
@ -40,6 +47,35 @@ public:
|
||||||
{
|
{
|
||||||
wt->setParams (proc.getLiveWTParams (idx));
|
wt->setParams (proc.getLiveWTParams (idx));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto& h = getHeader();
|
||||||
|
h.addAndMakeVisible (nextButton);
|
||||||
|
h.addAndMakeVisible (prevButton);
|
||||||
|
nextButton.onClick = [this] { proc.incWavetable (idx, +1); };
|
||||||
|
prevButton.onClick = [this] { proc.incWavetable (idx, -1); };
|
||||||
|
}
|
||||||
|
|
||||||
|
~OscillatorBox() override
|
||||||
|
{
|
||||||
|
if (idx == 0)
|
||||||
|
proc.osc1Table.removeListener (this);
|
||||||
|
else
|
||||||
|
proc.osc2Table.removeListener (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resized() override
|
||||||
|
{
|
||||||
|
gin::ParamBox::resized();
|
||||||
|
|
||||||
|
auto& h = getHeader();
|
||||||
|
nextButton.setBounds (getWidth() / 2 + 100, h.getHeight() / 2 - 4, 8, 8);
|
||||||
|
prevButton.setBounds (getWidth() / 2 - 108, h.getHeight() / 2 - 4, 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void valueChanged (juce::Value&) override
|
||||||
|
{
|
||||||
|
setTitle (idx == 0 ? proc.osc1Table.toString() : proc.osc2Table.toString());
|
||||||
|
wt->setWavetables (idx == 0 ? &proc.osc1Tables : &proc.osc2Tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
void paramChanged() override
|
void paramChanged() override
|
||||||
|
|
@ -59,6 +95,9 @@ public:
|
||||||
gin::WavetableComponent* wt;
|
gin::WavetableComponent* wt;
|
||||||
|
|
||||||
gin::CoalescedTimer timer;
|
gin::CoalescedTimer timer;
|
||||||
|
|
||||||
|
gin::SVGButton nextButton {"next", "M17.525 36.465l-7.071 7.07c-4.686 4.686-4.686 12.284 0 16.971L205.947 256 10.454 451.494c-4.686 4.686-4.686 12.284 0 16.971l7.071 7.07c4.686 4.686 12.284 4.686 16.97 0l211.051-211.05c4.686-4.686 4.686-12.284 0-16.971L34.495 36.465c-4.686-4.687-12.284-4.687-16.97 0z"};
|
||||||
|
gin::SVGButton prevButton {"prev", "M238.475 475.535l7.071-7.07c4.686-4.686 4.686-12.284 0-16.971L50.053 256 245.546 60.506c4.686-4.686 4.686-12.284 0-16.971l-7.071-7.07c-4.686-4.686-12.284-4.686-16.97 0L10.454 247.515c-4.686 4.686-4.686 12.284 0 16.971l211.051 211.05c4.686 4.686 12.284 4.686 16.97-.001z"};
|
||||||
};
|
};
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
@ -224,6 +263,8 @@ public:
|
||||||
{
|
{
|
||||||
setName ("gate");
|
setName ("gate");
|
||||||
|
|
||||||
|
addEnable (proc.gateParams.enable);
|
||||||
|
|
||||||
addControl (new gin::Select (proc.gateParams.beat), 0, 0);
|
addControl (new gin::Select (proc.gateParams.beat), 0, 0);
|
||||||
addControl (new gin::Knob (proc.gateParams.length), 1, 0);
|
addControl (new gin::Knob (proc.gateParams.length), 1, 0);
|
||||||
addControl (new gin::Knob (proc.gateParams.attack), 0, 1);
|
addControl (new gin::Knob (proc.gateParams.attack), 0, 1);
|
||||||
|
|
@ -274,6 +315,8 @@ public:
|
||||||
{
|
{
|
||||||
setName ("chorus");
|
setName ("chorus");
|
||||||
|
|
||||||
|
addEnable (proc.chorusParams.enable);
|
||||||
|
|
||||||
addControl (new gin::Knob (proc.chorusParams.delay), 0, 0);
|
addControl (new gin::Knob (proc.chorusParams.delay), 0, 0);
|
||||||
addControl (new gin::Knob (proc.chorusParams.rate), 1, 0);
|
addControl (new gin::Knob (proc.chorusParams.rate), 1, 0);
|
||||||
addControl (new gin::Knob (proc.chorusParams.mix), 2, 0);
|
addControl (new gin::Knob (proc.chorusParams.mix), 2, 0);
|
||||||
|
|
@ -296,6 +339,8 @@ public:
|
||||||
{
|
{
|
||||||
setName ("distort");
|
setName ("distort");
|
||||||
|
|
||||||
|
addEnable (proc.distortionParams.enable);
|
||||||
|
|
||||||
addControl (new gin::Knob (proc.distortionParams.amount), 0, 0);
|
addControl (new gin::Knob (proc.distortionParams.amount), 0, 0);
|
||||||
addControl (new gin::Knob (proc.distortionParams.highpass), 1, 0);
|
addControl (new gin::Knob (proc.distortionParams.highpass), 1, 0);
|
||||||
addControl (new gin::Knob (proc.distortionParams.output), 0, 1);
|
addControl (new gin::Knob (proc.distortionParams.output), 0, 1);
|
||||||
|
|
@ -316,6 +361,8 @@ public:
|
||||||
{
|
{
|
||||||
setName ("delay");
|
setName ("delay");
|
||||||
|
|
||||||
|
addEnable (proc.delayParams.enable);
|
||||||
|
|
||||||
addControl (t = new gin::Knob (proc.delayParams.time), 0, 0);
|
addControl (t = new gin::Knob (proc.delayParams.time), 0, 0);
|
||||||
addControl (b = new gin::Select (proc.delayParams.beat), 0, 0);
|
addControl (b = new gin::Select (proc.delayParams.beat), 0, 0);
|
||||||
addControl (new gin::Knob (proc.delayParams.fb), 1, 0);
|
addControl (new gin::Knob (proc.delayParams.fb), 1, 0);
|
||||||
|
|
@ -350,6 +397,8 @@ public:
|
||||||
{
|
{
|
||||||
setName ("reverb");
|
setName ("reverb");
|
||||||
|
|
||||||
|
addEnable (proc.reverbParams.enable);
|
||||||
|
|
||||||
addControl (new gin::Knob (proc.reverbParams.size), 0, 0);
|
addControl (new gin::Knob (proc.reverbParams.size), 0, 0);
|
||||||
addControl (new gin::Knob (proc.reverbParams.decay), 1, 0);
|
addControl (new gin::Knob (proc.reverbParams.decay), 1, 0);
|
||||||
addControl (new gin::Knob (proc.reverbParams.lowpass), 2, 0);
|
addControl (new gin::Knob (proc.reverbParams.lowpass), 2, 0);
|
||||||
|
|
@ -372,7 +421,7 @@ public:
|
||||||
{
|
{
|
||||||
setName ("scope");
|
setName ("scope");
|
||||||
|
|
||||||
scope = new gin::TriggeredScope (proc.fifo);
|
scope = new gin::TriggeredScope (proc.scopeFifo);
|
||||||
scope->setNumChannels (2);
|
scope->setNumChannels (2);
|
||||||
scope->setTriggerMode (gin::TriggeredScope::TriggerMode::Up);
|
scope->setTriggerMode (gin::TriggeredScope::TriggerMode::Up);
|
||||||
scope->setColour (gin::TriggeredScope::lineColourId, juce::Colours::transparentBlack);
|
scope->setColour (gin::TriggeredScope::lineColourId, juce::Colours::transparentBlack);
|
||||||
|
|
|
||||||
|
|
@ -328,9 +328,9 @@ void WavetableAudioProcessor::ReverbParams::setup (WavetableAudioProcessor& p)
|
||||||
|
|
||||||
size = p.addExtParam ("rvbSize", "Size", "", "", {0.0f, 1.0f, 0.0f, 2.0f}, 0.0f, 0.0f);
|
size = p.addExtParam ("rvbSize", "Size", "", "", {0.0f, 1.0f, 0.0f, 2.0f}, 0.0f, 0.0f);
|
||||||
decay = p.addExtParam ("rvbDecay", "Decay", "", "", {0.0f, 1.0f, 0.0f, 1.0f}, 0.0f, 0.0f);
|
decay = p.addExtParam ("rvbDecay", "Decay", "", "", {0.0f, 1.0f, 0.0f, 1.0f}, 0.0f, 0.0f);
|
||||||
lowpass = p.addExtParam ("rvbLowpass", "Lowpass", "", "", {0.0f, 1.0f, 16.0f, 20000.0f}, 0.0f, 0.0f);
|
lowpass = p.addExtParam ("rvbLowpass", "Lowpass", "", "", {16.0f, 20000.0f, 0.0f, 0.3f}, 10000.0f, 0.0f);
|
||||||
damping = p.addExtParam ("rvbDamping", "Damping", "", "", {0.0f, 1.0f, 16.0f, 20000.0f}, 0.0f, 0.0f);
|
damping = p.addExtParam ("rvbDamping", "Damping", "", "", {16.0f, 20000.0f, 0.0f, 0.3f}, 10000.0f, 0.0f);
|
||||||
predelay = p.addExtParam ("rvbPredelay", "Predelay", "", "", {0.0f, 1.0f, 0.0f, 0.1f}, 0.0f, 0.0f);
|
predelay = p.addExtParam ("rvbPredelay", "Predelay", "", "", {0.0f, 0.1f, 0.0f, 1.0f}, 0.0f, 0.0f);
|
||||||
mix = p.addExtParam ("rvbMix", "Mix", "", "", {0.0f, 1.0f, 0.0f, 1.0f}, 0.0f, 0.0f);
|
mix = p.addExtParam ("rvbMix", "Mix", "", "", {0.0f, 1.0f, 0.0f, 1.0f}, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -354,8 +354,10 @@ WavetableAudioProcessor::WavetableAudioProcessor()
|
||||||
enableLegacyMode();
|
enableLegacyMode();
|
||||||
setVoiceStealingEnabled (true);
|
setVoiceStealingEnabled (true);
|
||||||
|
|
||||||
loadWaveTable (osc1Tables, juce::MemoryBlock (BinaryData::Analog_PWM_Square_01_wav, BinaryData::Analog_PWM_Square_01_wavSize));
|
osc1Table = "Analog PWM Square 01";
|
||||||
loadWaveTable (osc2Tables, juce::MemoryBlock (BinaryData::Analog_PWM_Saw_01_wav, BinaryData::Analog_PWM_Saw_01_wavSize));
|
osc2Table = "Analog PWM Saw 01";
|
||||||
|
|
||||||
|
reloadWavetables();
|
||||||
|
|
||||||
for (int i = 0; i < juce::numElementsInArray (oscParams); i++)
|
for (int i = 0; i < juce::numElementsInArray (oscParams); i++)
|
||||||
oscParams[i].setup (*this, i);
|
oscParams[i].setup (*this, i);
|
||||||
|
|
@ -394,15 +396,68 @@ WavetableAudioProcessor::~WavetableAudioProcessor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WavetableAudioProcessor::reloadWavetables()
|
||||||
|
{
|
||||||
|
auto loadMemory = [&] (const juce::String& name) -> juce::MemoryBlock
|
||||||
|
{
|
||||||
|
for (auto i = 0; i < BinaryData::namedResourceListSize; i++)
|
||||||
|
{
|
||||||
|
if ((name + ".wav").equalsIgnoreCase (BinaryData::originalFilenames[i]))
|
||||||
|
{
|
||||||
|
int sz = 0;
|
||||||
|
if (auto data = BinaryData::getNamedResource (BinaryData::namedResourceList[i], sz))
|
||||||
|
return juce::MemoryBlock (data, sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto mb = loadMemory (osc1Table.toString()); mb.getSize() > 0)
|
||||||
|
loadWaveTable (osc1Tables, mb);
|
||||||
|
|
||||||
|
if (auto mb = loadMemory (osc2Table.toString()); mb.getSize() > 0)
|
||||||
|
loadWaveTable (osc2Tables, mb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WavetableAudioProcessor::incWavetable (int osc, int delta)
|
||||||
|
{
|
||||||
|
auto& table = osc == 0 ? osc1Table : osc2Table;
|
||||||
|
|
||||||
|
juce::StringArray tables;
|
||||||
|
for (auto i = 0; i < BinaryData::namedResourceListSize; i++)
|
||||||
|
if (juce::String (BinaryData::originalFilenames[i]).endsWith (".wav"))
|
||||||
|
tables.add (juce::String (BinaryData::originalFilenames[i]).upToLastOccurrenceOf (".wav", false, false));
|
||||||
|
|
||||||
|
tables.sortNatural();
|
||||||
|
|
||||||
|
auto idx = tables.indexOf (table.toString());
|
||||||
|
|
||||||
|
idx += delta;
|
||||||
|
if (idx < 0) idx = tables.size() - 1;
|
||||||
|
if (idx >= tables.size()) idx = 0;
|
||||||
|
|
||||||
|
table = tables[idx];
|
||||||
|
|
||||||
|
reloadWavetables();
|
||||||
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void WavetableAudioProcessor::stateUpdated()
|
void WavetableAudioProcessor::stateUpdated()
|
||||||
{
|
{
|
||||||
modMatrix.stateUpdated (state);
|
modMatrix.stateUpdated (state);
|
||||||
|
|
||||||
|
osc1Table = state.getProperty ("wt1");
|
||||||
|
osc2Table = state.getProperty ("wt2");
|
||||||
|
|
||||||
|
reloadWavetables();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WavetableAudioProcessor::updateState()
|
void WavetableAudioProcessor::updateState()
|
||||||
{
|
{
|
||||||
modMatrix.updateState (state);
|
modMatrix.updateState (state);
|
||||||
|
|
||||||
|
state.setProperty ("wt1", osc1Table, nullptr);
|
||||||
|
state.setProperty ("wt2", osc2Table, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
@ -469,6 +524,8 @@ void WavetableAudioProcessor::reset()
|
||||||
l.reset();
|
l.reset();
|
||||||
|
|
||||||
modStepLFO.reset();
|
modStepLFO.reset();
|
||||||
|
|
||||||
|
reloadWavetables();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSamplesPerBlock)
|
void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSamplesPerBlock)
|
||||||
|
|
@ -489,6 +546,8 @@ void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSample
|
||||||
l.setSampleRate (newSampleRate);
|
l.setSampleRate (newSampleRate);
|
||||||
|
|
||||||
modStepLFO.setSampleRate (newSampleRate);
|
modStepLFO.setSampleRate (newSampleRate);
|
||||||
|
|
||||||
|
reloadWavetables();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WavetableAudioProcessor::releaseResources()
|
void WavetableAudioProcessor::releaseResources()
|
||||||
|
|
@ -535,7 +594,9 @@ void WavetableAudioProcessor::processBlock (juce::AudioBuffer<float>& buffer, ju
|
||||||
|
|
||||||
playHead = nullptr;
|
playHead = nullptr;
|
||||||
|
|
||||||
fifo.write (buffer);
|
if (buffer.getNumSamples() <= scopeFifo.getFreeSpace())
|
||||||
|
scopeFifo.write (buffer);
|
||||||
|
|
||||||
endBlock (buffer.getNumSamples());
|
endBlock (buffer.getNumSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ public:
|
||||||
juce::Array<float> getLiveFilterCutoff();
|
juce::Array<float> getLiveFilterCutoff();
|
||||||
gin::WTOscillator::Params getLiveWTParams (int osc);
|
gin::WTOscillator::Params getLiveWTParams (int osc);
|
||||||
|
|
||||||
|
void reloadWavetables();
|
||||||
|
void incWavetable (int osc, int delta);
|
||||||
|
|
||||||
void applyEffects (juce::AudioSampleBuffer& buffer);
|
void applyEffects (juce::AudioSampleBuffer& buffer);
|
||||||
|
|
||||||
// Voice Params
|
// Voice Params
|
||||||
|
|
@ -233,11 +236,13 @@ public:
|
||||||
gin::StereoDelay stereoDelay { 120.1 };
|
gin::StereoDelay stereoDelay { 120.1 };
|
||||||
gin::PlateReverb<float, int> reverb;
|
gin::PlateReverb<float, int> reverb;
|
||||||
gin::GainProcessor outputGain;
|
gin::GainProcessor outputGain;
|
||||||
gin::AudioFifo fifo { 2, 44100 };
|
gin::AudioFifo scopeFifo { 2, 44100 };
|
||||||
|
|
||||||
juce::OwnedArray<gin::BandLimitedLookupTable> osc1Tables;
|
juce::OwnedArray<gin::BandLimitedLookupTable> osc1Tables;
|
||||||
juce::OwnedArray<gin::BandLimitedLookupTable> osc2Tables;
|
juce::OwnedArray<gin::BandLimitedLookupTable> osc2Tables;
|
||||||
|
|
||||||
|
juce::Value osc1Table, osc2Table;
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
gin::ModMatrix modMatrix;
|
gin::ModMatrix modMatrix;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue