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

View file

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

View file

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

View file

@ -33,7 +33,6 @@ 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 (trans = new gin::Knob (osc.voicesTrns, true), 3, 1);
watchParam (osc.voices);
@ -67,7 +66,7 @@ public:
void mouseUp (const juce::MouseEvent& e) override
{
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;
for (auto i = 0; i < BinaryData::namedResourceListSize; i++)
@ -123,14 +122,13 @@ public:
auto& osc = proc.oscParams[idx];
trans->setEnabled (osc.voices->getProcValue() > 1);
detune->setEnabled (osc.voices->getProcValue() > 1);
spread->setEnabled (osc.voices->getProcValue() > 1);
}
WavetableAudioProcessor& proc;
int idx = 0;
gin::ParamComponent::Ptr trans, detune, spread;
gin::ParamComponent::Ptr detune, spread;
gin::WavetableComponent* wt;
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"};
};
//==============================================================================
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
{
@ -381,9 +421,6 @@ public:
addEnable (proc.distortionParams.enable);
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);
}

View file

@ -2,19 +2,14 @@
#include "PluginEditor.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 gin::Wave::sine: return "Sine";
case gin::Wave::triangle: return "Triangle";
case gin::Wave::sawUp: return "Saw (Up)";
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:
case 0: return "Sine";
case 1: return "Triangle";
case 2: return "Saw";
case 3: return "Pulse";
default:
jassertfalse;
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);
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);
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);
@ -127,7 +121,7 @@ void WavetableAudioProcessor::SubParams::setup (WavetableAudioProcessor& p)
juce::String nm = "SUB ";
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);
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);
@ -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);
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();
chorus.reset();
distortion.reset();
stereoDelay.reset();
reverb.reset();
@ -555,7 +545,6 @@ void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSample
gate.setSampleRate (newSampleRate);
chorus.setSampleRate (newSampleRate);
distortion.setSampleRate (newSampleRate);
stereoDelay.setSampleRate (newSampleRate);
reverb.setSampleRate (float (newSampleRate));
@ -565,6 +554,7 @@ void WavetableAudioProcessor::prepareToPlay (double newSampleRate, int newSample
modStepLFO.setSampleRate (newSampleRate);
reloadWavetables();
analogTables.setSampleRate (newSampleRate);
}
void WavetableAudioProcessor::releaseResources()
@ -656,7 +646,10 @@ void WavetableAudioProcessor::applyEffects (juce::AudioSampleBuffer& buffer)
// Apply Distortion
if (distortionParams.enable->isOn())
distortion.process (buffer);
{
auto clip = 1.0f / (2.0f * distortionVal);
gin::Distortion::processBlock (buffer, distortionVal, -clip, clip);
}
// Apply Delay
if (delayParams.enable->isOn())
@ -754,12 +747,7 @@ void WavetableAudioProcessor::updateParams (int newBlockSize)
// Update Distortion
if (distortionParams.enable->isOn())
{
distortion.setParams (modMatrix.getValue (distortionParams.amount),
modMatrix.getValue (distortionParams.highpass),
modMatrix.getValue (distortionParams.output),
modMatrix.getValue (distortionParams.mix));
}
distortionVal = modMatrix.getValue (distortionParams.amount);
// Update Delay
if (delayParams.enable->isOn())

View file

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

View file

@ -4,6 +4,8 @@
//==============================================================================
WavetableVoice::WavetableVoice (WavetableAudioProcessor& p)
: proc (p)
, noise (proc.analogTables)
, sub (proc.analogTables)
{
filter.setNumChannels (2);
}
@ -155,6 +157,12 @@ void WavetableVoice::renderNextBlock (juce::AudioBuffer<float>& outputBuffer, in
if (proc.oscParams[i].enable->isOn())
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
float velocity = currentlyPlayingNote.noteOnVelocity.asUnsignedFloat();
buffer.applyGain (gin::velocityToGain (velocity, ampKeyTrack));
@ -196,13 +204,40 @@ void WavetableVoice::updateParams (int blockSize)
oscParams[i].wave = gin::Wave::wavetable;
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].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);
}
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);

View file

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