From 0a659efafd83517a820f94a292ae84cd1e2aff6f Mon Sep 17 00:00:00 2001 From: scanner darkly Date: Sat, 25 May 2024 11:10:05 -0700 Subject: [PATCH] comparator --- dev/cpp_comparator.cpp | 115 +++++++++++++ dev/panel_comparator.svg | 356 +++++++++++++++++++++++++++++++++++++++ dev/plugin.json | 6 + dev/run_comparator.bat | 1 + plugin.json | 10 ++ res/SDComparator.svg | 121 +++++++++++++ src/SDComparator.cpp | 165 ++++++++++++++++++ src/plugin.cpp | 1 + src/plugin.hpp | 3 +- 9 files changed, 777 insertions(+), 1 deletion(-) create mode 100644 dev/cpp_comparator.cpp create mode 100644 dev/panel_comparator.svg create mode 100644 dev/run_comparator.bat create mode 100644 res/SDComparator.svg create mode 100644 src/SDComparator.cpp diff --git a/dev/cpp_comparator.cpp b/dev/cpp_comparator.cpp new file mode 100644 index 0000000..b33f849 --- /dev/null +++ b/dev/cpp_comparator.cpp @@ -0,0 +1,115 @@ +#include "plugin.hpp" + + +struct SDComparator : Module { + enum ParamId { + LEVEL1_PARAM, + LEVEL2_PARAM, + LEVEL3_PARAM, + LEVEL4_PARAM, + LEVEL5_PARAM, + LEVEL6_PARAM, + LEVEL7_PARAM, + LEVEL8_PARAM, + MODE_PARAM, + PARAMS_LEN + }; + enum InputId { + LEVELS_INPUT, + INPUT_INPUT, + INPUTS_LEN + }; + enum OutputId { + GATE1_OUTPUT, + GATE2_OUTPUT, + GATE3_OUTPUT, + GATE4_OUTPUT, + GATE5_OUTPUT, + GATE6_OUTPUT, + GATE7_OUTPUT, + GATE8_OUTPUT, + OUTPUT_OUTPUT, + OUTPUTS_LEN + }; + enum LightId { + GATEON1_LIGHT, + GATEON2_LIGHT, + GATEON3_LIGHT, + GATEON4_LIGHT, + GATEON5_LIGHT, + GATEON6_LIGHT, + GATEON7_LIGHT, + GATEON8_LIGHT, + LIGHTS_LEN + }; + + SDComparator() { + config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN); + configParam(LEVEL1_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL2_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL3_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL4_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL5_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL6_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL7_PARAM, 0.f, 1.f, 0.f, ""); + configParam(LEVEL8_PARAM, 0.f, 1.f, 0.f, ""); + configParam(MODE_PARAM, 0.f, 1.f, 0.f, ""); + configInput(LEVELS_INPUT, ""); + configInput(INPUT_INPUT, ""); + configOutput(GATE1_OUTPUT, ""); + configOutput(GATE2_OUTPUT, ""); + configOutput(GATE3_OUTPUT, ""); + configOutput(GATE4_OUTPUT, ""); + configOutput(GATE5_OUTPUT, ""); + configOutput(GATE6_OUTPUT, ""); + configOutput(GATE7_OUTPUT, ""); + configOutput(GATE8_OUTPUT, ""); + configOutput(OUTPUT_OUTPUT, ""); + } + + void process(const ProcessArgs& args) override { + } +}; + + +struct SDComparatorWidget : ModuleWidget { + SDComparatorWidget(SDComparator* module) { + setModule(module); + setPanel(createPanel(asset::plugin(pluginInstance, "res/SDComparator.svg"))); + + addParam(createParamCentered(mm2px(Vec(6.271, 13.126)), module, SDComparator::LEVEL1_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 24.148)), module, SDComparator::LEVEL2_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 35.17)), module, SDComparator::LEVEL3_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 46.192)), module, SDComparator::LEVEL4_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 57.214)), module, SDComparator::LEVEL5_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 68.236)), module, SDComparator::LEVEL6_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 79.258)), module, SDComparator::LEVEL7_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 90.28)), module, SDComparator::LEVEL8_PARAM)); + addParam(createParam(mm2px(Vec(15.617, 101.089)), module, SDComparator::MODE_PARAM)); + + addInput(createInputCentered(mm2px(Vec(6.651, 104.61)), module, SDComparator::LEVELS_INPUT)); + addInput(createInputCentered(mm2px(Vec(6.651, 119.319)), module, SDComparator::INPUT_INPUT)); + + addOutput(createOutputCentered(mm2px(Vec(18.749, 13.126)), module, SDComparator::GATE1_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 24.148)), module, SDComparator::GATE2_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 35.17)), module, SDComparator::GATE3_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 46.192)), module, SDComparator::GATE4_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 57.214)), module, SDComparator::GATE5_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 68.236)), module, SDComparator::GATE6_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 79.258)), module, SDComparator::GATE7_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 90.28)), module, SDComparator::GATE8_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(17.836, 119.318)), module, SDComparator::OUTPUT_OUTPUT)); + + addChild(createLightCentered>(mm2px(Vec(12.7, 13.126)), module, SDComparator::GATEON1_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 24.148)), module, SDComparator::GATEON2_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 35.17)), module, SDComparator::GATEON3_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 46.192)), module, SDComparator::GATEON4_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 57.214)), module, SDComparator::GATEON5_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 68.236)), module, SDComparator::GATEON6_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 79.258)), module, SDComparator::GATEON7_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 90.28)), module, SDComparator::GATEON8_LIGHT)); + } +}; + + +Model* modelSDComparator = createModel("SDComparator"); \ No newline at end of file diff --git a/dev/panel_comparator.svg b/dev/panel_comparator.svg new file mode 100644 index 0000000..4ee0d2f --- /dev/null +++ b/dev/panel_comparator.svg @@ -0,0 +1,356 @@ + + + +image/svg+xmlCOMPARATORLEVELSLEVELSGATESOUTINMODE diff --git a/dev/plugin.json b/dev/plugin.json index 468ed77..8288788 100644 --- a/dev/plugin.json +++ b/dev/plugin.json @@ -43,6 +43,12 @@ "name": "SDTransgate", "description": "", "tags": [] + }, + { + "slug": "SDComparator", + "name": "SDComparator", + "description": "", + "tags": [] } ] } \ No newline at end of file diff --git a/dev/run_comparator.bat b/dev/run_comparator.bat new file mode 100644 index 0000000..a6123d2 --- /dev/null +++ b/dev/run_comparator.bat @@ -0,0 +1 @@ +python helper.py createmodule SDComparator panel_comparator.svg cpp_comparator.cpp diff --git a/plugin.json b/plugin.json index 7558500..d2b4921 100644 --- a/plugin.json +++ b/plugin.json @@ -50,6 +50,16 @@ "Polyphonic", "Utility" ] + }, + { + "slug": "SDComparator", + "name": "comparator", + "description": "polyphonic comparator", + "manualUrl": "https://github.com/scanner-darkly/eightfold#comparator", + "tags": [ + "Polyphonic", + "Utility" + ] } ] } \ No newline at end of file diff --git a/res/SDComparator.svg b/res/SDComparator.svg new file mode 100644 index 0000000..a0754c9 --- /dev/null +++ b/res/SDComparator.svg @@ -0,0 +1,121 @@ + + + +image/svg+xml diff --git a/src/SDComparator.cpp b/src/SDComparator.cpp new file mode 100644 index 0000000..c944854 --- /dev/null +++ b/src/SDComparator.cpp @@ -0,0 +1,165 @@ +#include "plugin.hpp" +#include "SDSharedComponents.hpp" + +#define CHANNEL_COUNT 8 + +struct SDComparator : Module { + enum ParamId { + LEVEL1_PARAM, + LEVEL2_PARAM, + LEVEL3_PARAM, + LEVEL4_PARAM, + LEVEL5_PARAM, + LEVEL6_PARAM, + LEVEL7_PARAM, + LEVEL8_PARAM, + MODE_PARAM, + PARAMS_LEN + }; + enum InputId { + LEVELS_INPUT, + INPUT_INPUT, + INPUTS_LEN + }; + enum OutputId { + GATE1_OUTPUT, + GATE2_OUTPUT, + GATE3_OUTPUT, + GATE4_OUTPUT, + GATE5_OUTPUT, + GATE6_OUTPUT, + GATE7_OUTPUT, + GATE8_OUTPUT, + OUTPUT_OUTPUT, + OUTPUTS_LEN + }; + enum LightId { + GATEON1_LIGHT, + GATEON2_LIGHT, + GATEON3_LIGHT, + GATEON4_LIGHT, + GATEON5_LIGHT, + GATEON6_LIGHT, + GATEON7_LIGHT, + GATEON8_LIGHT, + LIGHTS_LEN + }; + + SDComparator() { + config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN); + + configParam(LEVEL1_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL2_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL3_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL4_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL5_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL6_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL7_PARAM, -10.f, 10.f, 0.f, ""); + configParam(LEVEL8_PARAM, -10.f, 10.f, 0.f, ""); + + configSwitch(MODE_PARAM, 0.0, 1.0, 0.0, "Mode", {"Dot", "Bar"}); + getParamQuantity(MODE_PARAM)->randomizeEnabled = false; + + configInput(LEVELS_INPUT, "Threshold Levels"); + configInput(INPUT_INPUT, "Input"); + + configOutput(GATE1_OUTPUT, "Gate 1"); + configOutput(GATE2_OUTPUT, "Gate 2"); + configOutput(GATE3_OUTPUT, "Gate 3"); + configOutput(GATE4_OUTPUT, "Gate 4"); + configOutput(GATE5_OUTPUT, "Gate 5"); + configOutput(GATE6_OUTPUT, "Gate 6"); + configOutput(GATE7_OUTPUT, "Gate 7"); + configOutput(GATE8_OUTPUT, "Gate 8"); + + configOutput(OUTPUT_OUTPUT, "Output"); + + configLight(GATEON1_LIGHT, "Gate 1"); + configLight(GATEON2_LIGHT, "Gate 2"); + configLight(GATEON3_LIGHT, "Gate 3"); + configLight(GATEON4_LIGHT, "Gate 4"); + configLight(GATEON5_LIGHT, "Gate 5"); + configLight(GATEON6_LIGHT, "Gate 6"); + configLight(GATEON7_LIGHT, "Gate 7"); + configLight(GATEON8_LIGHT, "Gate 8"); + } + + void process(const ProcessArgs& args) override { + + bool gates[CHANNEL_COUNT]; + float level, voltage, highest; + voltage = inputs[INPUT_INPUT].getVoltage(); + highest = -100.f; + int highest_index = -1; + bool higher; + + for (int i = 0; i < CHANNEL_COUNT; i++) { + level = inputs[LEVELS_INPUT].getVoltage(i) + params[LEVEL1_PARAM + i].getValue(); + higher = voltage >= level; + + gates[i] = higher; + if (higher && level > highest) { + highest_index = i; + highest = level; + } + } + + if (params[MODE_PARAM].getValue() == 1) { // dot + for (int i = 0; i < CHANNEL_COUNT; i++) { + lights[GATEON1_LIGHT + i].setBrightness(i == highest_index ? 1.f : 0.f); + outputs[GATE1_OUTPUT + i].setVoltage(i == highest_index ? 10.f : 0.f); + outputs[OUTPUT_OUTPUT].setVoltage(i == highest_index ? 10.f : 0.f, i); + } + } else { // bar + for (int i = 0; i < CHANNEL_COUNT; i++) { + lights[GATEON1_LIGHT + i].setBrightness(gates[i] ? 1.f : 0.f); + outputs[GATE1_OUTPUT + i].setVoltage(gates[i] ? 10.f : 0.f); + outputs[OUTPUT_OUTPUT].setVoltage(gates[i] ? 10.f : 0.f, i); + } + } + + outputs[OUTPUT_OUTPUT].setChannels(CHANNEL_COUNT); + } +}; + + +struct SDComparatorWidget : ModuleWidget { + SDComparatorWidget(SDComparator* module) { + setModule(module); + setPanel(createPanel(asset::plugin(pluginInstance, "res/SDComparator.svg"))); + + addParam(createParamCentered(mm2px(Vec(6.271, 13.126)), module, SDComparator::LEVEL1_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 24.148)), module, SDComparator::LEVEL2_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 35.17)), module, SDComparator::LEVEL3_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 46.192)), module, SDComparator::LEVEL4_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 57.214)), module, SDComparator::LEVEL5_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 68.236)), module, SDComparator::LEVEL6_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 79.258)), module, SDComparator::LEVEL7_PARAM)); + addParam(createParamCentered(mm2px(Vec(6.271, 90.28)), module, SDComparator::LEVEL8_PARAM)); + addParam(createParam(mm2px(Vec(15.617, 101.089)), module, SDComparator::MODE_PARAM)); + + addInput(createInputCentered(mm2px(Vec(6.651, 104.61)), module, SDComparator::LEVELS_INPUT)); + addInput(createInputCentered(mm2px(Vec(6.651, 119.319)), module, SDComparator::INPUT_INPUT)); + + addOutput(createOutputCentered(mm2px(Vec(18.749, 13.126)), module, SDComparator::GATE1_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 24.148)), module, SDComparator::GATE2_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 35.17)), module, SDComparator::GATE3_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 46.192)), module, SDComparator::GATE4_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 57.214)), module, SDComparator::GATE5_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 68.236)), module, SDComparator::GATE6_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 79.258)), module, SDComparator::GATE7_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.749, 90.28)), module, SDComparator::GATE8_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(17.836, 119.318)), module, SDComparator::OUTPUT_OUTPUT)); + + addChild(createLightCentered>(mm2px(Vec(12.7, 13.126)), module, SDComparator::GATEON1_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 24.148)), module, SDComparator::GATEON2_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 35.17)), module, SDComparator::GATEON3_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 46.192)), module, SDComparator::GATEON4_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 57.214)), module, SDComparator::GATEON5_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 68.236)), module, SDComparator::GATEON6_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 79.258)), module, SDComparator::GATEON7_LIGHT)); + addChild(createLightCentered>(mm2px(Vec(12.7, 90.28)), module, SDComparator::GATEON8_LIGHT)); + } +}; + +Model* modelSDComparator = createModel("SDComparator"); diff --git a/src/plugin.cpp b/src/plugin.cpp index df6b456..2f09994 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -17,4 +17,5 @@ void init(Plugin *p) { p->addModel(modelSDFormation); p->addModel(modelSDLines); p->addModel(modelSDTransgate); + p->addModel(modelSDComparator); } diff --git a/src/plugin.hpp b/src/plugin.hpp index 5b73b32..fe2e03e 100644 --- a/src/plugin.hpp +++ b/src/plugin.hpp @@ -8,4 +8,5 @@ extern Plugin *pluginInstance; extern Model *modelSDOrcasHeartV2; extern Model *modelSDFormation; extern Model *modelSDLines; -extern Model *modelSDTransgate; \ No newline at end of file +extern Model *modelSDTransgate; +extern Model *modelSDComparator; \ No newline at end of file