gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 024e8c25b08b310f27b00bdd1e21ba87bedc26ae
parent 0247c580db5e69c66922c2556cdaf362e428ac1d
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Mon, 14 Feb 2022 20:01:26 +0100

parameter definitions now used from json

Diffstat:
Msource/jucePlugin/VirusController.cpp | 11+++++++----
Msource/jucePlugin/VirusController.h | 2++
Msource/jucePlugin/VirusParameter.cpp | 7+++----
Msource/jucePlugin/VirusParameter.h | 49+++++++++----------------------------------------
Msource/jucePlugin/VirusParameterDescription.cpp | 1530+------------------------------------------------------------------------------
Msource/jucePlugin/VirusParameterDescription.h | 43+++++++++++++++++++++++++++++++++++++++++--
Msource/jucePlugin/VirusParameterDescriptions.cpp | 69+++++++++++++++++++++++----------------------------------------------
Msource/jucePlugin/VirusParameterDescriptions.h | 11++++++++---
8 files changed, 94 insertions(+), 1628 deletions(-)

diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -1,6 +1,9 @@ #include <juce_audio_processors/juce_audio_processors.h> #include "VirusController.h" + +#include "BinaryData.h" #include "PluginProcessor.h" +#include "VirusParameterDescriptions.h" #include "../virusLib/microcontrollerTypes.h" @@ -11,9 +14,9 @@ namespace Virus static constexpr uint8_t kSysExStart[] = {0xf0, 0x00, 0x20, 0x33, 0x01}; static constexpr auto kHeaderWithMsgCodeLen = 7; - Controller::Controller(AudioPluginAudioProcessor &p, unsigned char deviceId) : m_processor(p), m_deviceId(deviceId) + Controller::Controller(AudioPluginAudioProcessor &p, unsigned char deviceId) : m_processor(p), m_deviceId(deviceId), m_descriptions(BinaryData::parameterDescriptions_C_json) { - assert(g_paramsDescription.size() == Param_Count && "size of enum must match size of parameter descriptions"); + assert(m_descriptions.getDescriptions().size() == Param_Count && "size of enum must match size of parameter descriptions"); juce::PropertiesFile::Options opts; opts.applicationName = "DSP56300 Emulator"; opts.filenameSuffix = ".settings"; @@ -59,7 +62,7 @@ namespace Virus std::make_unique<juce::AudioProcessorParameterGroup>("ch" + partNumber, "Ch " + partNumber, "|"); uint32_t parameterDescIndex = 0; - for (const auto& desc : g_paramsDescription) + for (const auto& desc : m_descriptions.getDescriptions()) { const auto paramType = static_cast<ParameterType>(parameterDescIndex); ++parameterDescIndex; @@ -171,7 +174,7 @@ namespace Virus juce::Value *Controller::getParamValue(uint8_t ch, uint8_t bank, uint8_t paramIndex) { - auto *param = findSynthParam(ch, static_cast<uint8_t>(Parameter::Page::A + bank), paramIndex); + auto *param = findSynthParam(ch, static_cast<uint8_t>(virusLib::PAGE_A + bank), paramIndex); if (param == nullptr) { // unregistered param? diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h @@ -5,6 +5,7 @@ #include "../synthLib/plugin.h" #include "VirusParameter.h" #include "VirusParameterDescription.h" +#include "VirusParameterDescriptions.h" namespace virusLib { @@ -130,5 +131,6 @@ namespace Virus uint8_t m_currentProgram[16]{}; uint8_t m_currentPart = 0; juce::PropertiesFile *m_config; + ParameterDescriptions m_descriptions; }; }; // namespace Virus diff --git a/source/jucePlugin/VirusParameter.cpp b/source/jucePlugin/VirusParameter.cpp @@ -4,10 +4,9 @@ namespace Virus { - Parameter::Parameter(Controller &ctrl, const Description desc, const uint8_t partNum) : - m_ctrl(ctrl), m_desc(desc), - m_partNum(partNum), juce::RangedAudioParameter(genId(desc, partNum), - "Ch " + juce::String(partNum + 1) + " " + desc.name) + Parameter::Parameter(Controller &ctrl, const Description& desc, const uint8_t partNum) : + juce::RangedAudioParameter(genId(desc, partNum), "Ch " + juce::String(partNum + 1) + " " + desc.name), m_ctrl(ctrl), + m_desc(desc), m_partNum(partNum) { m_range.start = static_cast<float>(m_desc.range.getStart()); m_range.end = static_cast<float>(m_desc.range.getEnd()); diff --git a/source/jucePlugin/VirusParameter.h b/source/jucePlugin/VirusParameter.h @@ -2,9 +2,11 @@ #include <juce_audio_processors/juce_audio_processors.h> +#include "VirusParameterDescription.h" + namespace Virus { - class Controller; + class Controller; class Parameter : juce::Value::Listener, public juce::RangedAudioParameter { @@ -23,30 +25,7 @@ namespace Virus VIRUS_C = 0x100, }; - enum Page - { - A = 0x70, - B = 0x71, - C = 0x72 - }; - - struct Description - { - Page page; - int classFlags; - uint8_t index; - juce::String name; - juce::Range<int> range; - std::function<juce::String(float, Description ctx)> valueToTextFunction; - std::function<float(const juce::String &, Description ctx)> textToValueFunction; - bool isPublic; - bool isDiscrete; - bool isBool; - bool isBipolar; - std::string toText; - }; - - Parameter(Controller &, const Description desc, uint8_t partNum = 0x40); + Parameter(Controller &, const Description& desc, uint8_t partNum = 0x40); juce::Value &getValueObject() { return m_value; }; const juce::Value &getValueObject() const { return m_value; }; @@ -78,24 +57,14 @@ namespace Virus float getValueForText(const juce::String &text) const override { - if (m_desc.textToValueFunction) - return convertTo0to1(m_desc.textToValueFunction(text, m_desc)); - if (m_desc.valueToTextFunction) - { - // brute force but this should be O(1) of 128... - for (auto i = 0; i < 128; i++) - if (m_desc.valueToTextFunction(static_cast<float>(i), m_desc) == text) - return convertTo0to1(static_cast<float>(i)); - } - return convertTo0to1(text.getFloatValue()); + const auto res = m_desc.valueList.textToValue(std::string(text.getCharPointer())); + return convertTo0to1(static_cast<float>(res)); } juce::String getText(float normalisedValue, int /*maximumStringLength*/) const override { - if (m_desc.valueToTextFunction) - return m_desc.valueToTextFunction(convertFrom0to1(normalisedValue), m_desc); - else - return juce::String(juce::roundToInt(convertFrom0to1(normalisedValue))); + const auto v = convertFrom0to1(normalisedValue); + return m_desc.valueList.valueToText(juce::roundToInt(v)); } // allow 'injecting' additional code for specific parameter. @@ -103,7 +72,7 @@ namespace Virus std::function<void()> onValueChanged = {}; private: - juce::String genId(const Description &d, int part); + static juce::String genId(const Description &d, int part); void valueChanged(juce::Value &) override; Controller &m_ctrl; diff --git a/source/jucePlugin/VirusParameterDescription.cpp b/source/jucePlugin/VirusParameterDescription.cpp @@ -1,1532 +1,5 @@ #include "VirusParameterDescription.h" -#include "VirusParameter.h" - namespace Virus { - juce::String numToBank(float bankIdx, const Parameter::Description&) - { - jassert(bankIdx >= 0); - juce::String prefix = "RAM"; - if (bankIdx > 3) - { - prefix = bankIdx < 9 ? "ROM " : "ROM"; - } - return prefix + juce::String(juce::roundToInt(bankIdx + 1)); - } - - juce::String numTo7bitSigned(const int idx) - { - const auto sign = idx > 64 ? "+" : ""; - return sign + juce::String(juce::roundToInt(idx - 64)); - } - - juce::String paramTo7bitSigned(const float idx, const Parameter::Description&) - { - return numTo7bitSigned(juce::roundToInt(idx)); - } - - float textTo7bitSigned(const juce::String& text, const Parameter::Description&) - { - const auto val = std::clamp(text.getIntValue(), -64, 63); - return static_cast<float>(val) + 64.0f; - } - - juce::String numToPan(float panIdx, const Parameter::Description&) - { - // handles rounding due to continuous... - const auto idx = juce::roundToInt(panIdx); - if (idx == 64) - return "Center"; - if (idx == 0) - return "Left"; - if (idx == 127) - return "Right"; - return numTo7bitSigned(idx); - } - - juce::String numToOscShape(float panIdx, Parameter::Description) - { - const auto idx = juce::roundToInt(panIdx); - if (idx == 64) - return "Saw"; - if (idx == 0) - return "Wave"; - if (idx == 127) - return "Pulse"; - return numTo7bitSigned(idx); - } - - juce::String numToOscWaveSelect(float panIdx, Parameter::Description) - { - const auto idx = juce::roundToInt(panIdx); - if (idx == 0) - return "Sine"; - if (idx == 1) - return "Triangle"; - return "Wave " + juce::String(idx + 1); - } - - juce::String numToSatCurv(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Light"; - case 2: return "Soft"; - case 3: return "Middle"; - case 4: return "Hard"; - case 5: return "Digital"; - case 6: return "Shaper"; - case 7: return "Rectifier"; - case 8: return "BitReducer"; - case 9: return "RateReducer"; - case 10: return "Rate+Flw"; - case 11: return "LowPass"; - case 12: return "Low+Flw"; - case 13: return "HighPass"; - case 14: return "High+Flw"; - - default: return juce::String(idx); - } - } - - juce::String numToDistortionCurv(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Light"; - case 2: return "Soft"; - case 3: return "Middle"; - case 4: return "Hard"; - case 5: return "Digital"; - case 6: return "Shaper"; - case 7: return "Rectifier"; - case 8: return "BitReducer"; - case 9: return "RateReducer"; - case 10: return "LowPass"; - case 11: return "HighPass"; - default: return juce::String(idx); - } - } - - juce::String numToFilterMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "LowPass"; - case 1: return "HighPass"; - case 2: return "BandPass"; - case 3: return "BandStop"; - case 4: return "Analog 1P"; - case 5: return "Analog 2P"; - case 6: return "Analog 3P"; - case 7: return "Analog 4P"; - default: return juce::String(idx); - } - } - - juce::String numToFilter2Mode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "LowPass"; - case 1: return "HighPass"; - case 2: return "BandPass"; - case 3: return "BandStop"; - default: return juce::String(idx); - } - } - - juce::String numToFilterRouting(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Serial 4"; - case 1: return "Serial 6"; - case 2: return "Parallel 4"; - case 3: return "Split"; - default: return juce::String(idx); - } - } - - juce::String numToEnvSusTime(float idx, const Parameter::Description&) - { - // handles rounding due to continuous... - const auto ridx = juce::roundToInt(idx); - if (ridx == 64) - return "Fall"; - if (ridx == 0) - return "Infinite"; - if (ridx == 127) - return "Rise"; - return numTo7bitSigned(ridx); - } - - juce::String numToLfoShape(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Sine"; - case 1: return "Triangle"; - case 2: return "Saw"; - case 3: return "Square"; - case 4: return "S&H"; - case 5: return "S&G"; - case 6: return "Wave3"; - case 7: return "Wave4"; - case 8: return "Wave5"; - case 9: return "Wave6"; - case 10: return "Wave7"; - case 11: return "Wave8"; - case 12: return "Wave9"; - case 13: return "Wave10"; - case 14: return "Wave11"; - case 15: return "Wave12"; - case 16: return "Wave13"; - case 17: return "Wave14"; - case 18: return "Wave15"; - case 19: return "Wave16"; - case 20: return "Wave17"; - case 21: return "Wave18"; - case 22: return "Wave19"; - case 23: return "Wave20"; - case 24: return "Wave21"; - case 25: return "Wave22"; - case 26: return "Wave23"; - case 27: return "Wave24"; - case 28: return "Wave25"; - case 29: return "Wave26"; - case 30: return "Wave27"; - case 31: return "Wave28"; - case 32: return "Wave29"; - case 33: return "Wave30"; - case 34: return "Wave31"; - case 35: return "Wave32"; - case 36: return "Wave33"; - case 37: return "Wave34"; - case 38: return "Wave35"; - case 39: return "Wave36"; - case 40: return "Wave37"; - case 41: return "Wave38"; - case 42: return "Wave39"; - case 43: return "Wave40"; - case 44: return "Wave41"; - case 45: return "Wave42"; - case 46: return "Wave43"; - case 47: return "Wave44"; - case 48: return "Wave45"; - case 49: return "Wave46"; - case 50: return "Wave47"; - case 51: return "Wave48"; - case 52: return "Wave49"; - case 53: return "Wave50"; - case 54: return "Wave51"; - case 55: return "Wave52"; - case 56: return "Wave53"; - case 57: return "Wave54"; - case 58: return "Wave55"; - case 59: return "Wave56"; - case 60: return "Wave57"; - case 61: return "Wave58"; - case 62: return "Wave59"; - case 63: return "Wave60"; - case 64: return "Wave61"; - case 65: return "Wave62"; - case 66: return "Wave63"; - case 67: return "Wave64"; - default: return juce::String(idx); - } - } - juce::String numToDelayLfoShape(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Sine"; - case 1: return "Triangle"; - case 2: return "Saw"; - case 3: return "Square"; - case 4: return "S&H"; - case 5: return "S&G"; - default: return juce::String(""); - } - } - juce::String numToOsc3Mode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Slave"; - case 2: return "Saw"; - case 3: return "Pulse"; - case 4: return "Sine"; - case 5: return "Triangle"; - case 6: return "Wave3"; - case 7: return "Wave4"; - case 8: return "Wave5"; - case 9: return "Wave6"; - case 10: return "Wave7"; - case 11: return "Wave8"; - case 12: return "Wave9"; - case 13: return "Wave10"; - case 14: return "Wave11"; - case 15: return "Wave12"; - case 16: return "Wave13"; - case 17: return "Wave14"; - case 18: return "Wave15"; - case 19: return "Wave16"; - case 20: return "Wave17"; - case 21: return "Wave18"; - case 22: return "Wave19"; - case 23: return "Wave20"; - case 24: return "Wave21"; - case 25: return "Wave22"; - case 26: return "Wave23"; - case 27: return "Wave24"; - case 28: return "Wave25"; - case 29: return "Wave26"; - case 30: return "Wave27"; - case 31: return "Wave28"; - case 32: return "Wave29"; - case 33: return "Wave30"; - case 34: return "Wave31"; - case 35: return "Wave32"; - case 36: return "Wave33"; - case 37: return "Wave34"; - case 38: return "Wave35"; - case 39: return "Wave36"; - case 40: return "Wave37"; - case 41: return "Wave38"; - case 42: return "Wave39"; - case 43: return "Wave40"; - case 44: return "Wave41"; - case 45: return "Wave42"; - case 46: return "Wave43"; - case 47: return "Wave44"; - case 48: return "Wave45"; - case 49: return "Wave46"; - case 50: return "Wave47"; - case 51: return "Wave48"; - case 52: return "Wave49"; - case 53: return "Wave50"; - case 54: return "Wave51"; - case 55: return "Wave52"; - case 56: return "Wave53"; - case 57: return "Wave54"; - case 58: return "Wave55"; - case 59: return "Wave56"; - case 60: return "Wave57"; - case 61: return "Wave58"; - case 62: return "Wave59"; - case 63: return "Wave60"; - case 64: return "Wave61"; - case 65: return "Wave62"; - case 66: return "Wave63"; - case 67: return "Wave64"; - default: return juce::String(idx); - } - } - - juce::String numToLfoMode(float v, const Parameter::Description&) { return juce::roundToInt(v) == 0 ? "Poly" : "Mono"; } - - juce::String numToKeyMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Poly"; - case 1: return "Mono 1"; - case 2: return "Mono 2"; - case 3: return "Mono 3"; - case 4: return "Mono 4"; - case 5: return "Hold"; - default: return juce::String(idx); - } - } - - juce::String numToInputMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Dynamic"; - case 2: return "Static"; - case 3: return "To Effects"; - default: return juce::String(idx); - } - } - - juce::String numToInputSelect(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "IN L"; - case 1: return "IN L+R"; - case 2: return "IN R"; - case 3: return "AUX 1 L"; - case 4: return "AUX 1 L+R"; - case 5: return "AUX 1 R"; - case 6: return "AUX 2 L"; - case 7: return "AUX 2 L+R"; - case 8: return "AUX 2 R"; - default: return juce::String(idx); - } - } - - juce::String numToOutputSelect(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "OUT 1 L"; - case 1: return "OUT 1 L+R"; - case 2: return "OUT 1 R"; - /* case 3: return "OUT 2 L"; - case 4: return "OUT 2 L+R"; - case 5: return "OUT 2 R"; - case 6: return "OUT 3 L"; - case 7: return "OUT 3 L+R"; - case 8: return "OUT 3 R";*/ - case 9: return "AUX 1 L"; - case 10: return "AUX 1 L+R"; - case 11: return "AUX 1 R"; - case 12: return "AUX 2 L"; - case 13: return "AUX 2 L+R"; - case 14: return "AUX 2 R"; - default: return juce::String(""); - } - } - - juce::String numToDelayReverbMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Delay"; - case 2: return "Reverb"; - case 3: return "Reverb + Feedback 1"; - case 4: return "Reverb + Feedback 2"; - case 5: return "Delay2:1"; - case 6: return "Delay4:3"; - case 7: return "Delay4:1"; - case 8: return "Delay8:7"; - case 9: return "Pattern1+1"; - case 10: return "Pattern2+1"; - case 11: return "Pattern3+1"; - case 12: return "Pattern4+1"; - case 13: return "Pattern5+1"; - case 14: return "Pattern2+3"; - case 15: return "Pattern2+5"; - case 16: return "Pattern3+2"; - case 17: return "Pattern3+3"; - case 18: return "Pattern3+4"; - case 19: return "Pattern3+5"; - case 20: return "Pattern4+3"; - case 21: return "Pattern4+5"; - case 22: return "Pattern5+2"; - case 23: return "Pattern5+3"; - case 24: return "Pattern5+4"; - case 25: return "Pattern5+5"; - case 26: return "Pattern X+Y"; - default: return juce::String(idx); - } - } - - juce::String numToArpMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Up"; - case 2: return "Down"; - case 3: return "Up&Down"; - case 4: return "As Played"; - case 5: return "Random"; - case 6: return "Chord"; - default: return juce::String(idx); - } - } - - juce::String numToLfoDest(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Osc1"; - case 1: return "Osc1+2"; - case 2: return "Osc2"; - case 3: return "PW1"; - case 4: return "PW1+2"; - case 5: return "PW2"; - default: return juce::String(idx); - } - } - - juce::String numToArpSwing(float idx, const Parameter::Description&) - { - return juce::String(juce::roundToInt(50 + (75 - 50) * (idx / 127))) + "%"; - } - - juce::String numToNumPlusOne(float idx, const Parameter::Description&) - { - return juce::String(juce::roundToInt(idx + 1)); - } - - juce::String numToClockTempo(float idx, const Parameter::Description&) - { - return juce::String(juce::roundToInt(63 + (190 - 63) * (idx / 127))) + "BPM"; - } - - juce::String numToControlSmoothMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "On"; - case 2: return "Auto"; - case 3: return "Note"; - default: return juce::String(idx); - } - } - - juce::String numToNegPos(float v, const Parameter::Description&) - { - return juce::roundToInt(v) == 0 ? "Negative" : "Positive"; - } - - juce::String numToLinExp(float v, const Parameter::Description&) - { - return juce::roundToInt(v) == 0 ? "Linear" : "Exponential"; - } - - juce::String numToModMatrixSource(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return "Off"; - case 1: return "PitchBnd"; - case 2: return "ChanPres"; - case 3: return "ModWheel"; - case 4: return "Breath"; - case 5: return "Contr3"; - case 6: return "Foot"; - case 7: return "Data"; - case 8: return "Balance"; - case 9: return "Contr 9"; - case 10: return "Express"; - case 11: return "Contr 12"; - case 12: return "Contr 13"; - case 13: return "Contr 14"; - case 14: return "Contr 15"; - case 15: return "Contr 16"; - case 16: return "HoldPed"; - case 17: return "PortaSw"; - case 18: return "SostPed"; - case 19: return "AmpEnv"; - case 20: return "FiltEnv"; - case 21: return "Lfo 1"; - case 22: return "Lfo 2"; - case 23: return "Lfo 3"; - case 24: return "VeloOn"; - case 25: return "VeloOff"; - case 26: return "KeyFlw"; - case 27: return "Random"; - default: return juce::String(v); - } - } - - juce::String numToModMatrixDest(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return "Off"; - case 1: return "PatchVol"; - case 2: return "ChannelVol"; - case 3: return "Panorama"; - case 4: return "Transpose"; - case 5: return "Portamento"; - case 6: return "Osc1Shape"; - case 7: return "Osc1PlsWdh"; - case 8: return "Osc1WavSel"; - case 9: return "Osc1Pitch"; - case 10: return "Osc1Keyflw"; - case 11: return "Osc2Shape"; - case 12: return "Osc2PlsWdh"; - case 13: return "Osc2WavSel"; - case 14: return "Osc2Pitch"; - case 15: return "Osc2Detune"; - case 16: return "Osc2FmAmt"; - case 17: return "Osc2EnvAmt"; - case 18: return "FmEnvAmt"; - case 19: return "Osc2Keyflw"; - case 20: return "OscBalance"; - case 21: return "SubOscVol"; - case 22: return "OscMainVol"; - case 23: return "NoiseVol"; - case 24: return "Cutoff"; - case 25: return "Cutoff2"; - case 26: return "Filt1Reso"; - case 27: return "Filt2Reso"; - case 28: return "Flt1EnvAmt"; - case 29: return "Flt2EnvAmt"; - case 30: return "Flt1Keyflw"; - case 31: return "Flt2Keyflw"; - case 32: return "FltBalance"; - case 33: return "FltAttack"; - case 34: return "FltDecay"; - case 35: return "FltSustain"; - case 36: return "FltSusTime"; - case 37: return "FltRelease"; - case 38: return "AmpAttack"; - case 39: return "AmpDecay"; - case 40: return "AmpSustain"; - case 41: return "AmpSusTime"; - case 42: return "AmpRelease"; - case 43: return "Lfo1Rate"; - case 44: return "Lfo1Cont"; - case 45: return "Lfo1>Osc1"; - case 46: return "Lfo1>Osc2"; - case 47: return "Lfo1>PlsWd"; - case 48: return "Lfo1>Reso"; - case 49: return "Lfo1>FltGn"; - case 50: return "Lfo2Rate"; - case 51: return "Lfo2Cont"; - case 52: return "Lfo2>Shape"; - case 53: return "Lfo2>Fm"; - case 54: return "Lfo2>Cut1"; - case 55: return "Lfo2>Cut2"; - case 56: return "Lfo2>Pan"; - case 57: return "Lfo3Rate"; - case 58: return "Lfo3OscAmt"; - case 59: return "UniDetune"; - case 60: return "UniSpread"; - case 61: return "UniLfoPhs"; - case 62: return "ChorusMix"; - case 63: return "ChorusRate"; - case 64: return "ChorusDpth"; - case 65: return "ChorusDly"; - case 66: return "ChorusFeed"; - case 67: return "EffectSend"; - case 68: return "DelayTime"; - case 69: return "DelayFeed"; - case 70: return "DelayRate"; - case 71: return "DelayDepth"; - case 72: return "Osc1ShpVel"; - case 73: return "Osc2ShpVel"; - case 74: return "PlsWhdVel"; - case 75: return "FmAmtVel"; - case 76: return "Flt1EnvVel"; - case 77: return "Flt2EnvVel"; - case 78: return "Reso1Vel"; - case 79: return "Reso2Vel"; - case 80: return "AmpVel"; - case 81: return "PanVel"; - case 82: return "Ass1Amt1"; - case 83: return "Ass2Amt1"; - case 84: return "Ass2Amt2"; - case 85: return "Ass3Amt1"; - case 86: return "Ass3Amt2"; - case 87: return "Ass3Amt3"; - case 88: return "OscInitPhs"; - case 89: return "PunchInt"; - case 90: return "RingMod"; - case 91: return "NoiseColor"; - case 92: return "DelayColor"; - case 93: return "ABoostInt"; - case 94: return "ABoostTune"; - case 95: return "DistInt"; - case 96: return "RingmodMix"; - case 97: return "Osc3Volume"; - case 98: return "Osc3Semi"; - case 99: return "Osc3Detune"; - case 100: return "Lfo1AssAmt"; - case 101: return "Lfo2AssAmt"; - case 102: return "PhaserMix"; - case 103: return "PhaserRate"; - case 104: return "PhaserDept"; - case 105: return "PhaserFreq"; - case 106: return "PhaserFdbk"; - case 107: return "PhaserSprd"; - case 108: return "RevbDecay"; - case 109: return "RevDamping"; - case 110: return "RevbColor"; - case 111: return "RevPredely"; - case 112: return "RevFeedbck"; - case 113: return "SecBalance"; - case 114: return "ArpNoteLen"; - case 115: return "ArpSwing"; - case 116: return "ArpPattern"; - case 117: return "EqMidGain"; - case 118: return "EqMidFreq"; - case 119: return "EqMidQFactor"; - case 120: return "Assign4Amt"; - case 121: return "Assign5Amt"; - case 122: return "Assign6Amt"; - default: return juce::String(v); - } - } - - juce::String numToSoftKnobDest(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return "Off"; - case 1: return "ModWheel"; - case 2: return "Breath"; - case 3: return "Contr3"; - case 4: return "Foot"; - case 5: return "Data"; - case 6: return "Balance"; - case 7: return "Contr9"; - case 8: return "Expression"; - case 9: return "Contr12"; - case 10: return "Contr13"; - case 11: return "Contr14"; - case 12: return "Contr15"; - case 13: return "Contr16"; - case 14: return "PatchVolume"; - case 15: return "ChannelVolume"; - case 16: return "Panorama"; - case 17: return "Transpose"; - case 18: return "Portamento"; - case 19: return "UnisonDetune"; - case 20: return "UnisonPanSprd"; - case 21: return "UnisoLfoPhase"; - case 22: return "ChorusMix"; - case 23: return "ChorusRate"; - case 24: return "ChorusDepth"; - case 25: return "ChorusDelay"; - case 26: return "ChorusFeedback"; - case 27: return "EffectSend"; - case 28: return "DelayTime(ms)"; - case 29: return "DelayFeedback"; - case 30: return "DelayRate"; - case 31: return "DelayDepth"; - case 32: return "Osc1WavSelect"; - case 33: return "Osc1PulseWidth"; - case 34: return "Osc1Semitone"; - case 35: return "Osc1Keyfollow"; - case 36: return "Osc2WavSelect"; - case 37: return "Os2PulseWidth"; - case 38: return "Osc2EnvAmount"; - case 39: return "FmEnvAmount"; - case 40: return "Osc2Keyfollow"; - case 41: return "NoiseVolume"; - case 42: return "Filt1Resonance"; - case 43: return "Filt2Resonance"; - case 44: return "Filt1EnvAmount"; - case 45: return "Filt2EnvAmount"; - case 46: return "Filt1Keyfollow"; - case 47: return "Filt2Keyfollow"; - case 48: return "Lfo1Symmetry"; - case 49: return "Lfo1>Osc1"; - case 50: return "Lfo1>Osc2"; - case 51: return "Lfo1>PulsWidth"; - case 52: return "Lfo1>Resonance"; - case 53: return "Lfo1>FiltGain"; - case 54: return "Lfo2Symmetry"; - case 55: return "Lfo2>Shape"; - case 56: return "Lfo2>FmAmount"; - case 57: return "Lfo2>Cutoff1"; - case 58: return "Lfo2>Cutoff2"; - case 59: return "Lfo2>Panorama"; - case 60: return "Lfo3Rate"; - case 61: return "Lfo3OscAmount"; - case 62: return "Osc1ShapeVel"; - case 63: return "Osc2ShapeVel"; - case 64: return "PulsWidthVel"; - case 65: return "FmAmountVel"; - case 66: return "Filt1EnvVel"; - case 67: return "Filt2EnvVel"; - case 68: return "Resonance1Vel"; - case 69: return "Resonance2Vel"; - case 70: return "AmplifierVel"; - case 71: return "PanoramaVel"; - case 72: return "Assign1Amt1"; - case 73: return "Assign2Amt1"; - case 74: return "Assign2Amt2"; - case 75: return "Assign3Amt1"; - case 76: return "Assign3Amt2"; - case 77: return "Assign3Amt3"; - case 78: return "ClockTempo"; - case 79: return "InputThru"; - case 80: return "OscInitPhase"; - case 81: return "PunchIntensity"; - case 82: return "Ringmodulator"; - case 83: return "NoiseColor"; - case 84: return "DelayColor"; - case 85: return "AnalogBoostInt"; - case 86: return "AnalogBstTune"; - case 87: return "DistortionInt"; - case 88: return "RingModMix"; - case 89: return "Osc3Volume"; - case 90: return "Osc3Semitone"; - case 91: return "Osc3Detune"; - case 92: return "Lfo1AssignAmt"; - case 93: return "Lfo2AssignAmt"; - case 94: return "PhaserMix"; - case 95: return "PhaserRate"; - case 96: return "PhaserDepth"; - case 97: return "PhaserFrequency"; - case 98: return "PhaserFeedback"; - case 99: return "PhaserSpread"; - case 100: return "RevDecayTime"; - case 101: return "ReverbDamping"; - case 102: return "ReverbColor"; - case 103: return "ReverbFeedback"; - case 104: return "SecondBalance"; - case 105: return "ArpMode"; - case 106: return "ArpPattern"; - case 107: return "ArpClock"; - case 108: return "ArpNoteLength"; - case 109: return "ArpSwing"; - case 110: return "ArpOctaves"; - case 111: return "ArpHold"; - case 112: return "EqMidGain"; - case 113: return "EqMidFreq"; - case 114: return "EqMidQFactor"; - case 115: return "Assign4Amt"; - case 116: return "Assign5Amt"; - case 117: return "Assign6Amt"; - default: return juce::String(v); - } - } - - juce::String numToSoftKnobName(float idx, const Parameter::Description&) { - const char *softKnobNames[] = { "~Para","+3rds","+4ths","+5ths", - "+7ths","+Octave","Access","ArpMode","ArpOct","Attack", - "Balance","Chorus","Cutoff","Decay","Delay","Depth", - "Destroy","Detune","Disolve","Distort","Dive","Effects", - "Elevate","Energy","EqHigh","EqLow","EqMid","Fast","Fear", - "Filter","FM","Glide","Hold","Hype","Infect","Length","Mix", - "Morph","Mutate","Noise","Open","Orbit","Pan","Phaser","Phatter", - "Pitch","Pulsate","Push","PWM","Rate","Release","Reso","Reverb", - "Scream","Shape","Sharpen","Slow","Soften","Speed","SubOsc", - "Sustain","Sweep","Swing","Tempo","Thinner","Tone","Tremolo", - "Vibrato","WahWah","Warmth","Warp","Width" }; - const auto ridx = juce::roundToInt(idx); - if (ridx < sizeof(softKnobNames) - 1) { - return softKnobNames[ridx]; - } - return juce::String(idx); - } - - juce::String numToUnisonMode(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Twin"; - case 2: return "3"; - case 3: return "4"; - case 4: return "5"; - case 5: return "6"; - case 6: return "7"; - case 7: return "8"; - case 8: return "9"; - case 9: return "10"; - case 10: return "11"; - case 11: return "12"; - case 12: return "13"; - case 13: return "14"; - case 14: return "15"; - case 15: return "16"; - default: return juce::String(v); - } - } - - juce::String filterKeytrackBase(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return "C-1"; - case 1: return "C#-1"; - case 2: return "D-1"; - case 3: return "D#-1"; - case 4: return "E-1"; - case 5: return "F-1"; - case 6: return "F#-1"; - case 7: return "G-1"; - case 8: return "G#-1"; - case 9: return "A-1"; - case 10: return "A#-1"; - case 11: return "B-1"; - case 12: return "C0"; - case 13: return "C#0"; - case 14: return "D0"; - case 15: return "D#0"; - case 16: return "E0"; - case 17: return "F0"; - case 18: return "F#0"; - case 19: return "G0"; - case 20: return "G#0"; - case 21: return "A0"; - case 22: return "A#0"; - case 23: return "B0"; - case 24: return "C1"; - case 25: return "C#1"; - case 26: return "D1"; - case 27: return "D#1"; - case 28: return "E1"; - case 29: return "F1"; - case 30: return "F#1"; - case 31: return "G1"; - case 32: return "G#1"; - case 33: return "A1"; - case 34: return "A#1"; - case 35: return "B1"; - case 36: return "C2"; - case 37: return "C#2"; - case 38: return "D2"; - case 39: return "D#2"; - case 40: return "E2"; - case 41: return "F2"; - case 42: return "F#2"; - case 43: return "G2"; - case 44: return "G#2"; - case 45: return "A2"; - case 46: return "A#2"; - case 47: return "B2"; - case 48: return "C3"; - case 49: return "C#3"; - case 50: return "D3"; - case 51: return "D#3"; - case 52: return "E3"; - case 53: return "F3"; - case 54: return "F#3"; - case 55: return "G3"; - case 56: return "G#3"; - case 57: return "A3"; - case 58: return "A#3"; - case 59: return "B3"; - case 60: return "C4"; - case 61: return "C#4"; - case 62: return "D4"; - case 63: return "D#4"; - case 64: return "E4"; - case 65: return "F4"; - case 66: return "F#4"; - case 67: return "G4"; - case 68: return "G#4"; - case 69: return "A4"; - case 70: return "A#4"; - case 71: return "B4"; - case 72: return "C5"; - case 73: return "C#5"; - case 74: return "D5"; - case 75: return "D#5"; - case 76: return "E5"; - case 77: return "F5"; - case 78: return "F#5"; - case 79: return "G5"; - case 80: return "G#5"; - case 81: return "A5"; - case 82: return "A#5"; - case 83: return "B5"; - case 84: return "C6"; - case 85: return "C#6"; - case 86: return "D6"; - case 87: return "D#6"; - case 88: return "E6"; - case 89: return "F6"; - case 90: return "F#6"; - case 91: return "G6"; - case 92: return "G#6"; - case 93: return "A6"; - case 94: return "A#6"; - case 95: return "B6"; - case 96: return "C7"; - case 97: return "C#7"; - case 98: return "D7"; - case 99: return "D#7"; - case 100: return "E7"; - case 101: return "F7"; - case 102: return "F#7"; - case 103: return "G7"; - case 104: return "G#7"; - case 105: return "A7"; - case 106: return "A#7"; - case 107: return "B7"; - case 108: return "C8"; - case 109: return "C#8"; - case 110: return "D8"; - case 111: return "D#8"; - case 112: return "E8"; - case 113: return "F8"; - case 114: return "F#8"; - case 115: return "G8"; - case 116: return "G#8"; - case 117: return "A8"; - case 118: return "A#8"; - case 119: return "B8"; - case 120: return "C9"; - case 121: return "C#9"; - case 122: return "D9"; - case 123: return"D#9"; - case 124: return "E9"; - case 125: return "F9"; - case 126: return "F#9"; - case 127: return "G9"; - default: return juce::String(v); - } - } - - juce::String numToOscFmMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Pos-Tri"; - case 1: return "Tri"; - case 2: return "Wave"; - case 3: return "Noise"; - case 4: return "In L"; - case 5: return "In L+R"; - case 6: return "In R"; - case 7: return "Aux1 L"; - case 8: return "Aux1 L+R"; - case 9: return "Aux1 R"; - case 10: return "Aux2 L"; - case 11: return "Aux2 L+R"; - case 12: return "Aux2 R"; - default: return juce::String(idx); - } - } - - juce::String numToVocoderMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "Oscillator"; - case 2: return "Osc Hold"; - case 3: return "Noise"; - case 4: return "In L"; - case 5: return "In L+R"; - case 6: return "In R"; - case 7: return "Aux1 L"; - case 8: return "Aux1 L+R"; - case 9: return "Aux1 R"; - case 10: return "Aux2 L"; - case 11: return "Aux2 L+R"; - case 12: return "Aux2 R"; - default: return juce::String(idx); - } - } - - juce::String numToInputFollowerMode(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "In L"; - case 2: return "In L+R"; - case 3: return "In R"; - case 4: return "Aux1 L"; - case 5: return "Aux1 L+R"; - case 6: return "Aux1 R"; - case 7: return "Aux2 L"; - case 8: return "Aux2 L+R"; - case 9: return "Aux2 R"; - default: return juce::String(idx); - } - } - - juce::String numToMusicDivision(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Off"; - case 1: return "1/64"; - case 2: return "1/32"; - case 3: return "1/16"; - case 4: return "1/8"; - case 5: return "1/4"; - case 6: return "1/2"; - case 7: return "3/64"; - case 8: return "3/32"; - case 9: return "3/16"; - case 10: return "3/8"; - case 11: return "1/24"; - case 12: return "1/12"; - case 13: return "1/6"; - case 14: return "1/3"; - case 15: return "2/3"; - case 16: return "3/4"; - case 17: return "1/1"; - case 18: return "2/1"; - case 19: return "4/1"; - case 20: return "8/1"; - case 21: return "16/1"; - default: return juce::String(idx); - } - } - - juce::String numToPhaserMode(float v, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(v); - switch (ridx) - { - case 0: return ""; - case 1: return "1 Stage"; - case 2: return "2 Stages"; - case 3: return "3 Stages"; - case 4: return "4 Stages"; - case 5: return "5 Stages"; - case 6: return "6 Stages"; - default: return juce::String(v); - } - } - - juce::String numToFilterSelect(float idx, const Parameter::Description&) - { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 0: return "Filter 1"; - case 1: return "Filter 2"; - case 2: return "Filter 1+2"; - default: return juce::String(idx); - } - } - - juce::String numToCategory(float idx, const Parameter::Description&) - { - const juce::Array<juce::String> categories = { "--", "Lead", "Bass", "Pad", "Decay", "Pluck", - "Acid", "Classic", "Arpeggiator", "Effects", "Drums", "Percussion", - "Input", "Vocoder", "Favourite 1", "Favourite 2", "Favourite 3" }; - - const auto ridx = juce::roundToInt(idx); - if (ridx < categories.size()) - return categories[ridx]; - return "Undefined"; - } - - juce::String numToBendRange(float idx, const Parameter::Description&) { - const auto ridx = juce::roundToInt(idx); - switch (ridx) - { - case 40: return "-2oct"; - case 52: return "-1oct"; - case 57: return "-7st"; - case 58: return "-6st"; - case 59: return "-5st"; - case 60: return "-4st"; - case 61: return "-3st"; - case 62: return "-2st"; - case 63: return "-1st"; - case 64: return "None"; - case 65: return "+1st"; - case 66: return "+2st"; - case 67: return "+3st"; - case 68: return "+4st"; - case 69: return "+5st"; - case 70: return "+6st"; - case 71: return "+7st"; - case 76: return "+1oct"; - case 88: return "+2oct"; - default: return juce::String(""); - } - } - juce::String numToReverbRoomSize(float idx, const Parameter::Description&) { - const auto ridx = juce::roundToInt(idx); - - switch (ridx) { - case 0: return "Ambience"; - case 1: return "Small Room"; - case 2: return "Large Room"; - case 3: return "Hall"; - default: return juce::String(""); - } - } - - const std::initializer_list<Parameter::Description> g_paramsDescription = - { - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 0, "Version", {0, 12}, numToBank, {}, false, true, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 1, "Modulation Wheel", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 2, "Breath Controller", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 3, "Contr 3", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 4, "Foot Controller", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 5, "Portamento Time", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 6, "Data Slider", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 7, "Channel Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 8, "Balance", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 9, "Contr 9", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 10, "Panorama", {0,127}, numToPan,{}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 11, "Expression", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 12, "Contr 12", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 13, "Contr 13", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 14, "Contr 14", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 15, "Contr 15", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 16, "Contr 16", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 17, "Osc1 Shape", {0,127}, numToOscShape,{}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 18, "Osc1 Pulsewidth", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 19, "Osc1 Wave Select", {0,63}, numToOscWaveSelect, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 20, "Osc1 Semitone", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 21, "Osc1 Keyfollow", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 22, "Osc2 Shape", {0,127}, numToOscShape, {}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 23, "Osc2 Pulsewidth", {0,127}, {}, {}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 24, "Osc2 Wave Select", {0,63}, numToOscWaveSelect,{}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 25, "Osc2 Semitone", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 26, "Osc2 Detune", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 27, "Osc2 FM Amount", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 28, "Osc2 Sync", {0,1}, {},{}, true, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 29, "Osc2 Filt Env Amt", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 30, "FM Filt Env Amt", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 31, "Osc2 Keyfollow", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 32, "Bank Select", {0, 8}, numToBank,{}, false, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 33, "Osc Balance", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 34, "Suboscillator Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 35, "Suboscillator Shape", {0,1}, [](float v, const Parameter::Description&) { return juce::roundToInt(v) == 0 ? "Square" : "Triangle"; },{}, true, true, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 36, "Osc Mainvolume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 37, "Noise Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 38, "Ringmodulator Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::VIRUS_C, 39, "Noise Color", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 40, "Cutoff", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 41, "Cutoff2", {0,127}, {},{}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 42, "Filter1 Resonance", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 43, "Filter2 Resonance", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 44, "Filter1 Env Amt", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 45, "Filter2 Env Amt", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 46, "Filter1 Keyfollow", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 47, "Filter2 Keyfollow", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 48, "Filter Balance", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 49, "Saturation Curve", {0,14}, numToSatCurv, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 51, "Filter1 Mode", {0,7}, numToFilterMode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 52, "Filter2 Mode", {0,3}, numToFilter2Mode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 53, "Filter Routing", {0,3}, numToFilterRouting, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 54, "Filter Env Attack", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 55, "Filter Env Decay", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 56, "Filter Env Sustain", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 57, "Filter Env Sustain Time", {0,127}, numToEnvSusTime, {}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 58, "Filter Env Release", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 59, "Amp Env Attack", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 60, "Amp Env Decay", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 61, "Amp Env Sustain", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 62, "Amp Env Sustain Time", {0,127}, numToEnvSusTime, {}, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 63, "Amp Env Release", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 64, "Hold Pedal", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 65, "Portamento Pedal", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::PERFORMANCE_CONTROLLER, 66, "Sostenuto Pedal", {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 67, "Lfo1 Rate", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 68, "Lfo1 Shape", {0,67}, numToLfoShape, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 69, "Lfo1 Env Mode", {0,1}, {},{}, true, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 70, "Lfo1 Mode", {0,1}, numToLfoMode, {}, true, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 71, "Lfo1 Symmetry", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 72, "Lfo1 Keyfollow", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 73, "Lfo1 Keytrigger", {0,127}, {}, {}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 74, "Osc1 Lfo1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 75, "Osc2 Lfo1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 76, "PW Lfo1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 77, "Reso Lfo1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 78, "FiltGain Lfo1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 79, "Lfo2 Rate", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 80, "Lfo2 Shape", {0,67}, numToLfoShape,{}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 81, "Lfo2 Env Mode", {0,1}, {},{}, true, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 82, "Lfo2 Mode", {0,1}, numToLfoMode, {}, true, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 83, "Lfo2 Symmetry", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 84, "Lfo2 Keyfollow", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 85, "Lfo2 Keytrigger", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 86, "Shape Lfo2 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 87, "FM Lfo2 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 88, "Cutoff1 Lfo2 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 89, "Cutoff2 Lfo2 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 90, "Pan Lfo2 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 91, "Patch Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 93, "Transpose", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 94, "Key Mode", {0,5}, numToKeyMode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 97, "Unison Mode", {0,15}, numToUnisonMode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 98, "Unison Detune", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 99, "Unison Pan Spread", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 100, "Unison Lfo Phase", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 101, "Input Mode", {0,3}, numToInputMode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 102, "Input Select", {0,8}, numToInputSelect,{}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 105, "Chorus Mix", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 106, "Chorus Rate", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 107, "Chorus Depth", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 108, "Chorus Delay", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 109, "Chorus Feedback", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A, 110, "Chorus Lfo Shape", {0,67}, numToLfoShape, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE, 112, "Delay/Reverb Mode", {0,26}, numToDelayReverbMode, {}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE, 113, "Effect Send", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 114, "Delay Time", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 115, "Delay Feedback", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 116, "Dly Rate / Rev Decay", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 117, "Dly Depth / Rev Size", {0,127}, numToReverbRoomSize,{}, true, true, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 118, "Delay Lfo Shape", {0,127}, numToDelayLfoShape, {}, true, true, false}, - // {Parameter::Page::A, Parameter::Class::SOUNDBANK_A|Parameter::Class::MULTI_OR_SINGLE|Parameter::Class::NON_PART_SENSITIVE, 118, "Reverb Damping", {0,127}, {},{}, true, false, false}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 119, "Delay Color", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 122, "Keyb Local", {0,1}, {},{}, false, false, true}, - {Parameter::Page::A, Parameter::Class::SOUNDBANK_A | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 123, "All Notes Off", {0,127}, {},{}, false, false, false}, - - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 1, "Arp Mode", {0,6}, numToArpMode, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 2, "Arp Pattern Selct", {0,63}, numToNumPlusOne, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 3, "Arp Octave Range", {0,3}, numToNumPlusOne,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 4, "Arp Hold Enable", {0,1}, {},{}, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 5, "Arp Note Length", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 6, "Arp Swing", {0,127}, numToArpSwing, {}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 7, "Lfo3 Rate", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 8, "Lfo3 Shape", {0,67}, numToLfoShape, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 9, "Lfo3 Mode", {0,1}, numToLfoMode, {}, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 10, "Lfo3 Keyfollow", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 11, "Lfo3 Destination", {0,5}, numToLfoDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 12, "Osc Lfo3 Amount", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 13, "Lfo3 Fade-In Time", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 16, "Clock Tempo", {0,127}, numToClockTempo, {}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 17, "Arp Clock", {0,17}, numToMusicDivision, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 18, "Lfo1 Clock", {0,21}, numToMusicDivision, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 19, "Lfo2 Clock", {0,21}, numToMusicDivision, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::MULTI_OR_SINGLE | Parameter::Class::NON_PART_SENSITIVE, 20, "Delay Clock", {0,16}, numToMusicDivision, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 21, "Lfo3 Clock", {0,21}, numToMusicDivision, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 25, "Control Smooth Mode", {0,3}, numToControlSmoothMode,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 26, "Bender Range Up", {0,127}, numToBendRange, {}, true, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 27, "Bender Range Down", {0,127}, numToBendRange, {}, true, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 28, "Bender Scale", {0,1}, numToLinExp, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 30, "Filter1 Env Polarity", {0,1}, numToNegPos, {}, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 31, "Filter1 Env Polarity", {0,1}, numToNegPos, {}, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 32, "Filter2 Cutoff Link", {0,1}, {},{}, true, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 33, "Filter Keytrack Base", {0,127}, filterKeytrackBase,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 34, "Osc FM Mode", {0,12}, numToOscFmMode,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 35, "Osc Init Phase", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 36, "Punch Intensity", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 38, "Input Follower Mode", {0,9}, numToInputFollowerMode, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 39, "Vocoder Mode", {0,12}, numToVocoderMode,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 41, "Osc3 Mode", {0,67}, numToOsc3Mode,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 42, "Osc3 Volume", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 43, "Osc3 Semitone", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 44, "Osc3 Detune", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 45, "LowEQ Frequency", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 46, "HighEQ Frequency", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 47, "Osc1 Shape Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 48, "Osc2 Shape Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 49, "PulseWidth Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 50, "Fm Amount Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 51, "Soft Knob1 ShortName", {0,71}, numToSoftKnobName,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 52, "Soft Knob2 ShortName", {0,71}, numToSoftKnobName,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 54, "Flt1 EnvAmt Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 55, "Flt2 EnvAmt Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 56, "Resonance1 Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 57, "Resonance2 Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 58, "Second Output Balance", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 60, "Amp Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 61, "Panorama Velocity", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 62, "Soft Knob-1 Single", {0,117}, numToSoftKnobDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 63, "Soft Knob-2 Single", {0,117}, numToSoftKnobDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 64, "Assign1 Source", {0,27}, numToModMatrixSource, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 65, "Assign1 Destination", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 66, "Assign1 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 67, "Assign2 Source", {0,27}, numToModMatrixSource,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 68, "Assign2 Destination1", {0,122}, numToModMatrixDest,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 69, "Assign2 Amount1", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 70, "Assign2 Destination2", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 71, "Assign2 Amount2", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 72, "Assign3 Source", {0,27}, numToModMatrixSource, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 73, "Assign3 Destination1", {0,122}, numToModMatrixDest,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 74, "Assign3 Amount1", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 75, "Assign3 Destination2", {0,122}, numToModMatrixDest,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 76, "Assign3 Amount2", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 77, "Assign3 Destination3", {0,122}, numToModMatrixDest,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 78, "Assign3 Amount3", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 79, "LFO1 Assign Dest", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 80, "LFO1 Assign Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 81, "LFO2 Assign Dest", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 82, "LFO2 Assign Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 84, "Phaser Mode", {0,6}, numToPhaserMode, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 85, "Phaser Mix", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 86, "Phaser Rate", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 87, "Phaser Depth", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 88, "Phaser Frequency", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 89, "Phaser Feedback", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 90, "Phaser Spread", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 92, "MidEQ Gain", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 93, "MidEQ Frequency", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 94, "MidEQ Q-Factor", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 95, "LowEQ Gain", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 96, "HighEQ Gain", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 97, "Bass Intensity", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 98, "Bass Tune", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 99, "Input Ringmodulator", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 100, "Distortion Curve", {0,11}, numToDistortionCurv,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 101, "Distortion Intensity", {0,127}, {},{}, true, false, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 103, "Assign 4 Source", {0,27}, numToModMatrixSource,{}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 104, "Assign 4 Destination", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 105, "Assign 4 Amount", {0,127}, {},{}, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 106, "Assign 5 Source", {0,27}, numToModMatrixSource, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 107, "Assign 5 Destination", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 108, "Assign 5 Amount", {0,127}, paramTo7bitSigned, textTo7bitSigned, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 109, "Assign 6 Source", {0,27}, numToModMatrixSource, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 110, "Assign 6 Destination", {0,122}, numToModMatrixDest, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 111, "Assign 6 Amount", {0,127}, paramTo7bitSigned, {}, true, false, false, true}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B | Parameter::Class::VIRUS_C, 122, "Filter Select", {0,2}, numToFilterSelect, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 123, "Category1", {0,16}, numToCategory, {}, true, true, false}, - {Parameter::Page::B, Parameter::Class::SOUNDBANK_B, 124, "Category2", {0,16}, numToCategory, {}, true, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM | Parameter::Class::NON_PART_SENSITIVE, 22, "Delay Output Select", {0,14}, numToOutputSelect, {}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM | Parameter::Class::BANK_PROGRAM_CHANGE_PARAM_BANK_SELECT, 31, "Part Bank Select", {0, 3 + 26}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM | Parameter::Class::BANK_PROGRAM_CHANGE_PARAM_BANK_SELECT, 32, "Part Bank Change", {0, 3 + 26}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM | Parameter::Class::BANK_PROGRAM_CHANGE_PARAM_BANK_SELECT, 33, "Part Program Change", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 34, "Part Midi Channel", {0,15}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 35, "Part Low Key", {0,127}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 36, "Part High Key", {0,127}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 37, "Part Transpose", {0,127}, paramTo7bitSigned, textTo7bitSigned, false, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 38, "Part Detune", {0,127}, paramTo7bitSigned, textTo7bitSigned, false, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 39, "Part Volume", {0,127}, paramTo7bitSigned,textTo7bitSigned, true, false, false, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 40, "Part Midi Volume Init", {0,127}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 41, "Part Output Select", {0,14}, numToOutputSelect,{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 45, "Second Output Select", {0,15}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 63, "Keyb Transpose Buttons", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 64, "Keyb Local", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 65, "Keyb Mode", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 66, "Keyb Transpose", {0,127}, paramTo7bitSigned, textTo7bitSigned, false, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 67, "Keyb ModWheel Contr", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 68, "Keyb Pedal 1 Contr", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 69, "Keyb Pedal 2 Contr", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 70, "Keyb Pressure Sens", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 72, "Part Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 73, "Part Midi Volume Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 74, "Part Hold Pedal Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 75, "Keyb To Midi", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 77, "Note Steal Priority", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::MULTI_PARAM, 78, "Part Prog Change Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 85, "Glob Prog Change Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 86, "MultiProg Change Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 87, "Glob Midi Volume Enable", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 90, "Input Thru Level", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 91, "Input Boost", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 92, "Master Tune", {0,127}, paramTo7bitSigned, textTo7bitSigned, false, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 93, "Device ID", {0,16}, {},{}, true, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 94, "Midi Control Low Page", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 95, "Midi Control High Page", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 96, "Midi Arpeggiator Send", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 97, "Knob Display", {0,3}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 98, "Midi Dump Tx", {0,4}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 99, "Midi Dump Rx", {0,4}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 105, "Multi Program Change", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 106, "Midi Clock Rx", {0,3}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 110, "Soft Knob-1 Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 111, "Soft Knob-2 Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 112, "Soft Knob-1 Global", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 113, "Soft Knob-2 Global", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 114, "Soft Knob-1 Midi", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 115, "Soft Knob-2 Midi", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 116, "Expert Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 117, "Knob Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 118, "Memory Protect", {0,1}, {},{}, false, false, true}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 120, "Soft Thru", {0,1}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 121, "Panel Destination", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 122, "Play Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 123, "Part Number", {0,127}, {},{}, false, true, false}, // 0..15;40 - {Parameter::Page::C, Parameter::Class::GLOBAL, 124, "Global Channel", {0,15}, {},{}, true, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 125, "Led Mode", {0,2}, {},{}, false, true, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 126, "LCD Contrast", {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::GLOBAL, 127, "Master Volume", {0,127}, {},{}, false, false, false}, - - // UNDEFINED / UNUSED / STUBS - {Parameter::Page::A, Parameter::Class::UNDEFINED, 92, {"Undefined92"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 95, {"Undefined95"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 96, {"Undefined96"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 111, {"Undefined111"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 120, {"Undefined120"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 121, {"Undefined121"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 124, {"Undefined124"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 125, {"Undefined125"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 126, {"Undefined126"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::A, Parameter::Class::UNDEFINED, 127, {"Undefined127"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 0, {"Undefined0"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 14, {"Undefined14"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 15, {"Undefined15"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 22, {"Undefined22"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 23, {"Undefined23"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 24, {"Undefined24"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 29, {"Undefined29"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 37, {"Undefined37"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 40, {"Undefined40"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 53, {"Undefined53"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 69, {"Undefined69"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 83, {"Undefined83"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 91, {"Undefined91"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 111, {"Undefined111"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 123, {"Undefined123"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 124, {"Undefined124"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 0, {"Undefined0"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 1, {"Undefined1"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 2, {"Undefined2"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 3, {"Undefined3"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 4, {"Undefined4"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 15, {"Undefined15"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 16, {"Undefined16"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 17, {"Undefined17"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 18, {"Undefined18"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 19, {"Undefined19"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 20, {"Undefined20"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 21, {"Undefined21"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 23, {"Undefined23"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 24, {"Undefined24"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 25, {"Undefined25"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 26, {"Undefined26"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 27, {"Undefined27"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 28, {"Undefined28"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 29, {"Undefined29"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 30, {"Undefined30"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 76, {"Undefined76"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 79, {"Undefined79"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 80, {"Undefined80"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 81, {"Undefined81"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 82, {"Undefined82"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 83, {"Undefined83"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 84, {"Undefined84"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 88, {"Undefined88"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 89, {"Undefined89"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 100, {"Undefined100"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 101, {"Undefined101"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 102, {"Undefined102"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 103, {"Undefined103"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 104, {"Undefined104"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 119, {"Undefined119"}, {0,127}, {},{}, false, false, false}, - // Text Chars / Unused - {Parameter::Page::B, Parameter::Class::UNDEFINED, 110, {"Undefined110"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 111, {"Undefined111"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 112, {"Undefined112"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 113, {"Undefined113"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 114, {"Undefined114"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 115, {"Undefined115"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 116, {"Undefined116"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 117, {"Undefined117"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 118, {"Undefined118"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 119, {"Undefined119"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 120, {"Undefined120"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::B, Parameter::Class::UNDEFINED, 121, {"Undefined121"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 5, {"Undefined5"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 6, {"Undefined6"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 7, {"Undefined7"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 8, {"Undefined8"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 9, {"Undefined9"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 10, {"Undefined10"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 11, {"Undefined11"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 12, {"Undefined12"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 13, {"Undefined13"}, {0,127}, {},{}, false, false, false}, - {Parameter::Page::C, Parameter::Class::UNDEFINED, 14, {"Undefined14"}, {0,127}, {},{}, false, false, false} - // TODO: B51-52 shortname?!? B54-B55 (same name?!) - }; -} -\ No newline at end of file +} diff --git a/source/jucePlugin/VirusParameterDescription.h b/source/jucePlugin/VirusParameterDescription.h @@ -1,6 +1,11 @@ #pragma once -#include "VirusParameter.h" +#include <cstdint> +#include <functional> + +#include <juce_audio_processors/juce_audio_processors.h> + +#include "../../virusLib/microcontrollerTypes.h" namespace Virus { @@ -373,5 +378,39 @@ namespace Virus Param_Count }; - extern const std::initializer_list<Virus::Parameter::Description> g_paramsDescription; + struct ValueList + { + std::vector<std::string> texts; + std::map<std::string, uint32_t> textToValueMap; + + uint32_t textToValue(const std::string& _string) const + { + const auto it = textToValueMap.find(_string); + if (it != textToValueMap.end()) + return it->second; + return 0; + } + + const std::string& valueToText(const uint32_t _value) const + { + if (_value >= texts.size()) + return texts.back(); + return texts[_value]; + } + }; + + struct Description + { + virusLib::Page page; + int classFlags; + uint8_t index; + juce::String name; + juce::Range<int> range; + ValueList valueList; + bool isPublic; + bool isDiscrete; + bool isBool; + bool isBipolar; + std::string toText; + }; } diff --git a/source/jucePlugin/VirusParameterDescriptions.cpp b/source/jucePlugin/VirusParameterDescriptions.cpp @@ -1,7 +1,5 @@ #include "VirusParameterDescriptions.h" -#include <cassert> - #include "VirusParameter.h" #include "VirusParameterDescription.h" @@ -77,19 +75,26 @@ namespace Virus const auto key = std::string(entryProps.getName(i).toString().toUTF8()); const auto values = entryProps.getValueAt(i).getArray(); - if(m_valueList.find(key) != m_valueList.end()) + if(m_valueLists.find(key) != m_valueLists.end()) return "value list " + key + " is defined twice"; if(!values || values->isEmpty()) return std::string("value list ") + key + " is not a valid array of strings"; - std::vector<std::string> stringList; - stringList.reserve(values->size()); + ValueList vl; + vl.texts.reserve(values->size()); for (auto&& value : *values) - stringList.push_back(static_cast<std::string>(value.toString().toUTF8())); + { + const auto text = static_cast<std::string>(value.toString().toUTF8()); + + if (vl.textToValueMap.find(text) == vl.textToValueMap.end()) + vl.textToValueMap.insert(std::make_pair(text, static_cast<uint32_t>(vl.texts.size()))); + + vl.texts.push_back(text); + } - m_valueList.insert(std::make_pair(key, stringList)); + m_valueLists.insert(std::make_pair(key, vl)); } } @@ -182,8 +187,8 @@ namespace Virus const auto valueList = readPropertyString("toText"); - const auto it = m_valueList.find(valueList); - if(it == m_valueList.end()) + const auto it = m_valueLists.find(valueList); + if(it == m_valueLists.end()) { errors << name << ": Value list " << valueList << " not found" << std::endl; continue; @@ -191,12 +196,12 @@ namespace Virus const auto& list = *it; - if((maxValue - minValue + 1) > static_cast<int>(list.second.size())) + if((maxValue - minValue + 1) > static_cast<int>(list.second.texts.size())) { - errors << name << ": value list " << valueList << " contains only " << list.second.size() << " entries but parameter range is " << minValue << "-" << maxValue << std::endl; + errors << name << ": value list " << valueList << " contains only " << list.second.texts.size() << " entries but parameter range is " << minValue << "-" << maxValue << std::endl; } - Parameter::Description d; + Description d; d.name = name; @@ -206,11 +211,13 @@ namespace Virus d.isBipolar = readPropertyBool("isBipolar"); d.toText = valueList; - d.index = readPropertyInt("index"); + d.index = static_cast<uint8_t>(readPropertyInt("index")); d.range.setStart(minValue); d.range.setEnd(maxValue); + d.valueList = it->second; + { d.classFlags = 0; @@ -270,9 +277,9 @@ namespace Virus switch (page[0]) { - case 'A': d.page = Parameter::A; break; - case 'B': d.page = Parameter::B; break; - case 'C': d.page = Parameter::C; break; + case 'A': d.page = virusLib::PAGE_A; break; + case 'B': d.page = virusLib::PAGE_B; break; + case 'C': d.page = virusLib::PAGE_C; break; default: errors << name << ": Page " << page << " is an invalid value" << std::endl; break; @@ -282,36 +289,6 @@ namespace Virus m_descriptions.push_back(d); } - assert(m_descriptions.size() == g_paramsDescription.size()); - - // DEBUG compare json parsed result to what we currently have in - size_t i = 0; - for(auto it = g_paramsDescription.begin(); it != g_paramsDescription.end(); ++it, ++i) - { - const auto& a = *it; - const auto& b = m_descriptions[i]; - - assert(a.name == b.name); - assert(a.range == b.range); - assert(a.index == b.index); - assert(a.classFlags == b.classFlags); - - assert(a.isBool == b.isBool); - assert(a.isBipolar == b.isBipolar); - assert(a.isDiscrete == b.isDiscrete); - assert(a.isPublic == b.isPublic); - - if(a.valueToTextFunction) - { - const auto textA = std::string(a.valueToTextFunction(0.0f, a).toUTF8()); - const auto textB = m_valueList[b.toText][0]; - - if (textA != textB) - { - LOG("Text doesn't match, param " << a.name << ", expected " << textA << " but got " << textB); - } - } - } return errors.str(); } } diff --git a/source/jucePlugin/VirusParameterDescriptions.h b/source/jucePlugin/VirusParameterDescriptions.h @@ -4,7 +4,7 @@ #include <string> #include <vector> -#include "VirusParameter.h" +#include "VirusParameterDescription.h" namespace Virus { @@ -13,10 +13,15 @@ namespace Virus public: explicit ParameterDescriptions(const std::string& _jsonString); + const std::vector<Description>& getDescriptions() const + { + return m_descriptions; + } + private: std::string loadJson(const std::string& _jsonString); - std::map<std::string, std::vector<std::string>> m_valueList; - std::vector<Parameter::Description> m_descriptions; + std::map<std::string, ValueList> m_valueLists; + std::vector<Description> m_descriptions; }; }