mirror of
https://codeberg.org/armin/rmx-19.git
synced 2026-10-11 16:51:55 +02:00
154 lines
7.3 KiB
C++
154 lines
7.3 KiB
C++
|
|
#include "Params.h"
|
||
|
|
#include "PresetBank.h"
|
||
|
|
|
||
|
|
namespace prm {
|
||
|
|
|
||
|
|
static const Desc table[num] = {
|
||
|
|
// id name short min max def disc fine coarse
|
||
|
|
{ "osc1wave", "OSC1 WAVE", "O1WV", 0, 4, 2, true, 1, 1 },
|
||
|
|
{ "osc2wave", "OSC2 WAVE", "O2WV", 0, 4, 3, true, 1, 1 },
|
||
|
|
{ "detune", "DETUNE", "DTN", -50, 50, 8, false, 1, 6 },
|
||
|
|
{ "oscmix", "OSC BAL", "MIX", 0, 100, 52, false, 1, 8 },
|
||
|
|
{ "flttype", "FILTER TYPE", "FTYP", 0, 3, 1, true, 1, 1 },
|
||
|
|
{ "fltcut", "CUTOFF", "CUT", 20, 20000, 3400, false, 20, 400 },
|
||
|
|
{ "fltres", "RESONANCE", "RES", 0, 0.98f, 0.18f, false, 0.01f, 0.08f },
|
||
|
|
{ "fltenv", "FILT ENV", "FEN", 0, 100, 52, false, 1, 8 },
|
||
|
|
{ "fltkey", "KEY TRACK", "KEY", 0, 100, 40, false, 1, 8 },
|
||
|
|
{ "ampA", "AMP ATTACK", "AAT", 0.001f, 6, 0.008f, false, 0.001f, 0.05f },
|
||
|
|
{ "ampD", "AMP DECAY", "ADE", 0.001f, 6, 0.26f, false, 0.001f, 0.05f },
|
||
|
|
{ "ampS", "AMP SUSTAIN", "ASUS", 0, 1, 0.70f, false, 0.01f, 0.08f },
|
||
|
|
{ "ampR", "AMP RELEASE", "AREL", 0.001f, 8, 0.35f, false, 0.001f, 0.05f },
|
||
|
|
{ "fenvA", "FENV ATTACK", "FAT", 0.001f, 6, 0.02f, false, 0.001f, 0.05f },
|
||
|
|
{ "fenvD", "FENV DECAY", "FDE", 0.001f, 6, 0.16f, false, 0.001f, 0.05f },
|
||
|
|
{ "fenvS", "FENV SUSTAIN", "FSUS", 0, 1, 0.26f, false, 0.01f, 0.08f },
|
||
|
|
{ "fenvR", "FENV RELEASE", "FRE", 0.001f, 8, 0.25f, false, 0.001f, 0.05f },
|
||
|
|
{ "lforate", "LFO RATE", "LFR", 0.02f, 22, 4.2f, false, 0.02f, 0.5f },
|
||
|
|
{ "lfoshape", "LFO SHAPE", "LFS", 0, 3, 0, true, 1, 1 },
|
||
|
|
{ "lfodepth", "LFO DEPTH", "LFD", 0, 1, 0.22f, false, 0.01f, 0.08f },
|
||
|
|
{ "lfotarget", "LFO TARGET", "LFT", 0, 2, 0, true, 1, 1 },
|
||
|
|
{ "fxtype", "FX TYPE", "FXT", 0, 3, 1, true, 1, 1 },
|
||
|
|
{ "fxamt", "FX DEPTH", "FXD", 0, 1, 0.30f, false, 0.01f, 0.08f },
|
||
|
|
{ "fxtime", "FX TIME", "FXT", 0.05f, 1.2f, 0.28f, false, 0.01f, 0.12f },
|
||
|
|
{ "vol", "MASTER VOL", "VOL", 0, 1, 0.85f, false, 0.01f, 0.08f },
|
||
|
|
{ "pan", "STEREO PAN", "PAN", -1, 1, 0, false, 0.02f, 0.2f },
|
||
|
|
{ "poly", "POLYPHONY", "POLY", 1, 16, 10, true, 1, 1 },
|
||
|
|
{ "glide", "PORTAMENTO", "GLD", 0, 2, 0, false, 0.02f, 0.2f },
|
||
|
|
{ "tune", "MASTER TUNE", "TUN", -12, 12, 0, true, 1, 1 },
|
||
|
|
};
|
||
|
|
|
||
|
|
const Desc& desc (Id id) { return table[static_cast<int>(id)]; }
|
||
|
|
bool validId (int i) { return i >= 0 && i < num; }
|
||
|
|
|
||
|
|
juce::AudioProcessorValueTreeState::ParameterLayout createLayout()
|
||
|
|
{
|
||
|
|
juce::AudioProcessorValueTreeState::ParameterLayout layout;
|
||
|
|
|
||
|
|
PresetBank bank;
|
||
|
|
const Patch& p0 = bank.get (0); // seed APVTS defaults with the first patch
|
||
|
|
|
||
|
|
for (int i = 0; i < num; ++i)
|
||
|
|
{
|
||
|
|
const Desc& d = table[i];
|
||
|
|
juce::NormalisableRange<float> r (d.min, d.max);
|
||
|
|
if (juce::String (d.id) == "fltcut")
|
||
|
|
r = juce::NormalisableRange<float> (d.min, d.max, 1.0f, 0.22f);
|
||
|
|
else if (d.discrete)
|
||
|
|
r = juce::NormalisableRange<float> (d.min, d.max, 1.0f);
|
||
|
|
|
||
|
|
layout.add (std::make_unique<juce::AudioParameterFloat> (
|
||
|
|
d.id, d.name, r, p0.v[i]));
|
||
|
|
}
|
||
|
|
|
||
|
|
layout.add (std::make_unique<juce::AudioParameterInt> ("patchsel", "Patch", 0, 15, 0));
|
||
|
|
return layout;
|
||
|
|
}
|
||
|
|
|
||
|
|
const char* waveName (int w)
|
||
|
|
{
|
||
|
|
switch (w) { case 0: return "SINE"; case 1: return "TRIANG"; case 2: return "SAWTOOTH";
|
||
|
|
case 3: return "PULSE"; case 4: return "NOISE"; default: return "-----"; }
|
||
|
|
}
|
||
|
|
|
||
|
|
const char* fltTypeName (int t)
|
||
|
|
{
|
||
|
|
switch (t) { case 0: return "OFF "; case 1: return "LOWPASS "; case 2: return "BANDPASS ";
|
||
|
|
case 3: return "HIGH-PASS"; default: return "OFF "; }
|
||
|
|
}
|
||
|
|
|
||
|
|
const char* lfoShapeName (int s)
|
||
|
|
{
|
||
|
|
switch (s) { case 0: return "SINE"; case 1: return "TRIANG"; case 2: return "SQUARE";
|
||
|
|
case 3: return "S+H "; default: return "SINE"; }
|
||
|
|
}
|
||
|
|
|
||
|
|
const char* lfoTargetName (int t)
|
||
|
|
{
|
||
|
|
switch (t) { case 0: return "FILTER"; case 1: return "PITCH"; case 2: return "AMP ";
|
||
|
|
default: return "FILTER"; }
|
||
|
|
}
|
||
|
|
|
||
|
|
const char* fxTypeName (int t)
|
||
|
|
{
|
||
|
|
switch (t) { case 0: return "OFF"; case 1: return "CHORUS"; case 2: return "DELAY ";
|
||
|
|
case 3: return "SPACE"; default: return "OFF"; }
|
||
|
|
}
|
||
|
|
|
||
|
|
static juce::String fmtTime (float t)
|
||
|
|
{
|
||
|
|
if (t >= 1.0f) return juce::String (t, 2) + "s";
|
||
|
|
if (t >= 0.1f) return juce::String (t, 2) + "s";
|
||
|
|
return juce::String ((int) (t * 1000.0f)) + "ms";
|
||
|
|
}
|
||
|
|
|
||
|
|
static juce::String fmtPercent (float v) { return juce::String ((int) (v * 100.0f + 0.5f)) + "%"; }
|
||
|
|
|
||
|
|
juce::String formatParam (Id id, float v)
|
||
|
|
{
|
||
|
|
switch (id)
|
||
|
|
{
|
||
|
|
case Id::osc1Wave:
|
||
|
|
case Id::osc2Wave: return waveName ((int) v);
|
||
|
|
case Id::detune: return juce::String ((int) v > 0 ? "+" : "") + juce::String ((int) v) + "c";
|
||
|
|
case Id::oscMix: return juce::String ((int) (100.0f - v)) + "/" + juce::String ((int) v);
|
||
|
|
case Id::fltType: return fltTypeName ((int) v);
|
||
|
|
case Id::fltCutoff:
|
||
|
|
if (v >= 1000.0f) return juce::String (v / 1000.0f, 2) + "kHz";
|
||
|
|
return juce::String ((int) v) + "Hz";
|
||
|
|
case Id::fltRes: return fmtPercent (v);
|
||
|
|
case Id::fltEnv: return fmtPercent (v / 100.0f);
|
||
|
|
case Id::fltKey: return fmtPercent (v / 100.0f);
|
||
|
|
case Id::ampA: case Id::ampD: case Id::ampR:
|
||
|
|
case Id::fenvA: case Id::fenvD: case Id::fenvR: return fmtTime (v);
|
||
|
|
case Id::ampS: case Id::fenvS: return fmtPercent (v);
|
||
|
|
case Id::lfoRate: return juce::String (v, 2) + "Hz";
|
||
|
|
case Id::lfoShape: return lfoShapeName ((int) v);
|
||
|
|
case Id::lfoDepth: return fmtPercent (v);
|
||
|
|
case Id::lfoTarget:return lfoTargetName ((int) v);
|
||
|
|
case Id::fxType: return fxTypeName ((int) v);
|
||
|
|
case Id::fxAmt: return fmtPercent (v);
|
||
|
|
case Id::fxTime: return fmtTime (v);
|
||
|
|
case Id::vol: return fmtPercent (v);
|
||
|
|
case Id::pan:
|
||
|
|
if (v < -0.02f) return "L" + juce::String ((int) (v * -100.0f));
|
||
|
|
if (v > 0.02f) return "R" + juce::String ((int) (v * 100.0f));
|
||
|
|
return "CTR";
|
||
|
|
case Id::poly: return juce::String ((int) v) + " VOICE";
|
||
|
|
case Id::glide: return v < 0.001f ? juce::String ("0") : fmtTime (v);
|
||
|
|
case Id::tune: {
|
||
|
|
const int t = (int) v;
|
||
|
|
return juce::String (t > 0 ? "+" : "") + juce::String (t) + "ST";
|
||
|
|
}
|
||
|
|
default: return "-----";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
float changeParam (Id id, float cur, int dir, bool coarse)
|
||
|
|
{
|
||
|
|
const Desc& d = desc (id);
|
||
|
|
float step = coarse ? d.coarse : d.fine;
|
||
|
|
cur = juce::jlimit (d.min, d.max, cur + dir * step);
|
||
|
|
if (d.discrete) cur = (float) juce::roundToInt (cur);
|
||
|
|
return cur;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace prm
|