Add noise and sub osc

This commit is contained in:
Roland Rabien 2023-08-26 11:17:03 -07:00
commit 5f08863f97
9 changed files with 111 additions and 38 deletions

@ -1 +1 @@
Subproject commit 3c168aa48ef18b5fe7f4a671a91e299f9ec1e32c Subproject commit 11ccb71b61b735fa2071330df9a349679cd3e01e

View file

@ -4,6 +4,8 @@
{ "id": "osc[1..2]", "x": "0,prevR()+1", "y": 0, "w": "parW()/2", "h": 163 }, { "id": "osc[1..2]", "x": "0,prevR()+1", "y": 0, "w": "parW()/2", "h": 163 },
{ "id": "flt", "x": "0", "y": "prevB()+1", "w": 175, "h": 163 }, { "id": "flt", "x": "0", "y": "prevB()+1", "w": 175, "h": 163 },
{ "id": "fltAdsr", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 }, { "id": "fltAdsr", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "noise", "x": "prevR()+1", "y": "prevY()", "w": 60, "h": 163 },
{ "id": "sub", "x": "prevR()+1", "y": "prevY()", "w": 120, "h": 163 },
{ "id": "lfo[1..3]", "x": "0,prevR()+1", "y": "prevB()+1,prevY()", "w": 175, "h": 163 }, { "id": "lfo[1..3]", "x": "0,prevR()+1", "y": "prevB()+1,prevY()", "w": 175, "h": 163 },
{ "id": "gate", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 }, { "id": "gate", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },
{ "id": "gatePattern", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 }, { "id": "gatePattern", "x": "prevR()+1", "y": "prevY()", "w": 175, "h": 163 },

View file

@ -7,6 +7,8 @@ Editor::Editor (WavetableAudioProcessor& proc_)
for (auto& l : lfos) addAndMakeVisible (l); for (auto& l : lfos) addAndMakeVisible (l);
for (auto& l : lfoGraphs) addAndMakeVisible (l); for (auto& l : lfoGraphs) addAndMakeVisible (l);
addAndMakeVisible (sub);
addAndMakeVisible (noise);
addAndMakeVisible (filter); addAndMakeVisible (filter);
addAndMakeVisible (fltADSR); addAndMakeVisible (fltADSR);

View file

@ -18,6 +18,8 @@ private:
WavetableAudioProcessor& proc; WavetableAudioProcessor& proc;
OscillatorBox oscillators[Cfg::numOSCs] { { "oscillator 1", proc, 0 }, { "oscillator 2", proc, 1 } }; OscillatorBox oscillators[Cfg::numOSCs] { { "oscillator 1", proc, 0 }, { "oscillator 2", proc, 1 } };
NoiseBox noise { "noise", proc };
SubBox sub { "sub", proc };
FilterBox filter { "filter", proc }; FilterBox filter { "filter", proc };

View file

@ -33,7 +33,6 @@ public:
addControl (new gin::Select (osc.voices), 0, 1); addControl (new gin::Select (osc.voices), 0, 1);
addControl (detune = new gin::Knob (osc.detune), 1, 1); addControl (detune = new gin::Knob (osc.detune), 1, 1);
addControl (spread = new gin::Knob (osc.spread), 2, 1); addControl (spread = new gin::Knob (osc.spread), 2, 1);
addControl (trans = new gin::Knob (osc.voicesTrns, true), 3, 1);
watchParam (osc.voices); watchParam (osc.voices);
@ -67,7 +66,7 @@ public:
void mouseUp (const juce::MouseEvent& e) override void mouseUp (const juce::MouseEvent& e) override
{ {
auto& h = getHeader(); auto& h = getHeader();
if (e.originalComponent == &h && e.mouseWasClicked()) if (e.originalComponent == &h && e.mouseWasClicked() && e.x >= prevButton.getRight() && e.x <= nextButton.getX())
{ {
juce::StringArray tables; juce::StringArray tables;
for (auto i = 0; i < BinaryData::namedResourceListSize; i++) for (auto i = 0; i < BinaryData::namedResourceListSize; i++)
@ -123,14 +122,13 @@ public:
auto& osc = proc.oscParams[idx]; auto& osc = proc.oscParams[idx];
trans->setEnabled (osc.voices->getProcValue() > 1);
detune->setEnabled (osc.voices->getProcValue() > 1); detune->setEnabled (osc.voices->getProcValue() > 1);
spread->setEnabled (osc.voices->getProcValue() > 1); spread->setEnabled (osc.voices->getProcValue() > 1);
} }
WavetableAudioProcessor& proc; WavetableAudioProcessor& proc;
int idx = 0; int idx = 0;
gin::ParamComponent::Ptr trans, detune, spread; gin::ParamComponent::Ptr detune, spread;
gin::WavetableComponent* wt; gin::WavetableComponent* wt;
gin::CoalescedTimer timer; gin::CoalescedTimer timer;
@ -139,6 +137,48 @@ public:
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"}; 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"};
}; };
//==============================================================================
class SubBox : public gin::ParamBox
{
public:
SubBox (const juce::String& name, WavetableAudioProcessor& proc_)
: gin::ParamBox (name), proc (proc_)
{
setName ("sub");
auto& sub = proc.subParams;
addEnable (sub.enable);
addControl (new gin::Knob (sub.tune, true), 0, 0);
addControl (new gin::Knob (sub.level, true), 1, 0);
addControl (new gin::Knob (sub.pan, true), 0, 1);
addControl (new gin::Select (sub.wave), 1, 1);
}
WavetableAudioProcessor& proc;
};
//==============================================================================
class NoiseBox : public gin::ParamBox
{
public:
NoiseBox (const juce::String& name, WavetableAudioProcessor& proc_)
: gin::ParamBox (name), proc (proc_)
{
setName ("noise");
auto& noise = proc.noiseParams;
addEnable (noise.enable);
addControl (new gin::Knob (noise.level, true), 0, 0);
addControl (new gin::Knob (noise.pan, true), 0, 1);
}
WavetableAudioProcessor& proc;
};
//============================================================================== //==============================================================================
class FilterBox : public gin::ParamBox class FilterBox : public gin::ParamBox
{ {
@ -381,9 +421,6 @@ public:
addEnable (proc.distortionParams.enable); 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.output), 0, 1);
addControl (new gin::Knob (proc.distortionParams.mix), 1, 1);
setSize (112, 163); setSize (112, 163);
} }

View file

@ -2,19 +2,14 @@
#include "PluginEditor.h" #include "PluginEditor.h"
#include "WavetableVoice.h" #include "WavetableVoice.h"
static juce::String waveTextFunction (const gin::Parameter&, float v) static juce::String subTextFunction (const gin::Parameter&, float v)
{ {
switch ((gin::Wave)int (v)) switch (int (v))
{ {
case gin::Wave::silence: return "Off"; case 0: return "Sine";
case gin::Wave::sine: return "Sine"; case 1: return "Triangle";
case gin::Wave::triangle: return "Triangle"; case 2: return "Saw";
case gin::Wave::sawUp: return "Saw (Up)"; case 3: return "Pulse";
case gin::Wave::sawDown: return "Saw (Down)";
case gin::Wave::pulse: return "Pulse";
case gin::Wave::square: return "Square";
case gin::Wave::noise: return "Noise";
case gin::Wave::wavetable:
default: default:
jassertfalse; jassertfalse;
return {}; return {};
@ -108,7 +103,6 @@ void WavetableAudioProcessor::OSCParams::setup (WavetableAudioProcessor& p, int
enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, idx == 0 ? 1.0f : 0.0f, 0.0f); enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, idx == 0 ? 1.0f : 0.0f, 0.0f);
voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f); voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f);
voicesTrns = p.addExtParam (id + "unisontrns", nm + "Unison Trns", "LTrans", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f); tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
finetune = p.addExtParam (id + "finetune", nm + "Fine Tune", "Fine", "ct", { -100.0, 100.0, 0.0, 1.0 }, 0.0, 0.0f); finetune = p.addExtParam (id + "finetune", nm + "Fine Tune", "Fine", "ct", { -100.0, 100.0, 0.0, 1.0 }, 0.0, 0.0f);
level = p.addExtParam (id + "level", nm + "Level", "Level", "db", { -100.0, 0.0, 1.0, 4.0 }, 0.0, 0.0f); level = p.addExtParam (id + "level", nm + "Level", "Level", "db", { -100.0, 0.0, 1.0, 4.0 }, 0.0, 0.0f);
@ -127,7 +121,7 @@ void WavetableAudioProcessor::SubParams::setup (WavetableAudioProcessor& p)
juce::String nm = "SUB "; juce::String nm = "SUB ";
enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, 0.0f, 0.0f); enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, 0.0f, 0.0f);
wave = p.addIntParam (id + "wave", nm + "Wave", "Wave", "", { 1.0, 7.0, 1.0, 1.0 }, 1.0, 0.0f, waveTextFunction); wave = p.addIntParam (id + "wave", nm + "Wave", "Wave", "", { 0.0, 3.0, 1.0, 1.0 }, 1.0, 0.0f, subTextFunction);
tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f); tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
level = p.addExtParam (id + "level", nm + "Level", "Level", "db", { -100.0, 0.0, 1.0, 4.0 }, 0.0, 0.0f); level = p.addExtParam (id + "level", nm + "Level", "Level", "db", { -100.0, 0.0, 1.0, 4.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); pan = p.addExtParam (id + "pan", nm + "Pan", "Pan", "", { -1.0, 1.0, 0.0, 1.0 }, 0.0, 0.0f);
@ -295,9 +289,6 @@ void WavetableAudioProcessor::DistortionParams::setup (WavetableAudioProcessor&
{ {
enable = p.addIntParam ("dsEnable", "Enable", "", "", { 0.0, 1.0, 1.0, 1.0 }, 0.0f, 0.0f, enableTextFunction); enable = p.addIntParam ("dsEnable", "Enable", "", "", { 0.0, 1.0, 1.0, 1.0 }, 0.0f, 0.0f, enableTextFunction);
amount = p.addExtParam ("dsAmount", "Amount", "", "", { 0.0, 1.0, 0.0, 1.0 }, 0.2f, 0.0f, distortionAmountTextFunction); amount = p.addExtParam ("dsAmount", "Amount", "", "", { 0.0, 1.0, 0.0, 1.0 }, 0.2f, 0.0f, distortionAmountTextFunction);
highpass = p.addExtParam ("dsHighpass", "Highpass", "", "", { 0.0, 1.0, 0.0, 1.0 }, 0.0, 0.0f);
output = p.addExtParam ("dsOutput", "Output", "", "", { 0.0, 1.0, 0.0, 1.0 }, 1.0, 0.0f);
mix = p.addExtParam ("dsMix", "Mix", "", "", { 0.0, 1.0, 0.0, 1.0 }, 1.0, 0.0f);
} }
//============================================================================== //==============================================================================
@ -532,7 +523,6 @@ void WavetableAudioProcessor::reset()
gate.reset(); gate.reset();
chorus.reset(); chorus.reset();
distortion.reset();
stereoDelay.reset(); stereoDelay.reset();
reverb.reset(); reverb.reset();
@ -555,7 +545,6 @@ void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSample
gate.setSampleRate (newSampleRate); gate.setSampleRate (newSampleRate);
chorus.setSampleRate (newSampleRate); chorus.setSampleRate (newSampleRate);
distortion.setSampleRate (newSampleRate);
stereoDelay.setSampleRate (newSampleRate); stereoDelay.setSampleRate (newSampleRate);
reverb.setSampleRate (float (newSampleRate)); reverb.setSampleRate (float (newSampleRate));
@ -565,6 +554,7 @@ void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSample
modStepLFO.setSampleRate (newSampleRate); modStepLFO.setSampleRate (newSampleRate);
reloadWavetables(); reloadWavetables();
analogTables.setSampleRate (newSampleRate);
} }
void WavetableAudioProcessor::releaseResources() void WavetableAudioProcessor::releaseResources()
@ -656,7 +646,10 @@ void WavetableAudioProcessor::applyEffects (juce::AudioSampleBuffer& buffer)
// Apply Distortion // Apply Distortion
if (distortionParams.enable->isOn()) if (distortionParams.enable->isOn())
distortion.process (buffer); {
auto clip = 1.0f / (2.0f * distortionVal);
gin::Distortion::processBlock (buffer, distortionVal, -clip, clip);
}
// Apply Delay // Apply Delay
if (delayParams.enable->isOn()) if (delayParams.enable->isOn())
@ -754,12 +747,7 @@ void WavetableAudioProcessor::updateParams (int newBlockSize)
// Update Distortion // Update Distortion
if (distortionParams.enable->isOn()) if (distortionParams.enable->isOn())
{ distortionVal = modMatrix.getValue (distortionParams.amount);
distortion.setParams (modMatrix.getValue (distortionParams.amount),
modMatrix.getValue (distortionParams.highpass),
modMatrix.getValue (distortionParams.output),
modMatrix.getValue (distortionParams.mix));
}
// Update Delay // Update Delay
if (delayParams.enable->isOn()) if (delayParams.enable->isOn())

View file

@ -47,8 +47,7 @@ public:
{ {
OSCParams() = default; OSCParams() = default;
gin::Parameter::Ptr enable, voices, voicesTrns, tune, finetune, gin::Parameter::Ptr enable, voices, tune, finetune, level, pos, detune, spread, pan;
level, pos, detune, spread, pan;
void setup (WavetableAudioProcessor& p, int idx); void setup (WavetableAudioProcessor& p, int idx);
@ -175,7 +174,7 @@ public:
{ {
DistortionParams() = default; DistortionParams() = default;
gin::Parameter::Ptr enable, amount, highpass, output, mix; gin::Parameter::Ptr enable, amount;
void setup (WavetableAudioProcessor& p); void setup (WavetableAudioProcessor& p);
@ -232,15 +231,17 @@ public:
//============================================================================== //==============================================================================
gin::GateEffect gate; gin::GateEffect gate;
gin::Modulation chorus { 0.5f }; gin::Modulation chorus { 0.5f };
gin::Distortion distortion;
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 scopeFifo { 2, 44100 }; gin::AudioFifo scopeFifo { 2, 44100 };
float distortionVal = 0.0f;
juce::OwnedArray<gin::BandLimitedLookupTable> osc1Tables; juce::OwnedArray<gin::BandLimitedLookupTable> osc1Tables;
juce::OwnedArray<gin::BandLimitedLookupTable> osc2Tables; juce::OwnedArray<gin::BandLimitedLookupTable> osc2Tables;
gin::BandLimitedLookupTables analogTables;
juce::Value osc1Table, osc2Table; juce::Value osc1Table, osc2Table;
//============================================================================== //==============================================================================

View file

@ -4,6 +4,8 @@
//============================================================================== //==============================================================================
WavetableVoice::WavetableVoice (WavetableAudioProcessor& p) WavetableVoice::WavetableVoice (WavetableAudioProcessor& p)
: proc (p) : proc (p)
, noise (proc.analogTables)
, sub (proc.analogTables)
{ {
filter.setNumChannels (2); filter.setNumChannels (2);
} }
@ -155,6 +157,12 @@ void WavetableVoice::renderNextBlock (juce::AudioBuffer<float>& outputBuffer, in
if (proc.oscParams[i].enable->isOn()) if (proc.oscParams[i].enable->isOn())
oscillators[i].processAdding (currentMidiNotes[i], oscParams[i], buffer); oscillators[i].processAdding (currentMidiNotes[i], oscParams[i], buffer);
if (proc.subParams.enable->isOn())
sub.processAdding (subNote, subParams, buffer);
if (proc.noiseParams.enable->isOn())
noise.processAdding (60.0f, noiseParams, buffer);
// Apply velocity // Apply velocity
float velocity = currentlyPlayingNote.noteOnVelocity.asUnsignedFloat(); float velocity = currentlyPlayingNote.noteOnVelocity.asUnsignedFloat();
buffer.applyGain (gin::velocityToGain (velocity, ampKeyTrack)); buffer.applyGain (gin::velocityToGain (velocity, ampKeyTrack));
@ -196,7 +204,7 @@ void WavetableVoice::updateParams (int blockSize)
oscParams[i].wave = gin::Wave::wavetable; oscParams[i].wave = gin::Wave::wavetable;
oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue()); oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue());
oscParams[i].vcTrns = int (proc.oscParams[i].voicesTrns->getProcValue()); oscParams[i].vcTrns = 0;
oscParams[i].pw = getValue (proc.oscParams[i].pos) / 100.0f; oscParams[i].pw = getValue (proc.oscParams[i].pos) / 100.0f;
oscParams[i].pan = getValue (proc.oscParams[i].pan); oscParams[i].pan = getValue (proc.oscParams[i].pan);
oscParams[i].spread = getValue (proc.oscParams[i].spread) / 100.0f; oscParams[i].spread = getValue (proc.oscParams[i].spread) / 100.0f;
@ -204,6 +212,33 @@ void WavetableVoice::updateParams (int blockSize)
oscParams[i].gain = getValue (proc.oscParams[i].level); oscParams[i].gain = getValue (proc.oscParams[i].level);
} }
if (proc.subParams.enable->isOn())
{
subNote = noteSmoother.getCurrentValue() * 127.0f;
if (glideInfo.glissando) subNote = (float) juce::roundToInt (subNote);
subNote += float (note.totalPitchbendInSemitones);
subNote += getValue (proc.subParams.tune);
switch (proc.subParams.wave->getUserValueInt())
{
case 0: subParams.wave = gin::Wave::sine; break;
case 1: subParams.wave = gin::Wave::triangle; break;
case 2: subParams.wave = gin::Wave::sawUp; break;
case 3: subParams.wave = gin::Wave::pulse; break;;
}
subParams.leftGain = getValue (proc.subParams.level) * (1.0f - getValue (proc.subParams.pan));
subParams.rightGain = getValue (proc.subParams.level) * (1.0f + getValue (proc.subParams.pan));
}
if (proc.noiseParams.enable->isOn())
{
noiseParams.wave = gin::Wave::noise;
noiseParams.leftGain = getValue (proc.noiseParams.level) * (1.0f - getValue (proc.noiseParams.pan));
noiseParams.rightGain = getValue (proc.noiseParams.level) * (1.0f + getValue (proc.noiseParams.pan));
}
ampKeyTrack = getValue (proc.adsrParams.velocityTracking); ampKeyTrack = getValue (proc.adsrParams.velocityTracking);
if (! proc.filterParams.enable->isOn()) if (! proc.filterParams.enable->isOn())

View file

@ -36,6 +36,8 @@ private:
WavetableAudioProcessor& proc; WavetableAudioProcessor& proc;
gin::WTVoicedStereoOscillator oscillators[Cfg::numOSCs]; gin::WTVoicedStereoOscillator oscillators[Cfg::numOSCs];
gin::StereoOscillator noise;
gin::StereoOscillator sub;
gin::Filter filter; gin::Filter filter;
gin::ADSR filterADSR; gin::ADSR filterADSR;
@ -49,6 +51,10 @@ private:
float currentMidiNotes[Cfg::numOSCs]; float currentMidiNotes[Cfg::numOSCs];
gin::WTVoicedStereoOscillator::Params oscParams[Cfg::numOSCs]; gin::WTVoicedStereoOscillator::Params oscParams[Cfg::numOSCs];
float subNote = 0.0f;
gin::StereoOscillator::Params subParams;
gin::StereoOscillator::Params noiseParams;
gin::EasedValueSmoother<float> noteSmoother; gin::EasedValueSmoother<float> noteSmoother;
float ampKeyTrack = 1.0f; float ampKeyTrack = 1.0f;