diff --git a/plugins/Cardinal/plugin.json b/plugins/Cardinal/plugin.json index d05bce01..1ef3af9f 100644 --- a/plugins/Cardinal/plugin.json +++ b/plugins/Cardinal/plugin.json @@ -75,6 +75,15 @@ "tags": [ "Utility" ] + }, + { + "slug": "CardinalExpIn8", + "disabled": false, + "name": "Cardinal Expander Inputs 8", + "description": "Expander to add 8 parameters CV inputs to Cardinal's plugin hosts", + "tags": [ + "Expander" + ] } ] } diff --git a/plugins/Cardinal/res/CardinalExpIn8.svg b/plugins/Cardinal/res/CardinalExpIn8.svg new file mode 100644 index 00000000..a40ba990 --- /dev/null +++ b/plugins/Cardinal/res/CardinalExpIn8.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/plugins/Cardinal/src/CardinalExpIn8.cpp b/plugins/Cardinal/src/CardinalExpIn8.cpp new file mode 100644 index 00000000..3b855ff2 --- /dev/null +++ b/plugins/Cardinal/src/CardinalExpIn8.cpp @@ -0,0 +1,88 @@ +//Expander module for Cardinal's plugin hosts +// +//Based on code from GateSeq64 and GateSeq64Expander by Marc Boulé +//Adapted for Ildaeil by Simon-L + +#include "plugin.hpp" +#include "expanders.hpp" + +static const unsigned int ildaeil_expanderRefreshStepSkips = 4; + +struct CardinalExpIn8 : CardinalExpander, Module { + + void sendExpMessage() { + for (int i = 0; i < NUM_INPUTS; i++) { + float *messageToBase = (float*)rightExpander.module->leftExpander.producerMessage; + messageToBase[i] = (inputs[i].isConnected() ? inputs[i].getVoltage() : 0.0); + } + rightExpander.module->leftExpander.messageFlipRequested = true; + } + + void processExpMessage() {} + + enum InputIds { + PARAM1_INPUT, + PARAM2_INPUT, + PARAM3_INPUT, + PARAM4_INPUT, + PARAM5_INPUT, + PARAM6_INPUT, + PARAM7_INPUT, + PARAM8_INPUT, + NUM_INPUTS + }; + + + CardinalExpIn8() { + config(0, NUM_INPUTS, 0, 0); + + rightExpander.producerMessage = rightMessages[0]; + rightExpander.consumerMessage = rightMessages[1]; + + configInput(PARAM1_INPUT, "Parameter 1"); + configInput(PARAM2_INPUT, "Parameter 2"); + configInput(PARAM3_INPUT, "Parameter 3"); + configInput(PARAM4_INPUT, "Parameter 4"); + configInput(PARAM5_INPUT, "Parameter 5"); + configInput(PARAM6_INPUT, "Parameter 6"); + configInput(PARAM7_INPUT, "Parameter 7"); + configInput(PARAM8_INPUT, "Parameter 8"); + + } + + void process(const ProcessArgs &args) override { + bool basePresent = (rightExpander.module && isCardinalExpandable(rightExpander.module)); + if (basePresent) { + sendExpMessage(); + } + }// process() +}; + + +struct CardinalExpIn8Widget : ModuleWidget { + CardinalExpIn8Widget(CardinalExpIn8 *module) { + setModule(module); + + setPanel(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CardinalExpIn8.svg"))); + box.size = Vec(RACK_GRID_WIDTH * 2, RACK_GRID_HEIGHT); + + // Screws + addChild(createWidget(Vec(0, 0))); + addChild(createWidget(Vec(0, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); + addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); + addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); + + // Inputs + addInput(createInput(Vec(3, 54 + 75), module, CardinalExpIn8::PARAM1_INPUT)); + addInput(createInput(Vec(3, 54 + 105), module, CardinalExpIn8::PARAM2_INPUT)); + addInput(createInput(Vec(3, 54 + 135), module, CardinalExpIn8::PARAM3_INPUT)); + addInput(createInput(Vec(3, 54 + 165), module, CardinalExpIn8::PARAM4_INPUT)); + addInput(createInput(Vec(3, 54 + 195), module, CardinalExpIn8::PARAM5_INPUT)); + addInput(createInput(Vec(3, 54 + 225), module, CardinalExpIn8::PARAM6_INPUT)); + addInput(createInput(Vec(3, 54 + 255), module, CardinalExpIn8::PARAM7_INPUT)); + addInput(createInput(Vec(3, 54 + 285), module, CardinalExpIn8::PARAM8_INPUT)); + } + +}; + +Model *modelCardinalExpIn8 = createModel("CardinalExpIn8"); diff --git a/plugins/Cardinal/src/Carla.cpp b/plugins/Cardinal/src/Carla.cpp index 33b034b3..abd0c20a 100644 --- a/plugins/Cardinal/src/Carla.cpp +++ b/plugins/Cardinal/src/Carla.cpp @@ -16,6 +16,7 @@ */ #include "plugincontext.hpp" +#include "expanders.hpp" #include "CarlaNativePlugin.h" #include "CarlaBackendUtils.hpp" @@ -54,7 +55,7 @@ static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpc // -------------------------------------------------------------------------------------------------------------------- -struct CarlaModule : Module { +struct CarlaModule : Module, CardinalExpander { enum ParamIds { BIPOLAR_INPUTS, BIPOLAR_OUTPUTS, @@ -123,6 +124,8 @@ struct CarlaModule : Module { std::memset(dataOut, 0, sizeof(dataOut)); + setupExpanding(this); + fCarlaPluginDescriptor = carla_get_native_patchbay_cv8_plugin(); DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginDescriptor != nullptr,); @@ -259,11 +262,34 @@ struct CarlaModule : Module { patchStorage = getPatchStorageDirectory(); } + void sendExpMessage() {} + + void processExpMessage() { + // Unimplemented + float *messagesFromExpander = (float*)leftExpander.consumerMessage; + if (carla_get_current_plugin_count(fCarlaHostHandle)) { + const uint32_t pcount = carla_get_parameter_count(fCarlaHostHandle, 0); + for (uint i = 0; i < 8; i++) { + if (i < pcount && leftExpander.module->inputs[i].isConnected()) { + const ::ParameterRanges* const pranges = carla_get_parameter_ranges(fCarlaHostHandle, 0, i); + float scaled_param = (messagesFromExpander[i] + 10.0) * (pranges->max - pranges->min) / (20.0 + pranges->min); + carla_set_parameter_value(fCarlaHostHandle, 0, i, scaled_param); + fCarlaHostDescriptor.ui_parameter_changed(this, i, scaled_param); + } + } + } + } + void process(const ProcessArgs& args) override { if (fCarlaPluginHandle == nullptr) return; + bool expanderPresent = (leftExpander.module && isCardinalExpander(leftExpander.module)); + if (expanderPresent) { + processExpMessage(); + } + const float inputOffset = params[BIPOLAR_INPUTS].getValue() > 0.1f ? -5.0f : 0.0f; const float outputOffset = params[BIPOLAR_OUTPUTS].getValue() > 0.1f ? -5.0f : 0.0f; diff --git a/plugins/Cardinal/src/Ildaeil.cpp b/plugins/Cardinal/src/Ildaeil.cpp index b826ad21..e75c2050 100644 --- a/plugins/Cardinal/src/Ildaeil.cpp +++ b/plugins/Cardinal/src/Ildaeil.cpp @@ -26,6 +26,7 @@ */ #include "plugincontext.hpp" +#include "expanders.hpp" #ifndef HEADLESS # include "ImGuiWidget.hpp" @@ -220,7 +221,7 @@ struct JuceInitializer { }; #endif -struct IldaeilModule : Module { +struct IldaeilModule : CardinalExpander, Module { enum ParamIds { NUM_PARAMS }; @@ -244,6 +245,23 @@ struct IldaeilModule : Module { NUM_LIGHTS }; + void sendExpMessage() {} + + void processExpMessage() { + float *messagesFromExpander = (float*)leftExpander.consumerMessage; + if (carla_get_current_plugin_count(fCarlaHostHandle)) { + const uint32_t pcount = carla_get_parameter_count(fCarlaHostHandle, 0); + for (uint i = 0; i < 8; i++) { + if (i < pcount && leftExpander.module->inputs[i].isConnected()) { + const ::ParameterRanges* const pranges = carla_get_parameter_ranges(fCarlaHostHandle, 0, i); + float scaled_param = (messagesFromExpander[i] + 10.0) * (pranges->max - pranges->min) / (20.0 + pranges->min); + carla_set_parameter_value(fCarlaHostHandle, 0, i, scaled_param); + fCarlaHostDescriptor.ui_parameter_changed(this, i, scaled_param); + } + } + } + } + #ifndef HEADLESS SharedResourcePointer juceInitializer; #endif @@ -273,6 +291,7 @@ struct IldaeilModule : Module { : pcontext(static_cast(APP)) { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + for (uint i=0; i<2; ++i) { const char name[] = { 'A','u','d','i','o',' ','#',static_cast('0'+i+1),'\0' }; @@ -289,6 +308,8 @@ struct IldaeilModule : Module { std::memset(audioDataOut1, 0, sizeof(audioDataOut1)); std::memset(audioDataOut2, 0, sizeof(audioDataOut2)); + setupExpanding(this); + fCarlaPluginDescriptor = carla_get_native_rack_plugin(); DISTRHO_SAFE_ASSERT_RETURN(fCarlaPluginDescriptor != nullptr,); @@ -432,6 +453,12 @@ struct IldaeilModule : Module { if (fCarlaPluginHandle == nullptr) return; + bool expanderPresent = (leftExpander.module && isCardinalExpander(leftExpander.module)); + if (expanderPresent) { + // d_stdout("hm?"); + processExpMessage(); + } + const unsigned i = audioDataFill++; audioDataIn1[i] = inputs[INPUT1].getVoltage() * 0.1f; @@ -1369,9 +1396,16 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { } else { + bool expanderPresent = (module->leftExpander.module && module->isCardinalExpander(module->leftExpander.module)); + const bool disabled = expanderPresent && (i < 8) && (module->leftExpander.module->inputs[i].isConnected()); + if (disabled) + ImGui::BeginDisabled(); const bool ret = param.log ? ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.format, 2.0f) : ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.format); + if (disabled) + ImGui::EndDisabled(); + if (ret) { if (ImGui::IsItemActivated()) diff --git a/plugins/Cardinal/src/expanders.hpp b/plugins/Cardinal/src/expanders.hpp new file mode 100644 index 00000000..063e408a --- /dev/null +++ b/plugins/Cardinal/src/expanders.hpp @@ -0,0 +1,21 @@ + +struct CardinalExpander +{ + CardinalExpander(){ + }; + virtual ~CardinalExpander(){}; + + bool isCardinalExpandable(Module *x) { return x->model == modelIldaeil || x->model == modelCarla; }; + bool isCardinalExpander(Module *x) { return x->model == modelCardinalExpIn8; }; + + virtual void sendExpMessage() = 0; + virtual void processExpMessage() = 0; + + float rightMessages[2][8] = {}; // messages from right-side + float leftMessages[2][8] = {};// messages from left-side + + void setupExpanding(Module *module) { + module->leftExpander.producerMessage = leftMessages[0]; + module->leftExpander.consumerMessage = leftMessages[1]; + } +}; \ No newline at end of file diff --git a/plugins/Cardinal/src/plugin.hpp b/plugins/Cardinal/src/plugin.hpp index 08044cbf..de7e8863 100644 --- a/plugins/Cardinal/src/plugin.hpp +++ b/plugins/Cardinal/src/plugin.hpp @@ -34,3 +34,4 @@ extern Model* modelHostCV; extern Model* modelHostParameters; extern Model* modelHostTime; extern Model* modelIldaeil; +extern Model* modelCardinalExpIn8; diff --git a/plugins/Makefile b/plugins/Makefile index 794e5969..97dcefd3 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -186,6 +186,7 @@ PLUGIN_FILES += Cardinal/src/HostCV.cpp PLUGIN_FILES += Cardinal/src/HostParameters.cpp PLUGIN_FILES += Cardinal/src/HostTime.cpp PLUGIN_FILES += Cardinal/src/Ildaeil.cpp +PLUGIN_FILES += Cardinal/src/CardinalExpIn8.cpp ifneq ($(HEADLESS),true) PLUGIN_FILES += Cardinal/src/ImGuiWidget.cpp diff --git a/plugins/plugins.cpp b/plugins/plugins.cpp index e588675b..0e438127 100644 --- a/plugins/plugins.cpp +++ b/plugins/plugins.cpp @@ -647,6 +647,7 @@ static void initStatic__Cardinal() p->addModel(modelHostParameters); p->addModel(modelHostTime); p->addModel(modelIldaeil); + p->addModel(modelCardinalExpIn8); } }