rmx-19/Source/SynthEngine.h

151 lines
4.8 KiB
C
Raw Normal View History

#pragma once
#include <juce_audio_processors/juce_audio_processors.h>
#include "Params.h"
struct VParams
{
float osc1w = 2, osc2w = 3, detune = 8, oscMix = 52.f;
float fltType = 1, fltCut = 3400.f, fltRes = 0.18f, fltEnv = 52.f, fltKey = 40.f;
float ampA = 0.008f, ampD = 0.26f, ampS = 0.70f, ampR = 0.35f;
float fA = 0.02f, fD = 0.16f, fS = 0.26f, fR = 0.25f;
float lfoRate = 4.2f, lfoShape = 0, lfoDepth = 0.22f, lfoTarget = 0;
float fxType = 1, fxAmt = 0.30f, fxTime = 0.28f;
float vol = 0.85f, pan = 0.0f, poly = 10.f, glide = 0.f, tune = 0.f;
float hq = 0.0f;
2026-09-08 21:57:34 +02:00
float arpOn = 0, arpRate = 2, arpPattern = 0, arpOct = 1, arpGate = 70;
void update (const juce::AudioProcessorValueTreeState& apvts)
{
auto get = [&] (const char* id) { return apvts.getRawParameterValue (id) -> load(); };
osc1w = get ("osc1wave"); osc2w = get ("osc2wave"); detune = get ("detune");
oscMix = get ("oscmix");
fltType = get ("flttype"); fltCut = get ("fltcut"); fltRes = get ("fltres");
fltEnv = get ("fltenv"); fltKey = get ("fltkey");
ampA = get ("ampA"); ampD = get ("ampD"); ampS = get ("ampS");
ampR = get ("ampR");
fA = get ("fenvA"); fD = get ("fenvD"); fS = get ("fenvS");
fR = get ("fenvR");
lfoRate = get ("lforate"); lfoShape = get ("lfoshape"); lfoDepth = get ("lfodepth");
lfoTarget= get ("lfotarget");
fxType = get ("fxtype"); fxAmt = get ("fxamt"); fxTime = get ("fxtime");
vol = get ("vol"); pan = get ("pan"); poly = get ("poly");
glide = get ("glide"); tune = get ("tune");
hq = get ("hq");
2026-09-08 21:57:34 +02:00
arpOn = get ("arpon");
arpRate = get ("arprate");
arpPattern = get ("arppattern");
arpOct = get ("arpoct");
arpGate = get ("arpgate");
}
};
// ---------------------------------------------------------------------------
class Env
{
public:
enum State { Off, Atk, Dec, Sus, Rel };
void setRates (float a, float d, float s, float r, double sr)
{
srInv = 1.0 / sr;
attTau = 1.0f / (0.001f + 0.25f * a);
decTau = 1.0f / (0.001f + 0.35f * d);
relTau = 1.0f / (0.001f + 0.30f * r);
susL = s;
}
void noteOn () { st = Atk; }
void noteOff ()
{
if (st != Off && st != Rel) st = Rel;
}
void reset (float v = 0.0f) { cur = v; st = Off; }
float next()
{
switch (st)
{
case Atk:
cur += (1.0f - cur) * std::min (1.0f, (float) (attTau * srInv) * 8.0f);
if (cur >= 1.0f) { cur = 1.0f; st = Dec; }
break;
case Dec:
cur = susL + (cur - susL) * std::exp (-decTau * (float) srInv);
if (std::abs (cur - susL) < 0.001f) { cur = susL; st = Sus; }
break;
case Sus: break;
case Rel:
cur *= std::exp (-relTau * (float) srInv);
if (cur < 0.0002f) { cur = 0.0f; st = Off; }
break;
case Off: break;
}
return cur;
}
bool running() const { return st != Off; }
float getCur() const { return cur; }
State getState() const { return st; }
private:
float cur = 0.0f, susL = 0.7f;
float attTau = 1.0f, decTau = 1.0f, relTau = 1.0f;
double srInv = 1.0 / 48000.0;
State st = Off;
};
// ---------------------------------------------------------------------------
class SynthEngine
{
public:
SynthEngine();
~SynthEngine();
void setSampleRate (double sr);
void noteOn (int midiNote, float velocity);
void noteOff (int midiNote);
void allNotesOff (bool immediate);
void sustainPedal (bool down);
void pitchBend (float cents);
void modWheel (float v);
void render (const VParams& p, float* left, float* right, int numSamples);
int activeVoices() const noexcept { return active; }
private:
struct Voice
{
bool active = false;
int note = 0;
float vel = 1.0f;
float panL = 0.71f, panR = 0.71f;
float curFreq = 0.0f, targetFreq = 0.0f;
double ph1 = 0.0, ph2 = 0.0, lfoPh = 0.0;
float lfoSH = 0.0f;
int lfoIdx = 0;
Env amp, flt;
float lp = 0.0f, bp = 0.0f, f1c = 0.0f;
float fcSm = 0.0f;
float outSmooth = 0.0f;
};
static constexpr int maxVoice = 16;
Voice voices[maxVoice];
double sr = 48000.0;
int active = 0;
int polyLimit = 16;
float mod = 0.0f, bendCents = 0.0f, bendSmooth = 0.0f;
bool pedal = false;
float lastNoteFreq = 440.0f, lastGlide = 0.0f, lastPan = 0.0f;
int stealIdx = 0;
juce::Random rng;
juce::Array<int> sustainedNotes;
float osc (int wave, double ph);
Voice* acquireVoice();
};