sm-26/Source/SynthParams.cpp

191 lines
6.1 KiB
C++
Raw Normal View History

#include "SynthParams.h"
namespace sm26 {
static const char* const kStepLabels[] = {
"1/32", "1/16T", "1/16", "1/8T",
"1/8", "1/4T", "1/4", "1/2T",
"1/2", "3/4", "1", "3/2",
"2", "3", "4", "8",
};
static const float kStepBeats[] = {
0.125f, 0.1667f, 0.25f, 0.3333f,
0.5f, 0.6667f, 1.0f, 1.3333f,
2.0f, 3.0f, 4.0f, 6.0f,
8.0f, 12.0f, 16.0f, 32.0f,
};
const char* const* stepsLabels() { return kStepLabels; }
const float* stepsBeats() { return kStepBeats; }
int stepsPerBeatFor(float stepIndex)
{
const int i = juce::jlimit(0, 15, (int) juce::roundToInt(stepIndex * 15.0f));
return juce::roundToInt(kStepBeats[i] * 4.0f);
}
float paramReal(int id, float n01)
{
n01 = clamp01(n01);
switch (id)
{
case PO1OCT: return -2.0f + n01 * 4.0f;
case PO1CT: return -100.0f + n01 * 200.0f;
case PO2OCT: return -2.0f + n01 * 4.0f;
case PO2CT: return -100.0f + n01 * 200.0f;
case PMIX: return n01;
case PNOISE: return n01;
case PCUTOFF: return (float) std::exp (std::log (20.0) + n01 * (std::log (20000.0) - std::log (20.0)));
case PRES: return 0.5f + n01 * 19.5f;
case PFENV: return n01;
case PATK: return (float) std::exp (std::log (0.001) + n01 * (std::log (8.0) - std::log (0.001)));
case PDEC: return (float) std::exp (std::log (0.002) + n01 * (std::log (8.0) - std::log (0.002)));
case PSUS: return n01;
case PREL: return (float) std::exp (std::log (0.002) + n01 * (std::log (8.0) - std::log (0.002)));
case PDTIME: return (float) std::exp (std::log (10.0) + n01 * (std::log (1500.0) - std::log (10.0)));
case PDFB: return n01;
case PDMIX: return n01;
case PDRIVE: return n01;
case PGLIDE: return (float) std::exp (std::log (0.001) + n01 * (std::log (2.0) - std::log (0.001)));
case PMASTER: return 0.10f + n01 * 0.70f;
default: return n01;
}
}
float unwrapParameter(int id, float n01)
{
n01 = clamp01(n01);
switch (id)
{
case PO1OCT: case PO2OCT:
return juce::jmax (0.0f, juce::jmin (1.0f, (n01 + 2.0f) / 4.0f));
case PO1CT: case PO2CT:
return (n01 + 100.0f) / 200.0f;
case PCUTOFF:
return (float) ((std::log (n01) - std::log (20.0)) / (std::log (20000.0) - std::log (20.0)));
case PATK:
return (float) ((std::log (n01) - std::log (0.001)) / (std::log (8.0) - std::log (0.001)));
case PDEC:
return (float) ((std::log (n01) - std::log (0.002)) / (std::log (8.0) - std::log (0.002)));
case PREL:
return (float) ((std::log (n01) - std::log (0.002)) / (std::log (8.0) - std::log (0.002)));
case PDTIME:
return (float) ((std::log (n01) - std::log (10.0)) / (std::log (1500.0) - std::log (10.0)));
case PGLIDE:
return (float) ((std::log (n01) - std::log (0.001)) / (std::log (2.0) - std::log (0.001)));
case PMASTER:
return (n01 - 0.10f) / 0.70f;
default:
return n01;
}
}
const char* paramShortName(int id)
{
static const char* const names[] = {
"OSC1", "OSC2", "O1-OCT", "O1-DET", "O2-OCT", "O2-DET",
"MIX", "NOISE", "CUTOFF", "RES", "F-ENV", "F-TYPE",
"ATK", "DEC", "SUS", "REL", "D-TIME", "D-STEPS",
"SYNC", "D-FB", "D-MIX", "DRIVE","GLIDE", "MASTER",
};
if (id >= 0 && id < kNumParams) return names[id];
return "----";
}
const char* paramUnit(int id)
{
switch (id)
{
case PO1OCT: case PO2OCT: return "oct";
case PO1CT: case PO2CT: return "ct";
case PCUTOFF: return "Hz";
case PDTIME: return "ms";
default: return "";
}
}
int paramWaveIndex(float n01)
{
const int i = (int) juce::roundToInt (n01 * 4.0f);
return juce::jlimit(0, 4, i);
}
int paramFilterType(float n01)
{
return juce::jlimit (0, 2, (int) juce::roundToInt (n01 * 2.0f));
}
const char* waveName(int w)
{
switch (w)
{
case 0: return "SINE";
case 1: return "TRI";
case 2: return "SAW";
case 3: return "SQRE";
case 4: return "NSE";
default: return "----";
}
}
const char* filterTypeName(int t)
{
switch (t)
{
case 0: return "LP";
case 1: return "BP";
case 2: return "HP";
default: return "LP";
}
}
String formatTimeMs(float ms)
{
if (ms >= 1000.0f) return String (ms / 1000.0, 2) + " s";
return String ((int) juce::roundToInt (ms)) + " ms";
}
String formatFreq(float hz)
{
if (hz >= 1000.0f) return String (hz / 1000.0, 2) + " kHz";
return String ((int) juce::roundToInt (hz)) + " Hz";
}
String formatPercent(float v)
{
return String ((int) juce::roundToInt (v * 100.0f)) + "%";
}
String formatParamReal(int id, float n01)
{
n01 = clamp01 (n01);
switch (id)
{
case PO1WAVE: case PO2WAVE:
return waveName (paramWaveIndex (n01));
case PO1OCT: case PO2OCT:
return String (paramReal (id, n01), 2);
case PO1CT: case PO2CT:
return String ((int) juce::roundToInt (paramReal (id, n01))) + " ct";
case PMIX: case PNOISE: case PFENV: case PSUS:
case PDFB: case PDMIX: case PDRIVE: case PMASTER:
return formatPercent (n01);
case PCUTOFF: return formatFreq (paramReal (id, n01));
case PRES: return String (paramReal (id, n01), 1);
case PFTYPE: return filterTypeName (paramFilterType (n01));
case PATK: case PDEC: case PREL:
return formatTimeMs (paramReal (id, n01) * 1000.0f);
case PDTIME: return formatTimeMs (paramReal (id, n01));
case PDSTEPS:
return stepsLabels() [juce::jlimit (0, 15, (int) juce::roundToInt (n01))];
case PDSYNC:
return n01 > 0.5f ? "SYNC" : "MS";
case PGLIDE:
return formatTimeMs (paramReal (id, n01) * 1000.0f);
default:
return String ((int) juce::roundToInt (n01 * 100.0f)) + "%";
}
}
} // namespace sm26