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 86ad0cfdbd6eb3126a7e78f56625ac9fbe8589ca
parent 0181e255d8aa3a846351a555afaa42ae5e15590a
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat, 14 May 2022 18:08:04 +0200

make parameter description more generic and move to own library

Diffstat:
MCMakeLists.txt | 1+
Msource/jucePlugin/CMakeLists.txt | 6++----
Msource/jucePlugin/VirusController.cpp | 8+++-----
Msource/jucePlugin/VirusController.h | 13++++++-------
Msource/jucePlugin/VirusParameter.cpp | 4++--
Msource/jucePlugin/VirusParameter.h | 24+++++-------------------
Msource/jucePlugin/VirusParameterBinding.cpp | 2+-
Msource/jucePlugin/VirusParameterBinding.h | 1+
Dsource/jucePlugin/VirusParameterDescription.cpp | 5-----
Dsource/jucePlugin/VirusParameterDescription.h | 420-------------------------------------------------------------------------------
Dsource/jucePlugin/VirusParameterDescriptions.cpp | 294-------------------------------------------------------------------------------
Dsource/jucePlugin/VirusParameterDescriptions.h | 29-----------------------------
Asource/jucePlugin/VirusParameterType.h | 378+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msource/jucePlugin/parameterDescriptions_C.json | 720++++++++++++++++++++++++++++++++++++++++----------------------------------------
Asource/jucePluginLib/CMakeLists.txt | 17+++++++++++++++++
Asource/jucePluginLib/controller.cpp | 5+++++
Asource/jucePluginLib/controller.h | 5+++++
Asource/jucePluginLib/midipacket.cpp | 5+++++
Asource/jucePluginLib/midipacket.h | 5+++++
Asource/jucePluginLib/parameterdescription.cpp | 5+++++
Asource/jucePluginLib/parameterdescription.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asource/jucePluginLib/parameterdescriptions.cpp | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asource/jucePluginLib/parameterdescriptions.h | 29+++++++++++++++++++++++++++++
23 files changed, 1149 insertions(+), 1146 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -28,6 +28,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS YES) if(${PROJECT_NAME}_BUILD_JUCEPLUGIN) set(JUCE_ENABLE_MODULE_SOURCE_GROUPS ON CACHE BOOL "" FORCE) add_subdirectory(source/JUCE) + add_subdirectory(source/jucePluginLib) add_subdirectory(source/juceUiLib) add_subdirectory(source/jucePlugin) endif() diff --git a/source/jucePlugin/CMakeLists.txt b/source/jucePlugin/CMakeLists.txt @@ -24,10 +24,7 @@ set(SOURCES VirusParameter.h VirusParameterBinding.cpp VirusParameterBinding.h - VirusParameterDescription.cpp - VirusParameterDescription.h - VirusParameterDescriptions.cpp - VirusParameterDescriptions.h + VirusParameterType.h version.h ) @@ -93,6 +90,7 @@ macro(createJucePlugin targetName productName isSynth plugin4CC binaryDataProjec PRIVATE ${binaryDataProject} juceUiLib + jucePluginLib juce::juce_audio_utils juce::juce_cryptography PUBLIC diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -2,7 +2,6 @@ #include "BinaryData.h" #include "PluginProcessor.h" -#include "VirusParameterDescriptions.h" #include "../virusLib/microcontrollerTypes.h" @@ -72,7 +71,6 @@ namespace Virus uint32_t parameterDescIndex = 0; for (const auto& desc : m_descriptions.getDescriptions()) { - const auto paramType = static_cast<ParameterType>(parameterDescIndex); ++parameterDescIndex; const ParamIndex idx = {static_cast<uint8_t>(desc.page), part, desc.index}; @@ -98,7 +96,7 @@ namespace Virus m_paramsByParamType[part].push_back(p.get()); - const bool isNonPartExclusive = (desc.classFlags & Parameter::Class::GLOBAL) || (desc.classFlags & Parameter::Class::NON_PART_SENSITIVE); + const bool isNonPartExclusive = (desc.classFlags & (int)pluginLib::ParameterClass::Global) || (desc.classFlags & (int)pluginLib::ParameterClass::NonPartSensitive); if (isNonPartExclusive) { if (part != 0) @@ -281,7 +279,7 @@ namespace Virus for (const auto& param : globalParams) { auto flags = param->getDescription().classFlags; - if (!(flags & Parameter::Class::GLOBAL) && !(flags & Parameter::Class::NON_PART_SENSITIVE)) + if (!(flags & (int)pluginLib::ParameterClass::Global) && !(flags & (int)pluginLib::ParameterClass::NonPartSensitive)) { jassertfalse; return; @@ -427,7 +425,7 @@ namespace Virus { for (const auto& param : params) { - if ((param->getDescription().classFlags & Parameter::MULTI_OR_SINGLE) && isMultiMode()) + if ((param->getDescription().classFlags & (int)pluginLib::ParameterClass::MultiOrSingle) && isMultiMode()) continue; param->setValueFromSynth(patch.data[i], true); } diff --git a/source/jucePlugin/VirusController.h b/source/jucePlugin/VirusController.h @@ -1,14 +1,13 @@ #pragma once -#include "../synthLib/plugin.h" #include "VirusParameter.h" +#include "VirusParameterType.h" -#include "VirusParameterDescriptions.h" +#include "../jucePluginLib/parameterdescriptions.h" -namespace virusLib -{ - enum class BankNumber : uint8_t; -} +#include "../virusLib/microcontrollerTypes.h" + +#include "../synthLib/plugin.h" class AudioPluginAudioProcessor; @@ -153,6 +152,6 @@ namespace Virus uint8_t m_currentProgram[16]{}; uint8_t m_currentPart = 0; juce::PropertiesFile *m_config; - ParameterDescriptions m_descriptions; + pluginLib::ParameterDescriptions m_descriptions; }; }; // namespace Virus diff --git a/source/jucePlugin/VirusParameter.cpp b/source/jucePlugin/VirusParameter.cpp @@ -4,7 +4,7 @@ namespace Virus { - Parameter::Parameter(Controller &ctrl, const Description& desc, const uint8_t partNum, const int uniqueId) : + Parameter::Parameter(Controller &ctrl, const pluginLib::Description& desc, const uint8_t partNum, const int uniqueId) : RangedAudioParameter(genId(desc, partNum, uniqueId), "Ch " + juce::String(partNum + 1) + " " + desc.name), m_ctrl(ctrl), m_desc(desc), m_partNum(partNum), m_uniqueId(uniqueId) { @@ -102,7 +102,7 @@ namespace Virus m_changingLinkedValues = false; } - juce::String Parameter::genId(const Description &d, const int part, const int uniqueId) + juce::String Parameter::genId(const pluginLib::Description &d, const int part, const int uniqueId) { if(uniqueId > 0) return juce::String::formatted("%d_%d_%d_%d", static_cast<int>(d.page), part, d.index, uniqueId); diff --git a/source/jucePlugin/VirusParameter.h b/source/jucePlugin/VirusParameter.h @@ -4,7 +4,7 @@ #include <juce_audio_processors/juce_audio_processors.h> -#include "VirusParameterDescription.h" +#include "../jucePluginLib/parameterdescription.h" namespace Virus { @@ -13,26 +13,12 @@ namespace Virus class Parameter : juce::Value::Listener, public juce::RangedAudioParameter { public: - enum Class - { - UNDEFINED = 0x0, - GLOBAL = 0x1, - PERFORMANCE_CONTROLLER = 0x2, - SOUNDBANK_A = 0x4, - SOUNDBANK_B = 0x8, - MULTI_OR_SINGLE = 0x10, - MULTI_PARAM = 0x20, - NON_PART_SENSITIVE = 0x40, - BANK_PROGRAM_CHANGE_PARAM_BANK_SELECT = 0x80, - VIRUS_C = 0x100, - }; - - Parameter(Controller &, const Description& desc, uint8_t partNum, int uniqueId); + Parameter(Controller &, const pluginLib::Description& desc, uint8_t partNum, int uniqueId); juce::Value &getValueObject() { return m_value; }; const juce::Value &getValueObject() const { return m_value; }; - const Description& getDescription() const { return m_desc; }; + const pluginLib::Description& getDescription() const { return m_desc; }; const juce::NormalisableRange<float> &getNormalisableRange() const override { return m_range; } @@ -80,12 +66,12 @@ namespace Virus int getUniqueId() const { return m_uniqueId; } private: - static juce::String genId(const Description &d, int part, int uniqueId); + static juce::String genId(const pluginLib::Description &d, int part, int uniqueId); void valueChanged(juce::Value &) override; void setLinkedValue(int _value); Controller &m_ctrl; - const Description m_desc; + const pluginLib::Description m_desc; juce::NormalisableRange<float> m_range; const uint8_t m_partNum; const int m_uniqueId; // 0 for all unique parameters, > 0 if multiple Parameter instances reference a single synth parameter diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp @@ -42,7 +42,7 @@ void VirusParameterBinding::setPart(uint8_t _part) } const auto& desc = b.parameter->getDescription(); - const bool isNonPartExclusive = (desc.classFlags & Virus::Parameter::Class::GLOBAL) || (desc.classFlags & Virus::Parameter::Class::NON_PART_SENSITIVE); + const bool isNonPartExclusive = (desc.classFlags & (int)pluginLib::ParameterClass::Global) || (desc.classFlags & (int)pluginLib::ParameterClass::NonPartSensitive); if(isNonPartExclusive) continue; diff --git a/source/jucePlugin/VirusParameterBinding.h b/source/jucePlugin/VirusParameterBinding.h @@ -1,6 +1,7 @@ #pragma once #include "VirusParameter.h" +#include "VirusParameterType.h" namespace juce { class Value; diff --git a/source/jucePlugin/VirusParameterDescription.cpp b/source/jucePlugin/VirusParameterDescription.cpp @@ -1,5 +0,0 @@ -#include "VirusParameterDescription.h" - -namespace Virus -{ -} diff --git a/source/jucePlugin/VirusParameterDescription.h b/source/jucePlugin/VirusParameterDescription.h @@ -1,420 +0,0 @@ -#pragma once - -#include <cstdint> -#include <functional> - -#include <juce_audio_processors/juce_audio_processors.h> - -#include "../../virusLib/microcontrollerTypes.h" - -namespace Virus -{ - enum ParameterType - { - Param_Invalid = -1, - - Param_BankSelect, - Param_ModWheel, - Param_BreathControl, - Param_Control3, - Param_FootControl, - Param_PortamentoTime, - Param_Data, - Param_ChannelVolume, - Param_Balance, - Param_Control9, - Param_Panorama, - Param_Expression, - Param_Control12, - Param_Control13, - Param_Control14, - Param_Control15, - Param_Control16, - Param_Osc1Shape, - Param_Osc1PW, - Param_Osc1Wave, - Param_Osc1Semitone, - Param_Osc1Keyfollow, - Param_Osc2Shape, - Param_Osc2PW, - Param_Osc2Wave, - Param_Osc2Semitone, - Param_Osc2Detune, - Param_Osc2FMAmount, - Param_Osc2Sync, - Param_Osc2FltEnvAmt, - Param_FMFiltEnvAmt, - Param_Osc2Keyfollow, - Param_PerfControl_BankSelect, - Param_OscBalance, - Param_SubOscVolume, - Param_SubOscShape, - Param_OscMainVolume, - Param_NoiseVolume, - Param_RingModMVolume, - Param_NoiseColor, - Param_FilterCutA, - Param_FilterCutB, - Param_FilterResA, - Param_FilterResB, - Param_FilterEnvAmtA, - Param_FilterEnvAmtB, - Param_FilterKeyFollowA, - Param_FilterKeyFollowB, - Param_FilterBalance, - Param_SaturationCurve, - Param_FilterModeA, - Param_FilterModeB, - Param_FilterRouting, - Param_FilterEnvAttack, - Param_FilterEnvDecay, - Param_FilterEnvSustain, - Param_FilterEnvSustainTime, - Param_FilterEnvRelease, - Param_AmpEnvAttack, - Param_AmpEnvDecay, - Param_AmpEnvSustain, - Param_AmpEnvSustainTime, - Param_AmpEnvRelease, - Param_HoldPedal, - Param_PortamentoPedal, - Param_SostenutoPedal, - Param_Lfo1Rate, - Param_Lfo1Shape, - Param_Lfo1EnvMode, - Param_Lfo1Mode, - Param_Lfo1Symmetry, - Param_Lfo1Keyfollow, - Param_Lfo1KeyTrigger, - Param_Osc1Lfo1Amount, - Param_Osc2Lfo1Amount, - Param_PWLfo1Amount, - Param_ResoLfo1Amount, - Param_FltGainLfo1Amount, - Param_Lfo2Rate, - Param_Lfo2Shape, - Param_Lfo2EnvMode, - Param_Lfo2Mode, - Param_Lfo2Symmetry, - Param_Lfo2Keyfollow, - Param_Lfo2Keytrigger, - Param_OscShapeLfo2Amount, - Param_FmAmountLfo2Amount, - Param_Cutoff1Lfo2Amount, - Param_Cutoff2Lfo2Amount, - Param_PanoramaLfo2Amount, - Param_PatchVolume, - Param_Transpose, - Param_KeyMode, - Param_UnisonMode, - Param_UnisonDetune, - Param_UnisonPanSpread, - Param_UnisonLfoPhase, - Param_InputMode, - Param_InputSelect, - Param_ChorusMix, - Param_ChorusRate, - Param_ChorusDepth, - Param_ChorusDelay, - Param_ChorusFeedback, - Param_ChorusLfoShape, - Param_DelayReverbMode, - Param_EffectSend, - Param_DelayTime, - Param_DelayFeedback, - Param_DelayRateReverbDecayTime, - Param_DelayDepth, - Param_ReverbRoomSize, - Param_DelayLfoShape, - Param_ReverbDamping, - Param_DelayColor, - Param_KeybLocal, - Param_AllNotesOff, - - Param_ArpMode, - Param_ArpPatternSelect, - Param_ArpOctaveRange, - Param_ArpHoldEnable, - Param_ArpNoteLength, - Param_ArpSwing, - - Param_Lfo3Rate, - Param_Lfo3Shape, - Param_Lfo3Mode, - Param_Lfo3Keyfollow, - Param_Lfo3Destination, - Param_OscLfo3Amount, - Param_Lfo3FadeInTime, - Param_ClockTempo, - Param_ArpClock, - Param_Lfo1Clock, - Param_Lfo2Clock, - Param_DelayClock, - Param_Lfo3Clock, - Param_ControlSmoothMode, - Param_BenderRangeUp, - Param_BenderRangeDown, - Param_BenderScale, - Param_Filter1EnvPolarity, - Param_Filter2EnvPolarity, - Param_Filter2CutoffLink, - Param_FilterKeytrackBase, - Param_OscFMMode, - Param_OscInitPhase, - Param_PunchIntensity, - Param_InputFollowMode, - Param_VocoderMode, - Param_Osc3Mode, - Param_Osc3Volume, - Param_Osc3Semitone, - Param_Osc3Detune, - Param_LowEqFreq, - Param_HighEqFreq, - Param_Osc1ShapeVelocity, - Param_Osc2ShapeVelocity, - Param_PulseWidthVelocity, - Param_FmAmountVelocity, - Param_SoftKnob1ShortName, - Param_SoftKnob2ShortName, - Param_Filter1EnvAmtVelocity, - Param_Filter2EnvAmtVelocity, - Param_Resonance1Velocity, - Param_Resonance2Velocity, - Param_SecondOutputBalance, - Param_AmpVelocity, - Param_PanoramaVelocity, - Param_SoftKnob1Single, - Param_SoftKnob2Single, - Param_Assign1Source, - Param_Assign1Destination, - Param_Assign1Amount, - Param_Assign2Source, - Param_Assign2Destination1, - Param_Assign2Amount1, - Param_Assign2Destination2, - Param_Assign2Amount2, - Param_Assign3Source, - Param_Assign3Destination1, - Param_Assign3Amount1, - Param_Assign3Destination2, - Param_Assign3Amount2, - Param_Assign2Destination3, - Param_Assign2Amount3, - Param_Lfo1AssignDest, - Param_Lfo1AssignAmount, - Param_Lfo2AssignDest, - Param_Lfo2AssignAmount, - Param_PhaserMode, - Param_PhaserMix, - Param_PhaserRate, - Param_PhaserDepth, - Param_PhaserFreq, - Param_PhaserFeedback, - Param_PhaserSpread, - Param_MidEqGain, - Param_MidEqFreq, - Param_MidEqQFactor, - Param_LowEqGain, - Param_HighEqGain, - Param_BassIntensity, - Param_BassTune, - Param_InputRingMod, - Param_DistortionCurve, - Param_DistortionIntensity, - Param_Assign4Source, - Param_Assign4Destination, - Param_Assign4Amount, - Param_Assign5Source, - Param_Assign5Destination, - Param_Assign5Amount, - Param_Assign6Source, - Param_Assign6Destination, - Param_Assign6Amount, - Param_FilterSelect, - Param_Category1, - Param_Category2, - Param_DelayOutputSelect, - Param_PartBankSelect, - Param_PartBankChange, - Param_PartProgramChange, - Param_PartMidiChannel, - Param_PartLowKey, - Param_PartHighKey, - Param_PartTranspose, - Param_PartDetune, - Param_PartVolume, - Param_PartMidiVolumeInit, - Param_PartOutputSelect, - Param_GlobalSecondOutputSelect, - Param_GlobalKeybTransposeButtons, - Param_GlobalKeybLocal, - Param_GlobalKeybMode, - Param_GlobalKeybTranspose, - Param_GlobalKeyModWheelControl, - Param_GlobalKeybPedal1Control, - Param_GlobalKeybPedal2Control, - Param_GlobalKeybPressureSensitive, - Param_PartEnable, - Param_PartMidiVolumeEnable, - Param_PartHoldPedalEnable, - Param_KeybToMidi, - Param_NoteStealPriority, - Param_PartProgChangeEnable, - Param_GlobalProgChangeEnable, - Param_MultiProgChangeEnable, - Param_GlobalMidiVolumeEnable, - Param_InputThruLevel, - Param_InputBoost, - Param_MasterTune, - Param_DeviceID, - Param_MidiControlLowPage, - Param_MidiControlHighPage, - Param_MidiArpSend, - Param_KnobDisplay, - Param_MidiDumpTX, - Param_MidiDumpRX, - Param_MultiProgramChange, - Param_MidiClockRX, - Param_SoftKnob1Mode, - Param_SoftKnob2Mode, - Param_SoftKnob1Global, - Param_SoftKnob2Global, - Param_SoftKnob1Midi, - Param_SoftKnob2Midi, - Param_ExpertMode, - Param_KnobMode, - Param_MemoryProtect, - Param_SoftThru, - Param_PanelDestination, - Param_PlayMode, - Param_PartNumber, - Param_GlobalChannel, - Param_LedMode, - Param_LcdContrast, - Param_MasterVolume, - - // UNDEFINED / UNUSED / STUBS - Param_PageA_Undefined92, - Param_PageA_Undefined95, - Param_PageA_Undefined96, - Param_PageA_Undefined111, - Param_PageA_Undefined120, - Param_PageA_Undefined121, - Param_PageA_Undefined124, - Param_PageA_Undefined125, - Param_PageA_Undefined126, - Param_PageA_Undefined127, - Param_PageB_Undefined0, - Param_PageB_Undefined14, - Param_PageB_Undefined15, - Param_PageB_Undefined22, - Param_PageB_Undefined23, - Param_PageB_Undefined24, - Param_PageB_Undefined29, - Param_PageB_Undefined37, - Param_PageB_Undefined40, - Param_PageB_Undefined53, - Param_PageB_Undefined69, - Param_PageB_Undefined83, - Param_PageB_Undefined91, - Param_PageB_Undefined111, - Param_PageB_Undefined123, - Param_PageB_Undefined124, - Param_PageC_Undefined0, - Param_PageC_Undefined1, - Param_PageC_Undefined2, - Param_PageC_Undefined3, - Param_PageC_Undefined4, - Param_PageC_Undefined15, - Param_PageC_Undefined16, - Param_PageC_Undefined17, - Param_PageC_Undefined18, - Param_PageC_Undefined19, - Param_PageC_Undefined20, - Param_PageC_Undefined21, - Param_PageC_Undefined23, - Param_PageC_Undefined24, - Param_PageC_Undefined25, - Param_PageC_Undefined26, - Param_PageC_Undefined27, - Param_PageC_Undefined28, - Param_PageC_Undefined29, - Param_PageC_Undefined30, - Param_PageC_Undefined76, - Param_PageC_Undefined79, - Param_PageC_Undefined80, - Param_PageC_Undefined81, - Param_PageC_Undefined82, - Param_PageC_Undefined83, - Param_PageC_Undefined84, - Param_PageC_Undefined88, - Param_PageC_Undefined89, - Param_PageC_Undefined100, - Param_PageC_Undefined101, - Param_PageC_Undefined102, - Param_PageC_Undefined103, - Param_PageC_Undefined104, - Param_PageC_Undefined119, - // Text Chars / Unused - Param_PageB_Undefined110, - Param_PageB_Undefined111_, - Param_PageB_Undefined112, - Param_PageB_Undefined113, - Param_PageB_Undefined114, - Param_PageB_Undefined115, - Param_PageB_Undefined116, - Param_PageB_Undefined117, - Param_PageB_Undefined118, - Param_PageB_Undefined119, - Param_PageB_Undefined120, - Param_PageB_Undefined121, - Param_PageC_Undefined5, - Param_PageC_Undefined6, - Param_PageC_Undefined7, - Param_PageC_Undefined8, - Param_PageC_Undefined9, - Param_PageC_Undefined10, - Param_PageC_Undefined11, - Param_PageC_Undefined12, - Param_PageC_Undefined13, - Param_PageC_Undefined14, - - Param_Count - }; - - 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,294 +0,0 @@ -#include "VirusParameterDescriptions.h" - -#include "VirusParameter.h" -#include "VirusParameterDescription.h" - -#include "dsp56kEmu/logging.h" - -namespace Virus -{ - ParameterDescriptions::ParameterDescriptions(const std::string& _jsonString) - { - const auto err = loadJson(_jsonString); - LOG(err); - } - - std::string ParameterDescriptions::removeComments(std::string _json) - { - auto removeBlock = [&](const std::string& _begin, const std::string& _end) - { - const auto pos = _json.find(_begin); - - if (pos == std::string::npos) - return false; - - const auto end = _json.find(_end, pos + 1); - - if (end != std::string::npos) - _json.erase(pos, end - pos + _end.size()); - else - _json.erase(pos); - - return true; - }; - - while (removeBlock("//", "\n") || removeBlock("/*", "*/")) - { - } - - return _json; - } - - std::string ParameterDescriptions::loadJson(const std::string& _jsonString) - { - // juce' JSON parser doesn't like JSON5-style comments - const auto jsonString = removeComments(_jsonString); - - juce::var json; - - const auto error = juce::JSON::parse(juce::String(jsonString), json); - - if (error.failed()) - return std::string("Failed to parse JSON: ") + std::string(error.getErrorMessage().toUTF8()); - - const auto paramDescDefaults = json["parameterdescriptiondefaults"].getDynamicObject(); - const auto defaultProperties = paramDescDefaults ? paramDescDefaults->getProperties() : juce::NamedValueSet(); - const auto paramDescs = json["parameterdescriptions"]; - - const auto descsArray = paramDescs.getArray(); - - if (descsArray == nullptr) - return "Parameter descriptions are empty"; - - { - const auto valueLists = json["valuelists"]; - - auto* entries = valueLists.getDynamicObject(); - - if (!entries) - return "value lists are not defined"; - - auto entryProps = entries->getProperties(); - - for(int i=0; i<entryProps.size(); ++i) - { - const auto key = std::string(entryProps.getName(i).toString().toUTF8()); - const auto values = entryProps.getValueAt(i).getArray(); - - 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"; - - ValueList vl; - vl.texts.reserve(values->size()); - - for (auto&& value : *values) - { - 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_valueLists.insert(std::make_pair(key, vl)); - } - } - - std::stringstream errors; - - const auto& descs = *descsArray; - - for (int i = 0; i < descs.size(); ++i) - { - const auto& desc = descs[i].getDynamicObject(); - const auto props = desc->getProperties(); - - if (props.isEmpty()) - { - errors << "Parameter desc " << i << " has no properties defined" << std::endl; - continue; - } - - const auto name = props["name"].toString(); - - if (name.isEmpty()) - { - errors << "Parameter desc " << i << " doesn't have a name" << std::endl; - continue; - } - - auto readProperty = [&](const char* _key) - { - auto result = props[_key]; - if (!result.isVoid()) - return result; - result = defaultProperties[_key]; - if (result.isVoid()) - errors << "Property " << _key << " not found for parameter description " << name << " and no default provided" << std::endl; - return result; - }; - - auto readPropertyString = [&](const char* _key) - { - const auto res = readProperty(_key); - - if(!res.isString()) - errors << "Property " << _key << " of parameter desc " << name << " is not of type string" << std::endl; - - return std::string(res.toString().toUTF8()); - }; - - auto readPropertyInt = [&](const char* _key) - { - const auto res = readProperty(_key); - - if (!res.isInt()) - errors << "Property " << _key << " of parameter desc " << name << " is not of type int " << std::endl; - - return static_cast<int>(res); - }; - - auto readPropertyBool = [&](const char* _key) - { - const auto res = readProperty(_key); - - if (res.isInt()) - return static_cast<int>(res) != 0; - if (res.isBool()) - return static_cast<bool>(res); - - errors << "Property " << _key << " of parameter desc " << name << " is not of type bool " << std::endl; - - return static_cast<bool>(res); - }; - - const auto minValue = readPropertyInt("min"); - const auto maxValue = readPropertyInt("max"); - - if (minValue < 0 || minValue > 127) - { - errors << name << ": min value for parameter desc " << name << " must be in range 0-127 but min is set to " << minValue << std::endl; - continue; - } - if(maxValue < 0 || maxValue > 127) - { - errors << name << ": max value for parameter desc " << name << " must be in range 0-127 but max is set to " << maxValue << std::endl; - continue; - } - if (maxValue < minValue) - { - errors << name << ": max value must be larger than min value but min is " << minValue << ", max is " << maxValue << std::endl; - continue; - } - - const auto valueList = readPropertyString("toText"); - - const auto it = m_valueLists.find(valueList); - if(it == m_valueLists.end()) - { - errors << name << ": Value list " << valueList << " not found" << std::endl; - continue; - } - - const auto& list = *it; - - if((maxValue - minValue + 1) > static_cast<int>(list.second.texts.size())) - { - errors << name << ": value list " << valueList << " contains only " << list.second.texts.size() << " entries but parameter range is " << minValue << "-" << maxValue << std::endl; - } - - Description d; - - d.name = name; - - d.isPublic = readPropertyBool("isPublic"); - d.isDiscrete = readPropertyBool("isDiscrete"); - d.isBool = readPropertyBool("isBool"); - d.isBipolar = readPropertyBool("isBipolar"); - - d.toText = valueList; - d.index = static_cast<uint8_t>(readPropertyInt("index")); - - d.range.setStart(minValue); - d.range.setEnd(maxValue); - - d.valueList = it->second; - - { - d.classFlags = 0; - - const auto classFlags = readPropertyString("class"); - - std::vector<std::string> flags; - size_t off = 0; - - while (true) - { - const auto pos = classFlags.find('|', off); - - if(pos == std::string::npos) - { - flags.push_back(classFlags.substr(off)); - break; - } - - flags.push_back(classFlags.substr(off, pos - off)); - off = pos + 1; - } - - for (const auto & flag : flags) - { - if (flag == "Undefined") - d.classFlags |= Parameter::UNDEFINED; - else if (flag == "Global") - d.classFlags |= Parameter::GLOBAL; - else if (flag == "PerformanceController") - d.classFlags |= Parameter::PERFORMANCE_CONTROLLER; - else if (flag == "SoundbankA") - d.classFlags |= Parameter::SOUNDBANK_A; - else if (flag == "SoundbankB") - d.classFlags |= Parameter::SOUNDBANK_B; - else if (flag == "MultiOrSingle") - d.classFlags |= Parameter::MULTI_OR_SINGLE; - else if (flag == "Multi") - d.classFlags |= Parameter::MULTI_PARAM; - else if (flag == "NonPartSensitive") - d.classFlags |= Parameter::NON_PART_SENSITIVE; - else if (flag == "BankProgramChangeParamBankSelect") - d.classFlags |= Parameter::BANK_PROGRAM_CHANGE_PARAM_BANK_SELECT; - else if (flag == "VirusC") - d.classFlags |= Parameter::VIRUS_C; - else - errors << "Class " << flag << " is unknown" << std::endl; - } - } - { - const auto page = readPropertyString("page"); - - if (page.size() != 1) - { - errors << name << ": Page " << page << " is an invalid value" << std::endl; - continue; - } - - switch (page[0]) - { - 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; - } - } - - m_descriptions.push_back(d); - } - - return errors.str(); - } -} diff --git a/source/jucePlugin/VirusParameterDescriptions.h b/source/jucePlugin/VirusParameterDescriptions.h @@ -1,29 +0,0 @@ -#pragma once - -#include <map> -#include <string> -#include <vector> - -#include "VirusParameterDescription.h" - -namespace Virus -{ - class ParameterDescriptions - { - public: - explicit ParameterDescriptions(const std::string& _jsonString); - - const std::vector<Description>& getDescriptions() const - { - return m_descriptions; - } - - static std::string removeComments(std::string _json); - - private: - std::string loadJson(const std::string& _jsonString); - - std::map<std::string, ValueList> m_valueLists; - std::vector<Description> m_descriptions; - }; -} diff --git a/source/jucePlugin/VirusParameterType.h b/source/jucePlugin/VirusParameterType.h @@ -0,0 +1,377 @@ +#pragma once + +namespace Virus +{ + enum ParameterType + { + Param_Invalid = -1, + + Param_BankSelect, + Param_ModWheel, + Param_BreathControl, + Param_Control3, + Param_FootControl, + Param_PortamentoTime, + Param_Data, + Param_ChannelVolume, + Param_Balance, + Param_Control9, + Param_Panorama, + Param_Expression, + Param_Control12, + Param_Control13, + Param_Control14, + Param_Control15, + Param_Control16, + Param_Osc1Shape, + Param_Osc1PW, + Param_Osc1Wave, + Param_Osc1Semitone, + Param_Osc1Keyfollow, + Param_Osc2Shape, + Param_Osc2PW, + Param_Osc2Wave, + Param_Osc2Semitone, + Param_Osc2Detune, + Param_Osc2FMAmount, + Param_Osc2Sync, + Param_Osc2FltEnvAmt, + Param_FMFiltEnvAmt, + Param_Osc2Keyfollow, + Param_PerfControl_BankSelect, + Param_OscBalance, + Param_SubOscVolume, + Param_SubOscShape, + Param_OscMainVolume, + Param_NoiseVolume, + Param_RingModMVolume, + Param_NoiseColor, + Param_FilterCutA, + Param_FilterCutB, + Param_FilterResA, + Param_FilterResB, + Param_FilterEnvAmtA, + Param_FilterEnvAmtB, + Param_FilterKeyFollowA, + Param_FilterKeyFollowB, + Param_FilterBalance, + Param_SaturationCurve, + Param_FilterModeA, + Param_FilterModeB, + Param_FilterRouting, + Param_FilterEnvAttack, + Param_FilterEnvDecay, + Param_FilterEnvSustain, + Param_FilterEnvSustainTime, + Param_FilterEnvRelease, + Param_AmpEnvAttack, + Param_AmpEnvDecay, + Param_AmpEnvSustain, + Param_AmpEnvSustainTime, + Param_AmpEnvRelease, + Param_HoldPedal, + Param_PortamentoPedal, + Param_SostenutoPedal, + Param_Lfo1Rate, + Param_Lfo1Shape, + Param_Lfo1EnvMode, + Param_Lfo1Mode, + Param_Lfo1Symmetry, + Param_Lfo1Keyfollow, + Param_Lfo1KeyTrigger, + Param_Osc1Lfo1Amount, + Param_Osc2Lfo1Amount, + Param_PWLfo1Amount, + Param_ResoLfo1Amount, + Param_FltGainLfo1Amount, + Param_Lfo2Rate, + Param_Lfo2Shape, + Param_Lfo2EnvMode, + Param_Lfo2Mode, + Param_Lfo2Symmetry, + Param_Lfo2Keyfollow, + Param_Lfo2Keytrigger, + Param_OscShapeLfo2Amount, + Param_FmAmountLfo2Amount, + Param_Cutoff1Lfo2Amount, + Param_Cutoff2Lfo2Amount, + Param_PanoramaLfo2Amount, + Param_PatchVolume, + Param_Transpose, + Param_KeyMode, + Param_UnisonMode, + Param_UnisonDetune, + Param_UnisonPanSpread, + Param_UnisonLfoPhase, + Param_InputMode, + Param_InputSelect, + Param_ChorusMix, + Param_ChorusRate, + Param_ChorusDepth, + Param_ChorusDelay, + Param_ChorusFeedback, + Param_ChorusLfoShape, + Param_DelayReverbMode, + Param_EffectSend, + Param_DelayTime, + Param_DelayFeedback, + Param_DelayRateReverbDecayTime, + Param_DelayDepth, + Param_ReverbRoomSize, + Param_DelayLfoShape, + Param_ReverbDamping, + Param_DelayColor, + Param_KeybLocal, + Param_AllNotesOff, + + Param_ArpMode, + Param_ArpPatternSelect, + Param_ArpOctaveRange, + Param_ArpHoldEnable, + Param_ArpNoteLength, + Param_ArpSwing, + + Param_Lfo3Rate, + Param_Lfo3Shape, + Param_Lfo3Mode, + Param_Lfo3Keyfollow, + Param_Lfo3Destination, + Param_OscLfo3Amount, + Param_Lfo3FadeInTime, + Param_ClockTempo, + Param_ArpClock, + Param_Lfo1Clock, + Param_Lfo2Clock, + Param_DelayClock, + Param_Lfo3Clock, + Param_ControlSmoothMode, + Param_BenderRangeUp, + Param_BenderRangeDown, + Param_BenderScale, + Param_Filter1EnvPolarity, + Param_Filter2EnvPolarity, + Param_Filter2CutoffLink, + Param_FilterKeytrackBase, + Param_OscFMMode, + Param_OscInitPhase, + Param_PunchIntensity, + Param_InputFollowMode, + Param_VocoderMode, + Param_Osc3Mode, + Param_Osc3Volume, + Param_Osc3Semitone, + Param_Osc3Detune, + Param_LowEqFreq, + Param_HighEqFreq, + Param_Osc1ShapeVelocity, + Param_Osc2ShapeVelocity, + Param_PulseWidthVelocity, + Param_FmAmountVelocity, + Param_SoftKnob1ShortName, + Param_SoftKnob2ShortName, + Param_Filter1EnvAmtVelocity, + Param_Filter2EnvAmtVelocity, + Param_Resonance1Velocity, + Param_Resonance2Velocity, + Param_SecondOutputBalance, + Param_AmpVelocity, + Param_PanoramaVelocity, + Param_SoftKnob1Single, + Param_SoftKnob2Single, + Param_Assign1Source, + Param_Assign1Destination, + Param_Assign1Amount, + Param_Assign2Source, + Param_Assign2Destination1, + Param_Assign2Amount1, + Param_Assign2Destination2, + Param_Assign2Amount2, + Param_Assign3Source, + Param_Assign3Destination1, + Param_Assign3Amount1, + Param_Assign3Destination2, + Param_Assign3Amount2, + Param_Assign2Destination3, + Param_Assign2Amount3, + Param_Lfo1AssignDest, + Param_Lfo1AssignAmount, + Param_Lfo2AssignDest, + Param_Lfo2AssignAmount, + Param_PhaserMode, + Param_PhaserMix, + Param_PhaserRate, + Param_PhaserDepth, + Param_PhaserFreq, + Param_PhaserFeedback, + Param_PhaserSpread, + Param_MidEqGain, + Param_MidEqFreq, + Param_MidEqQFactor, + Param_LowEqGain, + Param_HighEqGain, + Param_BassIntensity, + Param_BassTune, + Param_InputRingMod, + Param_DistortionCurve, + Param_DistortionIntensity, + Param_Assign4Source, + Param_Assign4Destination, + Param_Assign4Amount, + Param_Assign5Source, + Param_Assign5Destination, + Param_Assign5Amount, + Param_Assign6Source, + Param_Assign6Destination, + Param_Assign6Amount, + Param_FilterSelect, + Param_Category1, + Param_Category2, + Param_DelayOutputSelect, + Param_PartBankSelect, + Param_PartBankChange, + Param_PartProgramChange, + Param_PartMidiChannel, + Param_PartLowKey, + Param_PartHighKey, + Param_PartTranspose, + Param_PartDetune, + Param_PartVolume, + Param_PartMidiVolumeInit, + Param_PartOutputSelect, + Param_GlobalSecondOutputSelect, + Param_GlobalKeybTransposeButtons, + Param_GlobalKeybLocal, + Param_GlobalKeybMode, + Param_GlobalKeybTranspose, + Param_GlobalKeyModWheelControl, + Param_GlobalKeybPedal1Control, + Param_GlobalKeybPedal2Control, + Param_GlobalKeybPressureSensitive, + Param_PartEnable, + Param_PartMidiVolumeEnable, + Param_PartHoldPedalEnable, + Param_KeybToMidi, + Param_NoteStealPriority, + Param_PartProgChangeEnable, + Param_GlobalProgChangeEnable, + Param_MultiProgChangeEnable, + Param_GlobalMidiVolumeEnable, + Param_InputThruLevel, + Param_InputBoost, + Param_MasterTune, + Param_DeviceID, + Param_MidiControlLowPage, + Param_MidiControlHighPage, + Param_MidiArpSend, + Param_KnobDisplay, + Param_MidiDumpTX, + Param_MidiDumpRX, + Param_MultiProgramChange, + Param_MidiClockRX, + Param_SoftKnob1Mode, + Param_SoftKnob2Mode, + Param_SoftKnob1Global, + Param_SoftKnob2Global, + Param_SoftKnob1Midi, + Param_SoftKnob2Midi, + Param_ExpertMode, + Param_KnobMode, + Param_MemoryProtect, + Param_SoftThru, + Param_PanelDestination, + Param_PlayMode, + Param_PartNumber, + Param_GlobalChannel, + Param_LedMode, + Param_LcdContrast, + Param_MasterVolume, + + // UNDEFINED / UNUSED / STUBS + Param_PageA_Undefined92, + Param_PageA_Undefined95, + Param_PageA_Undefined96, + Param_PageA_Undefined111, + Param_PageA_Undefined120, + Param_PageA_Undefined121, + Param_PageA_Undefined124, + Param_PageA_Undefined125, + Param_PageA_Undefined126, + Param_PageA_Undefined127, + Param_PageB_Undefined0, + Param_PageB_Undefined14, + Param_PageB_Undefined15, + Param_PageB_Undefined22, + Param_PageB_Undefined23, + Param_PageB_Undefined24, + Param_PageB_Undefined29, + Param_PageB_Undefined37, + Param_PageB_Undefined40, + Param_PageB_Undefined53, + Param_PageB_Undefined69, + Param_PageB_Undefined83, + Param_PageB_Undefined91, + Param_PageB_Undefined111, + Param_PageB_Undefined123, + Param_PageB_Undefined124, + Param_PageC_Undefined0, + Param_PageC_Undefined1, + Param_PageC_Undefined2, + Param_PageC_Undefined3, + Param_PageC_Undefined4, + Param_PageC_Undefined15, + Param_PageC_Undefined16, + Param_PageC_Undefined17, + Param_PageC_Undefined18, + Param_PageC_Undefined19, + Param_PageC_Undefined20, + Param_PageC_Undefined21, + Param_PageC_Undefined23, + Param_PageC_Undefined24, + Param_PageC_Undefined25, + Param_PageC_Undefined26, + Param_PageC_Undefined27, + Param_PageC_Undefined28, + Param_PageC_Undefined29, + Param_PageC_Undefined30, + Param_PageC_Undefined76, + Param_PageC_Undefined79, + Param_PageC_Undefined80, + Param_PageC_Undefined81, + Param_PageC_Undefined82, + Param_PageC_Undefined83, + Param_PageC_Undefined84, + Param_PageC_Undefined88, + Param_PageC_Undefined89, + Param_PageC_Undefined100, + Param_PageC_Undefined101, + Param_PageC_Undefined102, + Param_PageC_Undefined103, + Param_PageC_Undefined104, + Param_PageC_Undefined119, + // Text Chars / Unused + Param_PageB_Undefined110, + Param_PageB_Undefined111_, + Param_PageB_Undefined112, + Param_PageB_Undefined113, + Param_PageB_Undefined114, + Param_PageB_Undefined115, + Param_PageB_Undefined116, + Param_PageB_Undefined117, + Param_PageB_Undefined118, + Param_PageB_Undefined119, + Param_PageB_Undefined120, + Param_PageB_Undefined121, + Param_PageC_Undefined5, + Param_PageC_Undefined6, + Param_PageC_Undefined7, + Param_PageC_Undefined8, + Param_PageC_Undefined9, + Param_PageC_Undefined10, + Param_PageC_Undefined11, + Param_PageC_Undefined12, + Param_PageC_Undefined13, + Param_PageC_Undefined14, + + Param_Count + }; +} +\ No newline at end of file diff --git a/source/jucePlugin/parameterDescriptions_C.json b/source/jucePlugin/parameterDescriptions_C.json @@ -11,375 +11,375 @@ }, "parameterdescriptions": [ - {"page":"A", "class":"PerformanceController", "index":0, "name":"Version", "min":0, "max":12, "toText":"version", "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":1, "name":"Modulation Wheel", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":2, "name":"Breath Controller", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":3, "name":"Contr 3", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":4, "name":"Foot Controller", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":5, "name":"Portamento Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":6, "name":"Data Slider", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":7, "name":"Channel Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":8, "name":"Balance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":9, "name":"Contr 9", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":10, "name":"Panorama", "min":0, "max":127, "toText":"pan", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"PerformanceController", "index":11, "name":"Expression", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":12, "name":"Contr 12", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":13, "name":"Contr 13", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":14, "name":"Contr 14", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":15, "name":"Contr 15", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":16, "name":"Contr 16", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":17, "name":"Osc1 Shape", "min":0, "max":127, "toText":"oscShape", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":18, "name":"Osc1 Pulsewidth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":19, "name":"Osc1 Wave Select", "min":0, "max":63, "toText":"oscWave", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":20, "name":"Osc1 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":21, "name":"Osc1 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":22, "name":"Osc2 Shape", "min":0, "max":127, "toText":"oscShape", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":23, "name":"Osc2 Pulsewidth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":24, "name":"Osc2 Wave Select", "min":0, "max":63, "toText":"oscWave", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":25, "name":"Osc2 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":26, "name":"Osc2 Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":27, "name":"Osc2 FM Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":28, "name":"Osc2 Sync", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA", "index":29, "name":"Osc2 Filt Env Amt", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":30, "name":"FM Filt Env Amt", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":31, "name":"Osc2 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"PerformanceController", "index":32, "name":"Bank Select", "min":0, "max":8, "toText":"bank", "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":33, "name":"Osc Balance", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":34, "name":"Suboscillator Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":35, "name":"Suboscillator Shape", "min":0, "max":1, "toText":"suboscShape", "isDiscrete":true, "isBool":true, "isBipolar":false}, - {"page":"A", "class":"SoundbankA", "index":36, "name":"Osc Mainvolume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":37, "name":"Noise Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":38, "name":"Ringmodulator Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|VirusC", "index":39, "name":"Noise Color", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":40, "name":"Cutoff", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":41, "name":"Cutoff2", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":42, "name":"Filter1 Resonance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":43, "name":"Filter2 Resonance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":44, "name":"Filter1 Env Amt", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":45, "name":"Filter2 Env Amt", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":46, "name":"Filter1 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":47, "name":"Filter2 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":48, "name":"Filter Balance", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":49, "name":"Saturation Curve", "min":0, "max":14, "toText":"satCurve", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":51, "name":"Filter1 Mode", "min":0, "max":7, "toText":"filter1Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":52, "name":"Filter2 Mode", "min":0, "max":3, "toText":"filter2Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":53, "name":"Filter Routing", "min":0, "max":3, "toText":"filterRouting", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":54, "name":"Filter Env Attack", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":55, "name":"Filter Env Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":56, "name":"Filter Env Sustain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":57, "name":"Filter Env Sustain Time", "min":0, "max":127, "toText":"envSustainTime", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":58, "name":"Filter Env Release", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":59, "name":"Amp Env Attack", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":60, "name":"Amp Env Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":61, "name":"Amp Env Sustain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":62, "name":"Amp Env Sustain Time", "min":0, "max":127, "toText":"envSustainTime", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":63, "name":"Amp Env Release", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":64, "name":"Hold Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":65, "name":"Portamento Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"PerformanceController", "index":66, "name":"Sostenuto Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":67, "name":"Lfo1 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":68, "name":"Lfo1 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":69, "name":"Lfo1 Env Mode", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA", "index":70, "name":"Lfo1 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA", "index":71, "name":"Lfo1 Symmetry", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":72, "name":"Lfo1 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":73, "name":"Lfo1 Keytrigger", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":74, "name":"Osc1 Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":75, "name":"Osc2 Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":76, "name":"PW Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":77, "name":"Reso Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":78, "name":"FiltGain Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":79, "name":"Lfo2 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":80, "name":"Lfo2 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":81, "name":"Lfo2 Env Mode", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA", "index":82, "name":"Lfo2 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA", "index":83, "name":"Lfo2 Symmetry", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":84, "name":"Lfo2 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":85, "name":"Lfo2 Keytrigger", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":86, "name":"Shape Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":87, "name":"FM Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":88, "name":"Cutoff1 Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":89, "name":"Cutoff2 Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":90, "name":"Pan Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":91, "name":"Patch Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":93, "name":"Transpose", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":94, "name":"Key Mode", "min":0, "max":5, "toText":"keyMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":97, "name":"Unison Mode", "min":0, "max":15, "toText":"unisonMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":98, "name":"Unison Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":99, "name":"Unison Pan Spread", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":100, "name":"Unison Lfo Phase", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":101, "name":"Input Mode", "min":0, "max":3, "toText":"inputMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":102, "name":"Input Select", "min":0, "max":8, "toText":"inputSelect", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":105, "name":"Chorus Mix", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":106, "name":"Chorus Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":107, "name":"Chorus Depth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":108, "name":"Chorus Delay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA", "index":109, "name":"Chorus Feedback", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA", "index":110, "name":"Chorus Lfo Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle", "index":112, "name":"Delay/Reverb Mode", "min":0, "max":26, "toText":"delayReverbMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle", "index":113, "name":"Effect Send", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":114, "name":"Delay Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":115, "name":"Delay Feedback", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":116, "name":"Dly Rate / Rev Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":117, "name":"Dly Depth ", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":117, "name":"Rev Size", "min":0, "max":3, "toText":"reverbRoomSize", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":118, "name":"Delay Lfo Shape", "min":0, "max":5, "toText":"delayLfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":118, "name":"Reverb Damping", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":119, "name":"Delay Color", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":122, "name":"Keyb Local", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"A", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":123, "name":"All Notes Off", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":0, "name":"Version", "min":0, "max":12, "toText":"version", "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":1, "name":"Modulation Wheel", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":2, "name":"Breath Controller", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":3, "name":"Contr 3", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":4, "name":"Foot Controller", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":5, "name":"Portamento Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":6, "name":"Data Slider", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":7, "name":"Channel Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":8, "name":"Balance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":9, "name":"Contr 9", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":10, "name":"Panorama", "min":0, "max":127, "toText":"pan", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"PerformanceController", "index":11, "name":"Expression", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":12, "name":"Contr 12", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":13, "name":"Contr 13", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":14, "name":"Contr 14", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":15, "name":"Contr 15", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":16, "name":"Contr 16", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":17, "name":"Osc1 Shape", "min":0, "max":127, "toText":"oscShape", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":18, "name":"Osc1 Pulsewidth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":19, "name":"Osc1 Wave Select", "min":0, "max":63, "toText":"oscWave", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":20, "name":"Osc1 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":21, "name":"Osc1 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":22, "name":"Osc2 Shape", "min":0, "max":127, "toText":"oscShape", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":23, "name":"Osc2 Pulsewidth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":24, "name":"Osc2 Wave Select", "min":0, "max":63, "toText":"oscWave", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":25, "name":"Osc2 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":26, "name":"Osc2 Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":27, "name":"Osc2 FM Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":28, "name":"Osc2 Sync", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA", "index":29, "name":"Osc2 Filt Env Amt", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":30, "name":"FM Filt Env Amt", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":31, "name":"Osc2 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"PerformanceController", "index":32, "name":"Bank Select", "min":0, "max":8, "toText":"bank", "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":33, "name":"Osc Balance", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":34, "name":"Suboscillator Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":35, "name":"Suboscillator Shape", "min":0, "max":1, "toText":"suboscShape", "isDiscrete":true, "isBool":true, "isBipolar":false}, + {"page":"112", "class":"SoundbankA", "index":36, "name":"Osc Mainvolume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":37, "name":"Noise Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":38, "name":"Ringmodulator Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|VirusC", "index":39, "name":"Noise Color", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":40, "name":"Cutoff", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":41, "name":"Cutoff2", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":42, "name":"Filter1 Resonance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":43, "name":"Filter2 Resonance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":44, "name":"Filter1 Env Amt", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":45, "name":"Filter2 Env Amt", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":46, "name":"Filter1 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":47, "name":"Filter2 Keyfollow", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":48, "name":"Filter Balance", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":49, "name":"Saturation Curve", "min":0, "max":14, "toText":"satCurve", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":51, "name":"Filter1 Mode", "min":0, "max":7, "toText":"filter1Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":52, "name":"Filter2 Mode", "min":0, "max":3, "toText":"filter2Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":53, "name":"Filter Routing", "min":0, "max":3, "toText":"filterRouting", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":54, "name":"Filter Env Attack", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":55, "name":"Filter Env Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":56, "name":"Filter Env Sustain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":57, "name":"Filter Env Sustain Time", "min":0, "max":127, "toText":"envSustainTime", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":58, "name":"Filter Env Release", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":59, "name":"Amp Env Attack", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":60, "name":"Amp Env Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":61, "name":"Amp Env Sustain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":62, "name":"Amp Env Sustain Time", "min":0, "max":127, "toText":"envSustainTime", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":63, "name":"Amp Env Release", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":64, "name":"Hold Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":65, "name":"Portamento Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"PerformanceController", "index":66, "name":"Sostenuto Pedal", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":67, "name":"Lfo1 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":68, "name":"Lfo1 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":69, "name":"Lfo1 Env Mode", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA", "index":70, "name":"Lfo1 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA", "index":71, "name":"Lfo1 Symmetry", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":72, "name":"Lfo1 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":73, "name":"Lfo1 Keytrigger", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":74, "name":"Osc1 Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":75, "name":"Osc2 Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":76, "name":"PW Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":77, "name":"Reso Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":78, "name":"FiltGain Lfo1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":79, "name":"Lfo2 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":80, "name":"Lfo2 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":81, "name":"Lfo2 Env Mode", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA", "index":82, "name":"Lfo2 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA", "index":83, "name":"Lfo2 Symmetry", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":84, "name":"Lfo2 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":85, "name":"Lfo2 Keytrigger", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":86, "name":"Shape Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":87, "name":"FM Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":88, "name":"Cutoff1 Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":89, "name":"Cutoff2 Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":90, "name":"Pan Lfo2 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":91, "name":"Patch Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":93, "name":"Transpose", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":94, "name":"Key Mode", "min":0, "max":5, "toText":"keyMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":97, "name":"Unison Mode", "min":0, "max":15, "toText":"unisonMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":98, "name":"Unison Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":99, "name":"Unison Pan Spread", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":100, "name":"Unison Lfo Phase", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":101, "name":"Input Mode", "min":0, "max":3, "toText":"inputMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":102, "name":"Input Select", "min":0, "max":8, "toText":"inputSelect", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":105, "name":"Chorus Mix", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":106, "name":"Chorus Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":107, "name":"Chorus Depth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":108, "name":"Chorus Delay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA", "index":109, "name":"Chorus Feedback", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA", "index":110, "name":"Chorus Lfo Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle", "index":112, "name":"Delay/Reverb Mode", "min":0, "max":26, "toText":"delayReverbMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle", "index":113, "name":"Effect Send", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":114, "name":"Delay Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":115, "name":"Delay Feedback", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":116, "name":"Dly Rate / Rev Decay", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":117, "name":"Dly Depth ", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":117, "name":"Rev Size", "min":0, "max":3, "toText":"reverbRoomSize", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":118, "name":"Delay Lfo Shape", "min":0, "max":5, "toText":"delayLfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":118, "name":"Reverb Damping", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":119, "name":"Delay Color", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":122, "name":"Keyb Local", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"112", "class":"SoundbankA|MultiOrSingle|NonPartSensitive", "index":123, "name":"All Notes Off", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":1, "name":"Arp Mode", "min":0, "max":6, "toText":"arpMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":2, "name":"Arp Pattern Selct", "min":0, "max":63, "toText":"unsignedOne", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":3, "name":"Arp Octave Range", "min":0, "max":3, "toText":"unsignedOne", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":4, "name":"Arp Hold Enable", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"B", "class":"SoundbankB", "index":5, "name":"Arp Note Length", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":6, "name":"Arp Swing", "min":0, "max":127, "toText":"arpSwing", "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":7, "name":"Lfo3 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":8, "name":"Lfo3 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":9, "name":"Lfo3 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"B", "class":"SoundbankB", "index":10, "name":"Lfo3 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":11, "name":"Lfo3 Destination", "min":0, "max":5, "toText":"lfoDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":12, "name":"Osc Lfo3 Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":13, "name":"Lfo3 Fade-In Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|MultiOrSingle|NonPartSensitive", "index":16, "name":"Clock Tempo", "min":0, "max":127, "toText":"bpm", "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":17, "name":"Arp Clock", "min":0, "max":17, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":18, "name":"Lfo1 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":19, "name":"Lfo2 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|MultiOrSingle|NonPartSensitive", "index":20, "name":"Delay Clock", "min":0, "max":16, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":21, "name":"Lfo3 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":25, "name":"Control Smooth Mode", "min":0, "max":3, "toText":"controlSmoothMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":26, "name":"Bender Range Up", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":true, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":27, "name":"Bender Range Down", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":true, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":28, "name":"Bender Scale", "min":0, "max":1, "toText":"linExp", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":30, "name":"Filter1 Env Polarity", "min":0, "max":1, "toText":"negPos", "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"B", "class":"SoundbankB", "index":31, "name":"Filter2 Env Polarity", "min":0, "max":1, "toText":"negPos", "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"B", "class":"SoundbankB", "index":32, "name":"Filter2 Cutoff Link", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, - {"page":"B", "class":"SoundbankB", "index":33, "name":"Filter Keytrack Base", "min":0, "max":127, "toText":"filterKeytrackBase", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":34, "name":"Osc FM Mode", "min":0, "max":12, "toText":"oscFMMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":35, "name":"Osc Init Phase", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":36, "name":"Punch Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":38, "name":"Input Follower Mode", "min":0, "max":9, "toText":"inputFollowerMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":39, "name":"Vocoder Mode", "min":0, "max":12, "toText":"vocoderMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":41, "name":"Osc3 Mode", "min":0, "max":67, "toText":"osc3Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":42, "name":"Osc3 Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":43, "name":"Osc3 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":44, "name":"Osc3 Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":45, "name":"LowEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":46, "name":"HighEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":47, "name":"Osc1 Shape Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":48, "name":"Osc2 Shape Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":49, "name":"PulseWidth Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":50, "name":"Fm Amount Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":51, "name":"Soft Knob1 ShortName", "min":0, "max":71, "toText":"softknobName", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":52, "name":"Soft Knob2 ShortName", "min":0, "max":71, "toText":"softknobName", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":54, "name":"Flt1 EnvAmt Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":55, "name":"Flt2 EnvAmt Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":56, "name":"Resonance1 Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":57, "name":"Resonance2 Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":58, "name":"Second Output Balance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":60, "name":"Amp Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":61, "name":"Panorama Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":62, "name":"Soft Knob-1 Single", "min":0, "max":117, "toText":"softknobDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":63, "name":"Soft Knob-2 Single", "min":0, "max":117, "toText":"softknobDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":64, "name":"Assign1 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":65, "name":"Assign1 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":66, "name":"Assign1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":67, "name":"Assign2 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":68, "name":"Assign2 Destination1", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":69, "name":"Assign2 Amount1", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":70, "name":"Assign2 Destination2", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":71, "name":"Assign2 Amount2", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":72, "name":"Assign3 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":73, "name":"Assign3 Destination1", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":74, "name":"Assign3 Amount1", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":75, "name":"Assign3 Destination2", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":76, "name":"Assign3 Amount2", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":77, "name":"Assign3 Destination3", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":78, "name":"Assign3 Amount3", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":79, "name":"LFO1 Assign Dest", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":80, "name":"LFO1 Assign Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB", "index":81, "name":"LFO2 Assign Dest", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":82, "name":"LFO2 Assign Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":84, "name":"Phaser Mode", "min":0, "max":6, "toText":"phaserMode", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":85, "name":"Phaser Mix", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":86, "name":"Phaser Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":87, "name":"Phaser Depth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":88, "name":"Phaser Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":89, "name":"Phaser Feedback", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":90, "name":"Phaser Spread", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":92, "name":"MidEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":93, "name":"MidEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":94, "name":"MidEQ Q-Factor", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":95, "name":"LowEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar": true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":96, "name":"HighEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar": true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":97, "name":"Bass Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":98, "name":"Bass Tune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":99, "name":"Input Ringmodulator", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":100, "name":"Distortion Curve", "min":0, "max":11, "toText":"distCurve", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":101, "name":"Distortion Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":103, "name":"Assign 4 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":104, "name":"Assign 4 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":105, "name":"Assign 4 Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":106, "name":"Assign 5 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":107, "name":"Assign 5 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":108, "name":"Assign 5 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":109, "name":"Assign 6 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":110, "name":"Assign 6 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB|VirusC", "index":111, "name":"Assign 6 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"B", "class":"SoundbankB|VirusC", "index":122, "name":"Filter Select", "min":0, "max":2, "toText":"filterSelect", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":123, "name":"Category1", "min":0, "max":16, "toText":"category", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"B", "class":"SoundbankB", "index":124, "name":"Category2", "min":0, "max":16, "toText":"category", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":1, "name":"Arp Mode", "min":0, "max":6, "toText":"arpMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":2, "name":"Arp Pattern Selct", "min":0, "max":63, "toText":"unsignedOne", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":3, "name":"Arp Octave Range", "min":0, "max":3, "toText":"unsignedOne", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":4, "name":"Arp Hold Enable", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"113", "class":"SoundbankB", "index":5, "name":"Arp Note Length", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":6, "name":"Arp Swing", "min":0, "max":127, "toText":"arpSwing", "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":7, "name":"Lfo3 Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":8, "name":"Lfo3 Shape", "min":0, "max":67, "toText":"lfoShape", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":9, "name":"Lfo3 Mode", "min":0, "max":1, "toText":"lfoMode", "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"113", "class":"SoundbankB", "index":10, "name":"Lfo3 Keyfollow", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":11, "name":"Lfo3 Destination", "min":0, "max":5, "toText":"lfoDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":12, "name":"Osc Lfo3 Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":13, "name":"Lfo3 Fade-In Time", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|MultiOrSingle|NonPartSensitive", "index":16, "name":"Clock Tempo", "min":0, "max":127, "toText":"bpm", "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":17, "name":"Arp Clock", "min":0, "max":17, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":18, "name":"Lfo1 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":19, "name":"Lfo2 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|MultiOrSingle|NonPartSensitive", "index":20, "name":"Delay Clock", "min":0, "max":16, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":21, "name":"Lfo3 Clock", "min":0, "max":21, "toText":"musicDivision", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":25, "name":"Control Smooth Mode", "min":0, "max":3, "toText":"controlSmoothMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":26, "name":"Bender Range Up", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":true, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":27, "name":"Bender Range Down", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":true, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":28, "name":"Bender Scale", "min":0, "max":1, "toText":"linExp", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":30, "name":"Filter1 Env Polarity", "min":0, "max":1, "toText":"negPos", "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"113", "class":"SoundbankB", "index":31, "name":"Filter2 Env Polarity", "min":0, "max":1, "toText":"negPos", "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"113", "class":"SoundbankB", "index":32, "name":"Filter2 Cutoff Link", "min":0, "max":1, "isPublic":true, "isDiscrete":false, "isBool":true}, + {"page":"113", "class":"SoundbankB", "index":33, "name":"Filter Keytrack Base", "min":0, "max":127, "toText":"filterKeytrackBase", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":34, "name":"Osc FM Mode", "min":0, "max":12, "toText":"oscFMMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":35, "name":"Osc Init Phase", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":36, "name":"Punch Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":38, "name":"Input Follower Mode", "min":0, "max":9, "toText":"inputFollowerMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":39, "name":"Vocoder Mode", "min":0, "max":12, "toText":"vocoderMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":41, "name":"Osc3 Mode", "min":0, "max":67, "toText":"osc3Mode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":42, "name":"Osc3 Volume", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":43, "name":"Osc3 Semitone", "min":16, "max":112, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":44, "name":"Osc3 Detune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":45, "name":"LowEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":46, "name":"HighEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":47, "name":"Osc1 Shape Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":48, "name":"Osc2 Shape Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":49, "name":"PulseWidth Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":50, "name":"Fm Amount Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":51, "name":"Soft Knob1 ShortName", "min":0, "max":71, "toText":"softknobName", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":52, "name":"Soft Knob2 ShortName", "min":0, "max":71, "toText":"softknobName", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":54, "name":"Flt1 EnvAmt Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":55, "name":"Flt2 EnvAmt Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":56, "name":"Resonance1 Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":57, "name":"Resonance2 Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":58, "name":"Second Output Balance", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":60, "name":"Amp Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":61, "name":"Panorama Velocity", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":62, "name":"Soft Knob-1 Single", "min":0, "max":117, "toText":"softknobDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":63, "name":"Soft Knob-2 Single", "min":0, "max":117, "toText":"softknobDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":64, "name":"Assign1 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":65, "name":"Assign1 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":66, "name":"Assign1 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":67, "name":"Assign2 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":68, "name":"Assign2 Destination1", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":69, "name":"Assign2 Amount1", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":70, "name":"Assign2 Destination2", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":71, "name":"Assign2 Amount2", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":72, "name":"Assign3 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":73, "name":"Assign3 Destination1", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":74, "name":"Assign3 Amount1", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":75, "name":"Assign3 Destination2", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":76, "name":"Assign3 Amount2", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":77, "name":"Assign3 Destination3", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":78, "name":"Assign3 Amount3", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":79, "name":"LFO1 Assign Dest", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":80, "name":"LFO1 Assign Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB", "index":81, "name":"LFO2 Assign Dest", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":82, "name":"LFO2 Assign Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":84, "name":"Phaser Mode", "min":0, "max":6, "toText":"phaserMode", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":85, "name":"Phaser Mix", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":86, "name":"Phaser Rate", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":87, "name":"Phaser Depth", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":88, "name":"Phaser Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":89, "name":"Phaser Feedback", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":90, "name":"Phaser Spread", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":92, "name":"MidEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":93, "name":"MidEQ Frequency", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":94, "name":"MidEQ Q-Factor", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":95, "name":"LowEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar": true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":96, "name":"HighEQ Gain", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar": true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":97, "name":"Bass Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":98, "name":"Bass Tune", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":99, "name":"Input Ringmodulator", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":100, "name":"Distortion Curve", "min":0, "max":11, "toText":"distCurve", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":101, "name":"Distortion Intensity", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":103, "name":"Assign 4 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":104, "name":"Assign 4 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":105, "name":"Assign 4 Amount", "min":0, "max":127, "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":106, "name":"Assign 5 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":107, "name":"Assign 5 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":108, "name":"Assign 5 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":109, "name":"Assign 6 Source", "min":0, "max":27, "toText":"modmatrixSource", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":110, "name":"Assign 6 Destination", "min":0, "max":122, "toText":"modmatrixDest", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB|VirusC", "index":111, "name":"Assign 6 Amount", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"113", "class":"SoundbankB|VirusC", "index":122, "name":"Filter Select", "min":0, "max":2, "toText":"filterSelect", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":123, "name":"Category1", "min":0, "max":16, "toText":"category", "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"113", "class":"SoundbankB", "index":124, "name":"Category2", "min":0, "max":16, "toText":"category", "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi|NonPartSensitive", "index":22, "name":"Delay Output Select", "min":0, "max":14, "toText":"outputSelect", "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi|BankProgramChangeParamBankSelect", "index":31, "name":"Part Bank Select", "min":0, "max":29, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi|BankProgramChangeParamBankSelect", "index":32, "name":"Part Bank Change", "min":0, "max":29, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi|BankProgramChangeParamBankSelect", "index":33, "name":"Part Program Change", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Multi", "index":34, "name":"Part Midi Channel", "min":0, "max":15, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi", "index":35, "name":"Part Low Key", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi", "index":36, "name":"Part High Key", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi", "index":37, "name":"Part Transpose", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"C", "class":"Multi", "index":38, "name":"Part Detune", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"C", "class":"Multi", "index":39, "name":"Part Volume", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Multi", "index":40, "name":"Part Midi Volume Init", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Multi", "index":41, "name":"Part Output Select", "min":0, "max":14, "toText":"outputSelect", "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":45, "name":"Second Output Select", "min":0, "max":15, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":63, "name":"Keyb Transpose Buttons", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":64, "name":"Keyb Local", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":65, "name":"Keyb Mode", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":66, "name":"Keyb Transpose", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"C", "class":"Global", "index":67, "name":"Keyb ModWheel Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":68, "name":"Keyb Pedal 1 Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":69, "name":"Keyb Pedal 2 Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":70, "name":"Keyb Pressure Sens", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Multi", "index":72, "name":"Part Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Multi", "index":73, "name":"Part Midi Volume Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Multi", "index":74, "name":"Part Hold Pedal Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Multi", "index":75, "name":"Keyb To Midi", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Multi", "index":77, "name":"Note Steal Priority", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Multi", "index":78, "name":"Part Prog Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":85, "name":"Glob Prog Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":86, "name":"MultiProg Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":87, "name":"Glob Midi Volume Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":90, "name":"Input Thru Level", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":91, "name":"Input Boost", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":92, "name":"Master Tune", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, - {"page":"C", "class":"Global", "index":93, "name":"Device ID", "min":0, "max":16, "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":94, "name":"Midi Control Low Page", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":95, "name":"Midi Control High Page", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":96, "name":"Midi Arpeggiator Send", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":97, "name":"Knob Display", "min":0, "max":3, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":98, "name":"Midi Dump Tx", "min":0, "max":4, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":99, "name":"Midi Dump Rx", "min":0, "max":4, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":105, "name":"Multi Program Change", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":106, "name":"Midi Clock Rx", "min":0, "max":3, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":110, "name":"Soft Knob-1 Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":111, "name":"Soft Knob-2 Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":112, "name":"Soft Knob-1 Global", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":113, "name":"Soft Knob-2 Global", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":114, "name":"Soft Knob-1 Midi", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":115, "name":"Soft Knob-2 Midi", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":116, "name":"Expert Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":117, "name":"Knob Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":118, "name":"Memory Protect", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, - {"page":"C", "class":"Global", "index":120, "name":"Soft Thru", "min":0, "max":1, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":121, "name":"Panel Destination", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":122, "name":"Play Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":123, "name":"Part Number", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, // $0 .. $15, $40 - {"page":"C", "class":"Global", "index":124, "name":"Global Channel", "min":0, "max":15, "isPublic":true, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":125, "name":"Led Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, - {"page":"C", "class":"Global", "index":126, "name":"LCD Contrast", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Global", "index":127, "name":"Master Volume", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Multi|NonPartSensitive", "index":22, "name":"Delay Output Select", "min":0, "max":14, "toText":"outputSelect", "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi|BankProgramChangeParamBankSelect", "index":31, "name":"Part Bank Select", "min":0, "max":29, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi|BankProgramChangeParamBankSelect", "index":32, "name":"Part Bank Change", "min":0, "max":29, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi|BankProgramChangeParamBankSelect", "index":33, "name":"Part Program Change", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Multi", "index":34, "name":"Part Midi Channel", "min":0, "max":15, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi", "index":35, "name":"Part Low Key", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi", "index":36, "name":"Part High Key", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi", "index":37, "name":"Part Transpose", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"114", "class":"Multi", "index":38, "name":"Part Detune", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"114", "class":"Multi", "index":39, "name":"Part Volume", "min":0, "max":127, "toText":"signed", "isPublic":true, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Multi", "index":40, "name":"Part Midi Volume Init", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Multi", "index":41, "name":"Part Output Select", "min":0, "max":14, "toText":"outputSelect", "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":45, "name":"Second Output Select", "min":0, "max":15, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":63, "name":"Keyb Transpose Buttons", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":64, "name":"Keyb Local", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":65, "name":"Keyb Mode", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":66, "name":"Keyb Transpose", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"114", "class":"Global", "index":67, "name":"Keyb ModWheel Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":68, "name":"Keyb Pedal 1 Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":69, "name":"Keyb Pedal 2 Contr", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":70, "name":"Keyb Pressure Sens", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Multi", "index":72, "name":"Part Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Multi", "index":73, "name":"Part Midi Volume Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Multi", "index":74, "name":"Part Hold Pedal Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Multi", "index":75, "name":"Keyb To Midi", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Multi", "index":77, "name":"Note Steal Priority", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Multi", "index":78, "name":"Part Prog Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":85, "name":"Glob Prog Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":86, "name":"MultiProg Change Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":87, "name":"Glob Midi Volume Enable", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":90, "name":"Input Thru Level", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":91, "name":"Input Boost", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":92, "name":"Master Tune", "min":0, "max":127, "toText":"signed", "isPublic":false, "isDiscrete":false, "isBool":false, "isBipolar":true}, + {"page":"114", "class":"Global", "index":93, "name":"Device ID", "min":0, "max":16, "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":94, "name":"Midi Control Low Page", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":95, "name":"Midi Control High Page", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":96, "name":"Midi Arpeggiator Send", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":97, "name":"Knob Display", "min":0, "max":3, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":98, "name":"Midi Dump Tx", "min":0, "max":4, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":99, "name":"Midi Dump Rx", "min":0, "max":4, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":105, "name":"Multi Program Change", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":106, "name":"Midi Clock Rx", "min":0, "max":3, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":110, "name":"Soft Knob-1 Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":111, "name":"Soft Knob-2 Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":112, "name":"Soft Knob-1 Global", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":113, "name":"Soft Knob-2 Global", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":114, "name":"Soft Knob-1 Midi", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":115, "name":"Soft Knob-2 Midi", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":116, "name":"Expert Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":117, "name":"Knob Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":118, "name":"Memory Protect", "min":0, "max":1, "isPublic":false, "isDiscrete":false, "isBool":true}, + {"page":"114", "class":"Global", "index":120, "name":"Soft Thru", "min":0, "max":1, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":121, "name":"Panel Destination", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":122, "name":"Play Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":123, "name":"Part Number", "min":0, "max":127, "isPublic":false, "isDiscrete":true, "isBool":false}, // $0 .. $15, $40 + {"page":"114", "class":"Global", "index":124, "name":"Global Channel", "min":0, "max":15, "isPublic":true, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":125, "name":"Led Mode", "min":0, "max":2, "isPublic":false, "isDiscrete":true, "isBool":false}, + {"page":"114", "class":"Global", "index":126, "name":"LCD Contrast", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Global", "index":127, "name":"Master Volume", "min":0, "max":127, "isPublic":false, "isDiscrete":false, "isBool":false}, // UNDEFINED / UNUSED / STUBS - {"page":"A", "class":"Undefined", "name":"Undefined92", "index":92 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined95", "index":95 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined96", "index":96 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined120", "index":120, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined121", "index":121, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined124", "index":124, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined125", "index":125, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined126", "index":126, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"A", "class":"Undefined", "name":"Undefined127", "index":127, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined92", "index":92 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined95", "index":95 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined96", "index":96 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined120", "index":120, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined121", "index":121, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined124", "index":124, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined125", "index":125, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined126", "index":126, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"112", "class":"Undefined", "name":"Undefined127", "index":127, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined0" , "index":0 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined14" , "index":14 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined15" , "index":15 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined22" , "index":22 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined23" , "index":23 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined24" , "index":24 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined29" , "index":29 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined37" , "index":37 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined40" , "index":40 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined53" , "index":53 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined69" , "index":69 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined83" , "index":83 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined91" , "index":91 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined123", "index":123, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined124", "index":124, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined0" , "index":0 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined14" , "index":14 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined15" , "index":15 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined22" , "index":22 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined23" , "index":23 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined24" , "index":24 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined29" , "index":29 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined37" , "index":37 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined40" , "index":40 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined53" , "index":53 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined69" , "index":69 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined83" , "index":83 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined91" , "index":91 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined123", "index":123, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined124", "index":124, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined0" , "index":0 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined1" , "index":1 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined2" , "index":2 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined3" , "index":3 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined4" , "index":4 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined15" , "index":15 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined16" , "index":16 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined17" , "index":17 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined18" , "index":18 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined19" , "index":19 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined20" , "index":20 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined21" , "index":21 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined23" , "index":23 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined24" , "index":24 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined25" , "index":25 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined26" , "index":26 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined27" , "index":27 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined28" , "index":28 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined29" , "index":29 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined30" , "index":30 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined76" , "index":76 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined79" , "index":79 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined80" , "index":80 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined81" , "index":81 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined82" , "index":82 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined83" , "index":83 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined84" , "index":84 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined88" , "index":88 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined89" , "index":89 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined100", "index":100, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined101", "index":101, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined102", "index":102, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined103", "index":103, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined104", "index":104, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined119", "index":119, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined0" , "index":0 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined1" , "index":1 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined2" , "index":2 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined3" , "index":3 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined4" , "index":4 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined15" , "index":15 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined16" , "index":16 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined17" , "index":17 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined18" , "index":18 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined19" , "index":19 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined20" , "index":20 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined21" , "index":21 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined23" , "index":23 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined24" , "index":24 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined25" , "index":25 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined26" , "index":26 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined27" , "index":27 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined28" , "index":28 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined29" , "index":29 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined30" , "index":30 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined76" , "index":76 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined79" , "index":79 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined80" , "index":80 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined81" , "index":81 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined82" , "index":82 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined83" , "index":83 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined84" , "index":84 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined88" , "index":88 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined89" , "index":89 , "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined100", "index":100, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined101", "index":101, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined102", "index":102, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined103", "index":103, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined104", "index":104, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined119", "index":119, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, // Text Chars / Unused - {"page":"B", "class":"Undefined", "name":"Undefined110", "index":110, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined112", "index":112, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined113", "index":113, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined114", "index":114, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined115", "index":115, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined116", "index":116, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined117", "index":117, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined118", "index":118, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined119", "index":119, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined120", "index":120, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"B", "class":"Undefined", "name":"Undefined121", "index":121, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined110", "index":110, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined111", "index":111, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined112", "index":112, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined113", "index":113, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined114", "index":114, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined115", "index":115, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined116", "index":116, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined117", "index":117, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined118", "index":118, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined119", "index":119, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined120", "index":120, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"113", "class":"Undefined", "name":"Undefined121", "index":121, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined5", "index":5, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined6", "index":6, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined7", "index":7, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined8", "index":8, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined9", "index":9, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined10", "index":10, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined11", "index":11, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined12", "index":12, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined13", "index":13, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, - {"page":"C", "class":"Undefined", "name":"Undefined14", "index":14, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false} + {"page":"114", "class":"Undefined", "name":"Undefined5", "index":5, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined6", "index":6, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined7", "index":7, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined8", "index":8, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined9", "index":9, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined10", "index":10, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined11", "index":11, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined12", "index":12, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined13", "index":13, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false}, + {"page":"114", "class":"Undefined", "name":"Undefined14", "index":14, "min":0, "max":127, "toText":"unsignedZero", "isPublic":false, "isDiscrete":false, "isBool":false} ], "valuelists": { diff --git a/source/jucePluginLib/CMakeLists.txt b/source/jucePluginLib/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.15) +project(jucePluginLib VERSION ${CMAKE_PROJECT_VERSION}) + +set(SOURCES + controller.cpp controller.h + midipacket.cpp midipacket.h + parameterdescription.cpp parameterdescription.h + parameterdescriptions.cpp parameterdescriptions.h +) + +add_library(jucePluginLib STATIC) + +target_sources(jucePluginLib PRIVATE ${SOURCES}) +source_group("source" FILES ${SOURCES}) + +target_include_directories(jucePluginLib PUBLIC ../JUCE/modules) +target_compile_definitions(jucePluginLib PRIVATE JUCE_GLOBAL_MODULE_SETTINGS_INCLUDED=1) diff --git a/source/jucePluginLib/controller.cpp b/source/jucePluginLib/controller.cpp @@ -0,0 +1,5 @@ +#include "controller.h" + +namespace pluginLib +{ +} diff --git a/source/jucePluginLib/controller.h b/source/jucePluginLib/controller.h @@ -0,0 +1,5 @@ +#pragma once + +namespace pluginLib +{ +} diff --git a/source/jucePluginLib/midipacket.cpp b/source/jucePluginLib/midipacket.cpp @@ -0,0 +1,5 @@ +#include "midipacket.h" + +namespace pluginLib +{ +} diff --git a/source/jucePluginLib/midipacket.h b/source/jucePluginLib/midipacket.h @@ -0,0 +1,5 @@ +#pragma once + +namespace pluginLib +{ +} diff --git a/source/jucePluginLib/parameterdescription.cpp b/source/jucePluginLib/parameterdescription.cpp @@ -0,0 +1,5 @@ +#include "parameterdescription.h" + +namespace pluginLib +{ +} diff --git a/source/jucePluginLib/parameterdescription.h b/source/jucePluginLib/parameterdescription.h @@ -0,0 +1,51 @@ +#pragma once + +#include <cstdint> +#include <functional> + +#include <juce_audio_processors/juce_audio_processors.h> + +namespace pluginLib +{ + 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]; + } + }; + enum class ParameterClass + { + None = 0x00, + Global = 0x01, + MultiOrSingle = 0x02, + NonPartSensitive = 0x04, + }; + struct Description + { + uint8_t page; + uint8_t index; + int classFlags; + juce::String name; + juce::Range<int> range; + ValueList valueList; + bool isPublic; + bool isDiscrete; + bool isBool; + bool isBipolar; + std::string toText; + }; +} diff --git a/source/jucePluginLib/parameterdescriptions.cpp b/source/jucePluginLib/parameterdescriptions.cpp @@ -0,0 +1,268 @@ +#include "parameterdescriptions.h" + +#include "../dsp56300/source/dsp56kEmu/logging.h" + +namespace pluginLib +{ + ParameterDescriptions::ParameterDescriptions(const std::string& _jsonString) + { + const auto err = loadJson(_jsonString); + LOG(err); + } + + std::string ParameterDescriptions::removeComments(std::string _json) + { + auto removeBlock = [&](const std::string& _begin, const std::string& _end) + { + const auto pos = _json.find(_begin); + + if (pos == std::string::npos) + return false; + + const auto end = _json.find(_end, pos + 1); + + if (end != std::string::npos) + _json.erase(pos, end - pos + _end.size()); + else + _json.erase(pos); + + return true; + }; + + while (removeBlock("//", "\n") || removeBlock("/*", "*/")) + { + } + + return _json; + } + + std::string ParameterDescriptions::loadJson(const std::string& _jsonString) + { + // juce' JSON parser doesn't like JSON5-style comments + const auto jsonString = removeComments(_jsonString); + + juce::var json; + + const auto error = juce::JSON::parse(juce::String(jsonString), json); + + if (error.failed()) + return std::string("Failed to parse JSON: ") + std::string(error.getErrorMessage().toUTF8()); + + const auto paramDescDefaults = json["parameterdescriptiondefaults"].getDynamicObject(); + const auto defaultProperties = paramDescDefaults ? paramDescDefaults->getProperties() : juce::NamedValueSet(); + const auto paramDescs = json["parameterdescriptions"]; + + const auto descsArray = paramDescs.getArray(); + + if (descsArray == nullptr) + return "Parameter descriptions are empty"; + + { + const auto valueLists = json["valuelists"]; + + auto* entries = valueLists.getDynamicObject(); + + if (!entries) + return "value lists are not defined"; + + auto entryProps = entries->getProperties(); + + for(int i=0; i<entryProps.size(); ++i) + { + const auto key = std::string(entryProps.getName(i).toString().toUTF8()); + const auto values = entryProps.getValueAt(i).getArray(); + + 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"; + + ValueList vl; + vl.texts.reserve(values->size()); + + for (auto&& value : *values) + { + 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_valueLists.insert(std::make_pair(key, vl)); + } + } + + std::stringstream errors; + + const auto& descs = *descsArray; + + for (int i = 0; i < descs.size(); ++i) + { + const auto& desc = descs[i].getDynamicObject(); + const auto props = desc->getProperties(); + + if (props.isEmpty()) + { + errors << "Parameter desc " << i << " has no properties defined" << std::endl; + continue; + } + + const auto name = props["name"].toString(); + + if (name.isEmpty()) + { + errors << "Parameter desc " << i << " doesn't have a name" << std::endl; + continue; + } + + auto readProperty = [&](const char* _key) + { + auto result = props[_key]; + if (!result.isVoid()) + return result; + result = defaultProperties[_key]; + if (result.isVoid()) + errors << "Property " << _key << " not found for parameter description " << name << " and no default provided" << std::endl; + return result; + }; + + auto readPropertyString = [&](const char* _key) + { + const auto res = readProperty(_key); + + if(!res.isString()) + errors << "Property " << _key << " of parameter desc " << name << " is not of type string" << std::endl; + + return std::string(res.toString().toUTF8()); + }; + + auto readPropertyInt = [&](const char* _key) + { + const auto res = readProperty(_key); + + if (!res.isInt()) + errors << "Property " << _key << " of parameter desc " << name << " is not of type int " << std::endl; + + return static_cast<int>(res); + }; + + auto readPropertyBool = [&](const char* _key) + { + const auto res = readProperty(_key); + + if (res.isInt()) + return static_cast<int>(res) != 0; + if (res.isBool()) + return static_cast<bool>(res); + + errors << "Property " << _key << " of parameter desc " << name << " is not of type bool " << std::endl; + + return static_cast<bool>(res); + }; + + const auto minValue = readPropertyInt("min"); + const auto maxValue = readPropertyInt("max"); + + if (minValue < 0 || minValue > 127) + { + errors << name << ": min value for parameter desc " << name << " must be in range 0-127 but min is set to " << minValue << std::endl; + continue; + } + if(maxValue < 0 || maxValue > 127) + { + errors << name << ": max value for parameter desc " << name << " must be in range 0-127 but max is set to " << maxValue << std::endl; + continue; + } + if (maxValue < minValue) + { + errors << name << ": max value must be larger than min value but min is " << minValue << ", max is " << maxValue << std::endl; + continue; + } + + const auto valueList = readPropertyString("toText"); + + const auto it = m_valueLists.find(valueList); + if(it == m_valueLists.end()) + { + errors << name << ": Value list " << valueList << " not found" << std::endl; + continue; + } + + const auto& list = *it; + + if((maxValue - minValue + 1) > static_cast<int>(list.second.texts.size())) + { + errors << name << ": value list " << valueList << " contains only " << list.second.texts.size() << " entries but parameter range is " << minValue << "-" << maxValue << std::endl; + } + + Description d; + + d.name = name; + + d.isPublic = readPropertyBool("isPublic"); + d.isDiscrete = readPropertyBool("isDiscrete"); + d.isBool = readPropertyBool("isBool"); + d.isBipolar = readPropertyBool("isBipolar"); + + d.toText = valueList; + d.index = static_cast<uint8_t>(readPropertyInt("index")); + + d.range.setStart(minValue); + d.range.setEnd(maxValue); + + d.valueList = it->second; + + { + d.classFlags = 0; + + const auto classFlags = readPropertyString("class"); + + std::vector<std::string> flags; + size_t off = 0; + + while (true) + { + const auto pos = classFlags.find('|', off); + + if(pos == std::string::npos) + { + flags.push_back(classFlags.substr(off)); + break; + } + + flags.push_back(classFlags.substr(off, pos - off)); + off = pos + 1; + } + + for (const auto & flag : flags) + { + if (flag == "Global") + d.classFlags |= static_cast<int>(ParameterClass::Global); + else if (flag == "MultiOrSingle") + d.classFlags |= static_cast<int>(ParameterClass::MultiOrSingle); + else if (flag == "NonPartSensitive") + d.classFlags |= static_cast<int>(ParameterClass::NonPartSensitive); + else + errors << "Class " << flag << " is unknown" << std::endl; + } + } + { + const auto page = readPropertyString("page"); + if(page.empty()) + { + errors << name << ": Page parameter must not be empty" << std::endl; + break; + } + + d.page = static_cast<uint8_t>(::atoi(page.c_str())); + } + + m_descriptions.push_back(d); + } + + return errors.str(); + } +} diff --git a/source/jucePluginLib/parameterdescriptions.h b/source/jucePluginLib/parameterdescriptions.h @@ -0,0 +1,29 @@ +#pragma once + +#include <map> +#include <string> +#include <vector> + +#include "parameterdescription.h" + +namespace pluginLib +{ + class ParameterDescriptions + { + public: + explicit ParameterDescriptions(const std::string& _jsonString); + + const std::vector<Description>& getDescriptions() const + { + return m_descriptions; + } + + static std::string removeComments(std::string _json); + + private: + std::string loadJson(const std::string& _jsonString); + + std::map<std::string, ValueList> m_valueLists; + std::vector<Description> m_descriptions; + }; +}