diff --git a/plugin.json b/plugin.json index c009c3d..2ae5e61 100644 --- a/plugin.json +++ b/plugin.json @@ -311,6 +311,15 @@ "Utility", "Polyphonic" ] + }, + { + "slug": "Logic", + "name": "Logic", + "description": "Gate logic processor", + "tags": [ + "Logic", + "Polyphonic" + ] } ] } \ No newline at end of file diff --git a/res/Compare.svg b/res/Compare.svg new file mode 100644 index 0000000..2d90c79 --- /dev/null +++ b/res/Compare.svg @@ -0,0 +1,645 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/Logic.svg b/res/Logic.svg new file mode 100644 index 0000000..e8ab8b1 --- /dev/null +++ b/res/Logic.svg @@ -0,0 +1,598 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Logic.cpp b/src/Logic.cpp new file mode 100644 index 0000000..aea0353 --- /dev/null +++ b/src/Logic.cpp @@ -0,0 +1,131 @@ +#include "plugin.hpp" + + +struct Logic : Module { + enum ParamId { + B_PARAM, + PARAMS_LEN + }; + enum InputId { + A_INPUT, + B_INPUT, + INPUTS_LEN + }; + enum OutputId { + NOTA_OUTPUT, + NOTB_OUTPUT, + OR_OUTPUT, + NOR_OUTPUT, + AND_OUTPUT, + NAND_OUTPUT, + XOR_OUTPUT, + XNOR_OUTPUT, + OUTPUTS_LEN + }; + enum LightId { + B_BUTTON_LIGHT, + ENUMS(NOTA_LIGHT, 2), + ENUMS(NOTB_LIGHT, 2), + ENUMS(OR_LIGHT, 2), + ENUMS(NOR_LIGHT, 2), + ENUMS(AND_LIGHT, 2), + ENUMS(NAND_LIGHT, 2), + ENUMS(XOR_LIGHT, 2), + ENUMS(XNOR_LIGHT, 2), + LIGHTS_LEN + }; + + Logic() { + config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN); + configButton(B_PARAM, "B"); + configInput(A_INPUT, "A"); + configInput(B_INPUT, "B"); + configOutput(NOTA_OUTPUT, "NOT A"); + configOutput(NOTB_OUTPUT, "NOT B"); + configOutput(OR_OUTPUT, "OR"); + configOutput(NOR_OUTPUT, "NOR"); + configOutput(AND_OUTPUT, "AND"); + configOutput(NAND_OUTPUT, "NAND"); + configOutput(XOR_OUTPUT, "XOR"); + configOutput(XNOR_OUTPUT, "XNOR"); + } + + void process(const ProcessArgs& args) override { + int channels = std::max(inputs[A_INPUT].getChannels(), inputs[B_INPUT].getChannels()); + + bool bPush = params[B_PARAM].getValue() > 0.f; + bool anyState[8] = {}; + + for (int c = 0; c < channels; c++) { + bool a = inputs[A_INPUT].getPolyVoltage(c) > 1.f; + bool b = bPush || inputs[B_INPUT].getPolyVoltage(c) > 1.f; + + bool states[8] = { + !a, // NOTA + !b, // NOTB + a || b, // OR + !(a || b), // NOR + a && b, // AND + !(a && b), // NAND + a != b, // XOR + a == b, // XNOR + }; + + for (int i = 0; i < 8; i++) { + outputs[NOTA_OUTPUT + i].setVoltage(states[i] ? 10.f : 0.f); + if (states[i]) + anyState[i] = true; + } + } + + for (int i = 0; i < 8; i++) { + outputs[NOTA_OUTPUT + i].setChannels(channels); + } + + // Set lights + lights[B_BUTTON_LIGHT].setBrightness(bPush); + for (int i = 0; i < 8; i++) { + lights[NOTA_LIGHT + 2 * i + 0].setBrightness(anyState[i] && channels == 1); + lights[NOTA_LIGHT + 2 * i + 1].setBrightness(anyState[i] && channels > 1); + } + } +}; + + +struct LogicWidget : ModuleWidget { + LogicWidget(Logic* module) { + setModule(module); + setPanel(createPanel(asset::plugin(pluginInstance, "res/Logic.svg"))); + + addChild(createWidget(Vec(RACK_GRID_WIDTH, 0))); + addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0))); + addChild(createWidget(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); + addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); + + addParam(createLightParamCentered>(mm2px(Vec(12.7, 26.755)), module, Logic::B_PARAM, Logic::B_BUTTON_LIGHT)); + + addInput(createInputCentered(mm2px(Vec(7.299, 52.31)), module, Logic::A_INPUT)); + addInput(createInputCentered(mm2px(Vec(18.136, 52.31)), module, Logic::B_INPUT)); + + addOutput(createOutputCentered(mm2px(Vec(7.297, 67.53)), module, Logic::NOTA_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.134, 67.53)), module, Logic::NOTB_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(7.297, 82.732)), module, Logic::OR_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.134, 82.732)), module, Logic::NOR_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(7.297, 97.958)), module, Logic::AND_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.134, 97.958)), module, Logic::NAND_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(7.297, 113.115)), module, Logic::XOR_OUTPUT)); + addOutput(createOutputCentered(mm2px(Vec(18.134, 113.115)), module, Logic::XNOR_OUTPUT)); + + addChild(createLightCentered>>(mm2px(Vec(11.027, 63.805)), module, Logic::NOTA_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(21.864, 63.805)), module, Logic::NOTB_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(11.027, 79.007)), module, Logic::OR_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(21.864, 79.007)), module, Logic::NOR_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(11.027, 94.233)), module, Logic::AND_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(21.864, 94.233)), module, Logic::NAND_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(11.027, 109.393)), module, Logic::XOR_LIGHT)); + addChild(createLightCentered>>(mm2px(Vec(21.864, 109.393)), module, Logic::XNOR_LIGHT)); + } +}; + + +Model* modelLogic = createModel("Logic"); \ No newline at end of file diff --git a/src/plugin.cpp b/src/plugin.cpp index 9742595..75e37a3 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -36,4 +36,5 @@ void init(Plugin* p) { p->addModel(modelRandom); p->addModel(modelCVMix); p->addModel(modelFade); + p->addModel(modelLogic); } diff --git a/src/plugin.hpp b/src/plugin.hpp index 1352d22..6da7478 100644 --- a/src/plugin.hpp +++ b/src/plugin.hpp @@ -36,6 +36,7 @@ extern Model* modelNoise; extern Model* modelRandom; extern Model* modelCVMix; extern Model* modelFade; +extern Model* modelLogic; struct DigitalDisplay : Widget { @@ -102,3 +103,12 @@ struct YellowRedLight : TBase { this->addBaseColor(SCHEME_RED); } }; + + +template +struct YellowBlueLight : TBase { + YellowBlueLight() { + this->addBaseColor(SCHEME_YELLOW); + this->addBaseColor(SCHEME_BLUE); + } +};