|
- #include "HetrickCV.hpp"
-
- namespace rack_plugin_HetrickCV {
-
- #ifdef USE_VST2
- #define plugin "HetrickCV"
- #endif // USE_VST2
-
- struct LogicCombine : Module
- {
- enum ParamIds
- {
- NUM_PARAMS
- };
- enum InputIds
- {
- IN1_INPUT,
- IN2_INPUT,
- IN3_INPUT,
- IN4_INPUT,
- IN5_INPUT,
- IN6_INPUT,
- IN7_INPUT,
- IN8_INPUT,
- NUM_INPUTS
- };
- enum OutputIds
- {
- OR_OUTPUT,
- NOR_OUTPUT,
- TRIG_OUTPUT,
- NUM_OUTPUTS
- };
-
- enum LightIds
- {
- OR_LIGHT,
- NOR_LIGHT,
- TRIG_LIGHT,
- NUM_LIGHTS
- };
-
- bool ins[NUM_INPUTS] = {};
- bool trigs[NUM_INPUTS] = {};
- float outs[3] = {};
- float trigLight;
- SchmittTrigger inTrigs[NUM_INPUTS];
- bool orState = false;
- bool trigState = false;
- const float lightLambda = 0.075;
-
- TriggerGenerator trigger;
-
- LogicCombine() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS)
- {
-
- }
-
- void step() override;
-
- // For more advanced Module features, read Rack's engine.hpp header file
- // - toJson, fromJson: serialization of internal data
- // - onSampleRateChange: event triggered by a change of sample rate
- // - reset, randomize: implements special behavior when user clicks these from the context menu
- };
-
-
- void LogicCombine::step()
- {
- orState = false;
- trigState = false;
-
- for(int i = 0; i < NUM_INPUTS; i++)
- {
- ins[i] = (inputs[IN1_INPUT + i].value >= 1.0f);
- trigs[i] = inTrigs[i].process(inputs[IN1_INPUT + i].value);
-
- orState = orState || ins[i];
- trigState = trigState || trigs[i];
- }
-
- outs[0] = orState ? 5.0f : 0.0f;
- outs[1] = 5.0f - outs[0];
-
- if(trigState)
- {
- trigger.trigger();
- lights[TRIG_LIGHT].value = 5.0f;
- }
-
- outs[2] = trigger.process() ? 5.0f : 0.0f;
-
- if (lights[TRIG_LIGHT].value > 0.01)
- lights[TRIG_LIGHT].value -= lights[TRIG_LIGHT].value / lightLambda * engineGetSampleTime();
-
- outputs[OR_OUTPUT].value = outs[0];
- outputs[NOR_OUTPUT].value = outs[1];
- outputs[TRIG_OUTPUT].value = outs[2];
-
- lights[OR_LIGHT].setBrightness(outs[0]);
- lights[NOR_LIGHT].setBrightness(outs[1]);
- lights[TRIG_LIGHT].setBrightnessSmooth(outs[2]);
- }
-
- struct LogicCombineWidget : ModuleWidget { LogicCombineWidget(LogicCombine *module); };
-
- LogicCombineWidget::LogicCombineWidget(LogicCombine *module) : ModuleWidget(module)
- {
- box.size = Vec(8 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
-
- {
- auto *panel = new SVGPanel();
- panel->box.size = box.size;
- panel->setBackground(SVG::load(assetPlugin(plugin, "res/LogicCombiner.svg")));
- addChild(panel);
- }
-
- addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
- addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)));
- addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
- addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)));
-
- //////PARAMS//////
-
- //////INPUTS//////
- const int inSpacing = 40;
- const int outPos = 67;
- const int lightPos = outPos + 29;
-
- for(int i = 0; i < LogicCombine::NUM_INPUTS; i++)
- {
- addInput(Port::create<PJ301MPort>(Vec(10, 50 + (i*inSpacing)), Port::INPUT, module, LogicCombine::IN1_INPUT + i));
- }
-
- //////OUTPUTS//////
- addOutput(Port::create<PJ301MPort>(Vec(outPos, 150), Port::OUTPUT, module, LogicCombine::OR_OUTPUT));
- addOutput(Port::create<PJ301MPort>(Vec(outPos, 195), Port::OUTPUT, module, LogicCombine::NOR_OUTPUT));
- addOutput(Port::create<PJ301MPort>(Vec(outPos, 240), Port::OUTPUT, module, LogicCombine::TRIG_OUTPUT));
-
- //////BLINKENLIGHTS//////
- addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 158), module, LogicCombine::OR_LIGHT));
- addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 203), module, LogicCombine::NOR_LIGHT));
- addChild(ModuleLightWidget::create<SmallLight<RedLight>>(Vec(lightPos, 248), module, LogicCombine::TRIG_LIGHT));
- }
-
- } // namespace rack_plugin_HetrickCV
-
- using namespace rack_plugin_HetrickCV;
-
- RACK_PLUGIN_MODEL_INIT(HetrickCV, LogicCombine) {
- Model *modelLogicCombine = Model::create<LogicCombine, LogicCombineWidget>("HetrickCV", "Logic Combine", "OR Logic (Gate Combiner)", LOGIC_TAG);
- return modelLogicCombine;
- }
|