You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.3KB

  1. #include "plugin.hpp"
  2. struct Push : Module {
  3. enum ParamId {
  4. PUSH_PARAM,
  5. HOLD_PARAM,
  6. PARAMS_LEN
  7. };
  8. enum InputId {
  9. HOLD_INPUT,
  10. PUSH_INPUT,
  11. INPUTS_LEN
  12. };
  13. enum OutputId {
  14. TRIG_OUTPUT,
  15. GATE_OUTPUT,
  16. OUTPUTS_LEN
  17. };
  18. enum LightId {
  19. PUSH_LIGHT,
  20. HOLD_LIGHT,
  21. LIGHTS_LEN
  22. };
  23. dsp::BooleanTrigger holdBoolean;
  24. dsp::SchmittTrigger holdSchmitt;
  25. dsp::BooleanTrigger pushBoolean;
  26. dsp::SchmittTrigger pushSchmitt;
  27. dsp::PulseGenerator trigPulse;
  28. bool hold = false;
  29. Push() {
  30. config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
  31. configButton(PUSH_PARAM, "Push");
  32. configButton(HOLD_PARAM, "Hold");
  33. configInput(HOLD_INPUT, "Hold");
  34. configInput(PUSH_INPUT, "Push");
  35. configOutput(TRIG_OUTPUT, "Trigger");
  36. configOutput(GATE_OUTPUT, "Gate");
  37. }
  38. void onReset(const ResetEvent& e) override {
  39. Module::onReset(e);
  40. hold = false;
  41. }
  42. void process(const ProcessArgs& args) override {
  43. // Hold button
  44. if (holdBoolean.process(params[HOLD_PARAM].getValue()))
  45. hold ^= true;
  46. // Hold input
  47. if (holdSchmitt.process(inputs[HOLD_INPUT].getVoltage(), 0.1f, 1.f))
  48. hold ^= true;
  49. // Push button
  50. bool push = params[PUSH_PARAM].getValue() > 0.f;
  51. // Push input
  52. pushSchmitt.process(inputs[PUSH_INPUT].getVoltage(), 0.1f, 1.f);
  53. // Gate and trigger outputs
  54. bool gate = push || pushSchmitt.isHigh();
  55. gate ^= hold;
  56. if (pushBoolean.process(gate)) {
  57. trigPulse.trigger(1e-3f);
  58. }
  59. outputs[TRIG_OUTPUT].setVoltage(trigPulse.process(args.sampleTime) ? 10.f : 0.f);
  60. outputs[GATE_OUTPUT].setVoltage(gate ? 10.f : 0.f);
  61. lights[HOLD_LIGHT].setBrightnessSmooth(hold, args.sampleTime);
  62. lights[PUSH_LIGHT].setBrightnessSmooth(gate, args.sampleTime);
  63. }
  64. json_t* dataToJson() override {
  65. json_t* rootJ = json_object();
  66. json_object_set_new(rootJ, "hold", json_boolean(hold));
  67. return rootJ;
  68. }
  69. void dataFromJson(json_t* rootJ) override {
  70. json_t* holdJ = json_object_get(rootJ, "hold");
  71. if (holdJ)
  72. hold = json_boolean_value(holdJ);
  73. }
  74. };
  75. struct PushWidget : ModuleWidget {
  76. PushWidget(Push* module) {
  77. setModule(module);
  78. setPanel(createPanel(asset::plugin(pluginInstance, "res/Push.svg"), asset::plugin(pluginInstance, "res/Push-dark.svg")));
  79. addChild(createWidget<ThemedScrew>(Vec(RACK_GRID_WIDTH, 0)));
  80. addChild(createWidget<ThemedScrew>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  81. addChild(createWidget<ThemedScrew>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  82. addChild(createWidget<ThemedScrew>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  83. addParam(createLightParamCentered<LightButton<VCVBezelBig, VCVBezelLightBig<WhiteLight>>>(mm2px(Vec(7.62, 24.723)), module, Push::PUSH_PARAM, Push::PUSH_LIGHT));
  84. addParam(createLightParamCentered<VCVLightButton<MediumSimpleLight<WhiteLight>>>(mm2px(Vec(7.617, 48.074)), module, Push::HOLD_PARAM, Push::HOLD_LIGHT));
  85. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.612, 64.344)), module, Push::HOLD_INPUT));
  86. addInput(createInputCentered<ThemedPJ301MPort>(mm2px(Vec(7.612, 80.597)), module, Push::PUSH_INPUT));
  87. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(7.62, 96.864)), module, Push::TRIG_OUTPUT));
  88. addOutput(createOutputCentered<ThemedPJ301MPort>(mm2px(Vec(7.62, 113.115)), module, Push::GATE_OUTPUT));
  89. }
  90. };
  91. Model* modelPush = createModel<Push, PushWidget>("Push");