|
- /*
- * DISTRHO Cardinal Plugin
- * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 3 of
- * the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * For a full copy of the GNU General Public License see the LICENSE file.
- */
-
- #include "rack.hpp"
- #include "plugin.hpp"
-
- #include "DistrhoUtils.hpp"
-
- // Cardinal (built-in)
- #include "Cardinal/src/plugin.hpp"
-
- // Fundamental
- #include "Fundamental/src/plugin.hpp"
-
- // Aria
- extern Model* modelSpleet;
- extern Model* modelSwerge;
-
- // AudibleInstruments
- #include "AudibleInstruments/src/plugin.hpp"
-
- // BogaudioModules - integrate theme/skin support
- #include <mutex>
- #include <string>
- #include <unordered_map>
- #include <unordered_set>
- #include <vector>
- #define private public
- #include "BogaudioModules/src/skins.hpp"
- #undef private
-
- // BogaudioModules
- extern Model* modelAD;
- extern Model* modelBogaudioLFO;
- extern Model* modelBogaudioNoise;
- extern Model* modelBogaudioVCA;
- extern Model* modelBogaudioVCF;
- extern Model* modelBogaudioVCO;
- extern Model* modelOffset;
- extern Model* modelSampleHold;
- extern Model* modelSwitch;
- extern Model* modelSwitch18;
- extern Model* modelUnison;
-
- // MockbaModular
- #include "MockbaModular/src/plugin.hpp"
- #include "MockbaModular/src/MockbaModular.hpp"
- #undef min
- #define saveBack ignoreMockbaModular1
- #define loadBack ignoreMockbaModular2
- #include "MockbaModular/src/MockbaModular.cpp"
- #undef saveBack
- #undef loadBack
- std::string loadBack(int) { return "res/Empty_gray.svg"; }
-
- // surgext
- #include "surgext/src/SurgeXT.h"
- void surgext_rack_initialize();
- void surgext_rack_update_theme();
-
- // ValleyAudio
- #include "ValleyAudio/src/Valley.hpp"
-
- // known terminal modules
- std::vector<Model*> hostTerminalModels;
-
- // plugin instances
- Plugin* pluginInstance__Cardinal;
- Plugin* pluginInstance__Fundamental;
- Plugin* pluginInstance__Aria;
- Plugin* pluginInstance__AudibleInstruments;
- Plugin* pluginInstance__BogaudioModules;
- Plugin* pluginInstance__MockbaModular;
- Plugin* pluginInstance__surgext;
- Plugin* pluginInstance__ValleyAudio;
-
- namespace rack {
-
- namespace asset {
- std::string pluginManifest(const std::string& dirname);
- std::string pluginPath(const std::string& dirname);
- }
-
- namespace plugin {
-
- struct StaticPluginLoader {
- Plugin* const plugin;
- FILE* file;
- json_t* rootJ;
-
- StaticPluginLoader(Plugin* const p, const char* const name)
- : plugin(p),
- file(nullptr),
- rootJ(nullptr)
- {
- #ifdef DEBUG
- DEBUG("Loading plugin module %s", name);
- #endif
-
- p->path = asset::pluginPath(name);
-
- const std::string manifestFilename = asset::pluginManifest(name);
-
- if ((file = std::fopen(manifestFilename.c_str(), "r")) == nullptr)
- {
- d_stderr2("Manifest file %s does not exist", manifestFilename.c_str());
- return;
- }
-
- json_error_t error;
- if ((rootJ = json_loadf(file, 0, &error)) == nullptr)
- {
- d_stderr2("JSON parsing error at %s %d:%d %s", manifestFilename.c_str(), error.line, error.column, error.text);
- return;
- }
-
- // force ABI, we use static plugins so this doesnt matter as long as it builds
- json_t* const version = json_string((APP_VERSION_MAJOR + ".0").c_str());
- json_object_set(rootJ, "version", version);
- json_decref(version);
-
- // Load manifest
- p->fromJson(rootJ);
-
- // Reject plugin if slug already exists
- if (Plugin* const existingPlugin = getPlugin(p->slug))
- throw Exception("Plugin %s is already loaded, not attempting to load it again", p->slug.c_str());
- }
-
- ~StaticPluginLoader()
- {
- if (rootJ != nullptr)
- {
- // Load modules manifest
- json_t* const modulesJ = json_object_get(rootJ, "modules");
- plugin->modulesFromJson(modulesJ);
-
- json_decref(rootJ);
- plugins.push_back(plugin);
- }
-
- if (file != nullptr)
- std::fclose(file);
- }
-
- bool ok() const noexcept
- {
- return rootJ != nullptr;
- }
-
- void removeModule(const char* const slugToRemove) const noexcept
- {
- json_t* const modules = json_object_get(rootJ, "modules");
- DISTRHO_SAFE_ASSERT_RETURN(modules != nullptr,);
-
- size_t i;
- json_t* v;
- json_array_foreach(modules, i, v)
- {
- if (json_t* const slug = json_object_get(v, "slug"))
- {
- if (const char* const value = json_string_value(slug))
- {
- if (std::strcmp(value, slugToRemove) == 0)
- {
- json_array_remove(modules, i);
- break;
- }
- }
- }
- }
- }
- };
-
- static void initStatic__Cardinal()
- {
- Plugin* const p = new Plugin;
- pluginInstance__Cardinal = p;
-
- const StaticPluginLoader spl(p, "Cardinal");
- if (spl.ok())
- {
- p->addModel(modelHostAudio2);
- p->addModel(modelHostCV);
- p->addModel(modelHostMIDI);
- p->addModel(modelHostMIDICC);
- p->addModel(modelHostMIDIGate);
- p->addModel(modelHostMIDIMap);
- p->addModel(modelHostParameters);
- p->addModel(modelHostParametersMap);
- p->addModel(modelHostTime);
- p->addModel(modelTextEditor);
- /* TODO
- #ifdef HAVE_FFTW3F
- p->addModel(modelAudioToCVPitch);
- #else
- */
- spl.removeModule("AudioToCVPitch");
- /*
- #endif
- */
- spl.removeModule("AIDA-X");
- spl.removeModule("AudioFile");
- spl.removeModule("Blank");
- spl.removeModule("Carla");
- spl.removeModule("ExpanderInputMIDI");
- spl.removeModule("ExpanderOutputMIDI");
- spl.removeModule("HostAudio8");
- spl.removeModule("Ildaeil");
- spl.removeModule("MPV");
- spl.removeModule("SassyScope");
- spl.removeModule("glBars");
-
- hostTerminalModels = {
- modelHostAudio2,
- modelHostCV,
- modelHostMIDI,
- modelHostMIDICC,
- modelHostMIDIGate,
- modelHostMIDIMap,
- modelHostParameters,
- modelHostParametersMap,
- modelHostTime,
- };
- }
- }
-
- static void initStatic__Fundamental()
- {
- Plugin* const p = new Plugin;
- pluginInstance__Fundamental = p;
-
- const StaticPluginLoader spl(p, "Fundamental");
- if (spl.ok())
- {
- p->addModel(modelADSR);
- p->addModel(modelLFO);
- p->addModel(modelMerge);
- p->addModel(modelMidSide);
- p->addModel(modelNoise);
- p->addModel(modelQuantizer);
- p->addModel(modelRandom);
- p->addModel(modelScope);
- p->addModel(modelSplit);
- p->addModel(modelSum);
- p->addModel(modelVCA_1);
- p->addModel(modelVCF);
- p->addModel(modelVCMixer);
- p->addModel(modelVCO);
- spl.removeModule("8vert");
- spl.removeModule("Delay");
- spl.removeModule("LFO2");
- spl.removeModule("Mixer");
- spl.removeModule("Mutes");
- spl.removeModule("Octave");
- spl.removeModule("Pulses");
- spl.removeModule("SEQ3");
- spl.removeModule("SequentialSwitch1");
- spl.removeModule("SequentialSwitch2");
- spl.removeModule("VCA");
- spl.removeModule("VCO2");
- }
- }
-
- static void initStatic__Aria()
- {
- Plugin* const p = new Plugin;
- pluginInstance__Aria = p;
-
- const StaticPluginLoader spl(p, "AriaModules");
- if (spl.ok())
- {
- p->addModel(modelSpleet);
- p->addModel(modelSwerge);
-
- spl.removeModule("Aleister");
- spl.removeModule("Arcane");
- spl.removeModule("Atout");
- spl.removeModule("Blank");
- spl.removeModule("Darius");
- spl.removeModule("Grabby");
- spl.removeModule("Pokies4");
- spl.removeModule("Psychopump");
- spl.removeModule("Q");
- spl.removeModule("Qqqq");
- spl.removeModule("Quack");
- spl.removeModule("Quale");
- spl.removeModule("Rotatoes4");
- spl.removeModule("Smerge");
- spl.removeModule("Solomon16");
- spl.removeModule("Solomon4");
- spl.removeModule("Solomon8");
- spl.removeModule("Splirge");
- spl.removeModule("Splort");
- spl.removeModule("Undular");
-
- }
- }
-
- static void initStatic__AudibleInstruments()
- {
- Plugin* const p = new Plugin;
- pluginInstance__AudibleInstruments = p;
-
- const StaticPluginLoader spl(p, "AudibleInstruments");
- if (spl.ok())
- {
- p->addModel(modelPlaits);
-
- spl.removeModule("Blinds");
- spl.removeModule("Braids");
- spl.removeModule("Branches");
- spl.removeModule("Clouds");
- spl.removeModule("Elements");
- spl.removeModule("Frames");
- spl.removeModule("Kinks");
- spl.removeModule("Links");
- spl.removeModule("Marbles");
- spl.removeModule("Rings");
- spl.removeModule("Ripples");
- spl.removeModule("Shades");
- spl.removeModule("Shelves");
- spl.removeModule("Stages");
- spl.removeModule("Streams");
- spl.removeModule("Tides");
- spl.removeModule("Tides2");
- spl.removeModule("Veils");
- spl.removeModule("Warps");
- }
- }
-
- static void initStatic__BogaudioModules()
- {
- Plugin* const p = new Plugin;
- pluginInstance__BogaudioModules = p;
-
- const StaticPluginLoader spl(p, "BogaudioModules");
- if (spl.ok())
- {
- // Make sure to use match Cardinal theme
- Skins& skins(Skins::skins());
- skins._default = settings::preferDarkPanels ? "dark" : "light";
-
- p->addModel(modelAD);
- p->addModel(modelBogaudioLFO);
- p->addModel(modelBogaudioNoise);
- p->addModel(modelBogaudioVCA);
- p->addModel(modelBogaudioVCF);
- p->addModel(modelBogaudioVCO);
- p->addModel(modelOffset);
- p->addModel(modelSampleHold);
- p->addModel(modelSwitch);
- p->addModel(modelSwitch18);
- p->addModel(modelUnison);
-
- // cat plugins/BogaudioModules/plugin.json | jq -r .modules[].slug - | sort
- spl.removeModule("Bogaudio-Additator");
- spl.removeModule("Bogaudio-AddrSeq");
- spl.removeModule("Bogaudio-AddrSeqX");
- spl.removeModule("Bogaudio-ADSR");
- spl.removeModule("Bogaudio-AMRM");
- spl.removeModule("Bogaudio-Analyzer");
- spl.removeModule("Bogaudio-AnalyzerXL");
- spl.removeModule("Bogaudio-Arp");
- spl.removeModule("Bogaudio-ASR");
- spl.removeModule("Bogaudio-Assign");
- spl.removeModule("Bogaudio-Blank3");
- spl.removeModule("Bogaudio-Blank6");
- spl.removeModule("Bogaudio-Bool");
- spl.removeModule("Bogaudio-Chirp");
- spl.removeModule("Bogaudio-Clpr");
- spl.removeModule("Bogaudio-Cmp");
- spl.removeModule("Bogaudio-CmpDist");
- spl.removeModule("Bogaudio-CVD");
- spl.removeModule("Bogaudio-DADSRH");
- spl.removeModule("Bogaudio-DADSRHPlus");
- spl.removeModule("Bogaudio-Detune");
- spl.removeModule("Bogaudio-DGate");
- spl.removeModule("Bogaudio-Edge");
- spl.removeModule("Bogaudio-EightFO");
- spl.removeModule("Bogaudio-EightOne");
- spl.removeModule("Bogaudio-EQ");
- spl.removeModule("Bogaudio-EQS");
- spl.removeModule("Bogaudio-FFB");
- spl.removeModule("Bogaudio-FlipFlop");
- spl.removeModule("Bogaudio-FMOp");
- spl.removeModule("Bogaudio-Follow");
- spl.removeModule("Bogaudio-FourFO");
- spl.removeModule("Bogaudio-FourMan");
- spl.removeModule("Bogaudio-Inv");
- spl.removeModule("Bogaudio-Lgsw");
- spl.removeModule("Bogaudio-LLFO");
- spl.removeModule("Bogaudio-LLPG");
- spl.removeModule("Bogaudio-Lmtr");
- spl.removeModule("Bogaudio-LPG");
- spl.removeModule("Bogaudio-LVCF");
- spl.removeModule("Bogaudio-LVCO");
- spl.removeModule("Bogaudio-Manual");
- spl.removeModule("Bogaudio-Matrix18");
- spl.removeModule("Bogaudio-Matrix44");
- spl.removeModule("Bogaudio-Matrix44Cvm");
- spl.removeModule("Bogaudio-Matrix81");
- spl.removeModule("Bogaudio-Matrix88");
- spl.removeModule("Bogaudio-Matrix88Cv");
- spl.removeModule("Bogaudio-Matrix88M");
- spl.removeModule("Bogaudio-MegaGate");
- spl.removeModule("Bogaudio-Mix1");
- spl.removeModule("Bogaudio-Mix2");
- spl.removeModule("Bogaudio-Mix4");
- spl.removeModule("Bogaudio-Mix4x");
- spl.removeModule("Bogaudio-Mix8");
- spl.removeModule("Bogaudio-Mix8x");
- spl.removeModule("Bogaudio-Mono");
- spl.removeModule("Bogaudio-Mult");
- spl.removeModule("Bogaudio-Mumix");
- spl.removeModule("Bogaudio-Mute8");
- spl.removeModule("Bogaudio-Nsgt");
- spl.removeModule("Bogaudio-OneEight");
- spl.removeModule("Bogaudio-Pan");
- spl.removeModule("Bogaudio-PEQ");
- spl.removeModule("Bogaudio-PEQ14");
- spl.removeModule("Bogaudio-PEQ14XF");
- spl.removeModule("Bogaudio-PEQ6");
- spl.removeModule("Bogaudio-PEQ6XF");
- spl.removeModule("Bogaudio-Pgmr");
- spl.removeModule("Bogaudio-PgmrX");
- spl.removeModule("Bogaudio-PolyCon");
- spl.removeModule("Bogaudio-PolyCon8");
- spl.removeModule("Bogaudio-PolyMult");
- spl.removeModule("Bogaudio-PolyOff16");
- spl.removeModule("Bogaudio-PolyOff8");
- spl.removeModule("Bogaudio-Pressor");
- spl.removeModule("Bogaudio-Pulse");
- spl.removeModule("Bogaudio-Ranalyzer");
- spl.removeModule("Bogaudio-Reftone");
- spl.removeModule("Bogaudio-RGate");
- spl.removeModule("Bogaudio-Shaper");
- spl.removeModule("Bogaudio-ShaperPlus");
- spl.removeModule("Bogaudio-Sine");
- spl.removeModule("Bogaudio-Slew");
- spl.removeModule("Bogaudio-Stack");
- spl.removeModule("Bogaudio-Sums");
- spl.removeModule("Bogaudio-Switch1616");
- spl.removeModule("Bogaudio-Switch44");
- spl.removeModule("Bogaudio-Switch81");
- spl.removeModule("Bogaudio-Switch88");
- spl.removeModule("Bogaudio-UMix");
- spl.removeModule("Bogaudio-VCAmp");
- spl.removeModule("Bogaudio-VCM");
- spl.removeModule("Bogaudio-Velo");
- spl.removeModule("Bogaudio-Vish");
- spl.removeModule("Bogaudio-VU");
- spl.removeModule("Bogaudio-Walk");
- spl.removeModule("Bogaudio-Walk2");
- spl.removeModule("Bogaudio-XCO");
- spl.removeModule("Bogaudio-XFade");
- }
- }
-
- static void initStatic__MockbaModular()
- {
- Plugin* const p = new Plugin;
- pluginInstance__MockbaModular = p;
-
- const StaticPluginLoader spl(p, "MockbaModular");
- if (spl.ok())
- {
- p->addModel(modelCZOsc);
- p->addModel(modelFiltah);
- p->addModel(modelMaugOsc);
- p->addModel(modelMixah);
- p->addModel(modelPannah);
- p->addModel(modelReVoltah);
- p->addModel(modelShapah);
-
- spl.removeModule("Blank");
- spl.removeModule("Comparator");
- spl.removeModule("Countah");
- spl.removeModule("CZDblSine");
- spl.removeModule("CZPulse");
- spl.removeModule("CZReso1");
- spl.removeModule("CZReso2");
- spl.removeModule("CZReso3");
- spl.removeModule("CZSaw");
- spl.removeModule("CZSawPulse");
- spl.removeModule("CZSquare");
- spl.removeModule("Dividah");
- spl.removeModule("DualBUFFER");
- spl.removeModule("DualNOT");
- spl.removeModule("DualOR");
- spl.removeModule("DualNOR");
- spl.removeModule("DualAND");
- spl.removeModule("DualNAND");
- spl.removeModule("DualXOR");
- spl.removeModule("DualXNOR");
- spl.removeModule("Feidah");
- spl.removeModule("FeidahS");
- spl.removeModule("Holdah");
- spl.removeModule("MaugSaw");
- spl.removeModule("MaugSaw2");
- spl.removeModule("MaugShark");
- spl.removeModule("MaugSquare");
- spl.removeModule("MaugSquare2");
- spl.removeModule("MaugSquare3");
- spl.removeModule("MaugTriangle");
- spl.removeModule("Mixah3");
- spl.removeModule("PSelectah");
- spl.removeModule("Selectah");
- spl.removeModule("UDPClockMaster");
- spl.removeModule("UDPClockSlave");
- }
- }
-
- static void initStatic__surgext()
- {
- Plugin* const p = new Plugin;
- pluginInstance__surgext = p;
-
- const StaticPluginLoader spl(p, "surgext");
- if (spl.ok())
- {
- p->addModel(modelVCOModern);
- p->addModel(modelVCOSine);
- /*
- p->addModel(modelVCOAlias);
- p->addModel(modelVCOClassic);
- p->addModel(modelVCOFM2);
- p->addModel(modelVCOFM3);
- p->addModel(modelVCOSHNoise);
- p->addModel(modelVCOString);
- p->addModel(modelVCOTwist);
- p->addModel(modelVCOWavetable);
- p->addModel(modelVCOWindow);
- */
- spl.removeModule("SurgeXTOSCAlias");
- spl.removeModule("SurgeXTOSCClassic");
- spl.removeModule("SurgeXTOSCFM2");
- spl.removeModule("SurgeXTOSCFM3");
- spl.removeModule("SurgeXTOSCSHNoise");
- spl.removeModule("SurgeXTOSCString");
- spl.removeModule("SurgeXTOSCTwist");
- spl.removeModule("SurgeXTOSCWavetable");
- spl.removeModule("SurgeXTOSCWindow");
-
- // Add the ported ones
- p->addModel(modelSurgeLFO);
- p->addModel(modelSurgeMixer);
- p->addModel(modelSurgeMixerSlider);
- p->addModel(modelSurgeModMatrix);
- p->addModel(modelSurgeWaveshaper);
- /*
- p->addModel(modelSurgeDelay);
- p->addModel(modelSurgeDelayLineByFreq);
- p->addModel(modelSurgeDelayLineByFreqExpanded);
- p->addModel(modelSurgeDigitalRingMods);
- p->addModel(modelSurgeVCF);
- */
- spl.removeModule("SurgeXTDelay");
- spl.removeModule("SurgeXTDelayLineByFreq");
- spl.removeModule("SurgeXTDelayLineByFreqExpanded");
- spl.removeModule("SurgeXTDigitalRingMod");
- spl.removeModule("SurgeXTVCF");
-
- p->addModel(modelFXNimbus);
- spl.removeModule("SurgeXTFXBonsai");
- spl.removeModule("SurgeXTFXChorus");
- spl.removeModule("SurgeXTFXChow");
- spl.removeModule("SurgeXTFXCombulator");
- spl.removeModule("SurgeXTDigitalRingMod");
- spl.removeModule("SurgeXTFXDistortion");
- spl.removeModule("SurgeXTFXExciter");
- spl.removeModule("SurgeXTFXEnsemble");
- spl.removeModule("SurgeXTFXFlanger");
- spl.removeModule("SurgeXTFXFrequencyShifter");
- spl.removeModule("SurgeXTFXNeuron");
- spl.removeModule("SurgeXTFXPhaser");
- spl.removeModule("SurgeXTFXResonator");
- spl.removeModule("SurgeXTFXReverb");
- spl.removeModule("SurgeXTFXReverb2");
- spl.removeModule("SurgeXTFXRingMod");
- spl.removeModule("SurgeXTFXRotarySpeaker");
- spl.removeModule("SurgeXTFXSpringReverb");
- spl.removeModule("SurgeXTFXTreeMonster");
- spl.removeModule("SurgeXTFXVocoder");
-
- /*
- p->addModel(modelEGxVCA);
- p->addModel(modelQuadAD);
- p->addModel(modelQuadLFO);
- p->addModel(modelUnisonHelper);
- p->addModel(modelUnisonHelperCVExpander);
- */
- spl.removeModule("SurgeXTEGxVCA");
- spl.removeModule("SurgeXTQuadAD");
- spl.removeModule("SurgeXTQuadLFO");
- spl.removeModule("SurgeXTUnisonHelper");
- spl.removeModule("SurgeXTUnisonHelperCVExpander");
-
- surgext_rack_initialize();
- }
- }
-
- /*
- static void initStatic__ValleyAudio()
- {
- Plugin* const p = new Plugin;
- pluginInstance__ValleyAudio = p;
-
- const StaticPluginLoader spl(p, "ValleyAudio");
- if (spl.ok())
- {
- p->addModel(modelDexter);
- p->addModel(modelInterzone);
-
- spl.removeModule("Amalgam");
- spl.removeModule("Feline");
- spl.removeModule("Plateau");
- spl.removeModule("Terrorform");
- spl.removeModule("Topograph");
- spl.removeModule("uGraph");
- }
- }
- */
-
- void initStaticPlugins()
- {
- initStatic__Cardinal();
- initStatic__Fundamental();
- initStatic__Aria();
- initStatic__AudibleInstruments();
- initStatic__BogaudioModules();
- initStatic__MockbaModular();
- initStatic__surgext();
- /*
- initStatic__ValleyAudio();
- */
- }
-
- void destroyStaticPlugins()
- {
- for (Plugin* p : plugins)
- delete p;
- plugins.clear();
- }
-
- void updateStaticPluginsDarkMode()
- {
- const bool darkMode = settings::preferDarkPanels;
- // bogaudio
- {
- Skins& skins(Skins::skins());
- skins._default = darkMode ? "dark" : "light";
-
- std::lock_guard<std::mutex> lock(skins._defaultSkinListenersLock);
- for (auto listener : skins._defaultSkinListeners) {
- listener->defaultSkinChanged(skins._default);
- }
- }
- // surgext
- {
- surgext_rack_update_theme();
- }
- }
-
- }
- }
|