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.

135 lines
3.6KB

  1. ///////////////////////////////////////////////////
  2. //
  3. // Gates VCV Module
  4. //
  5. // Strum 2017
  6. //
  7. ///////////////////////////////////////////////////
  8. #include "mental.hpp"
  9. #include "dsp/digital.hpp"
  10. /////////////////////////////////////////////////
  11. namespace rack_plugin_mental {
  12. struct MentalGates : Module {
  13. enum ParamIds {
  14. BUTTON_PARAM,
  15. NUM_PARAMS = BUTTON_PARAM + 4
  16. };
  17. enum InputIds {
  18. INPUT,
  19. GATE_INPUT = INPUT + 4,
  20. NUM_INPUTS = GATE_INPUT + 4
  21. };
  22. enum OutputIds {
  23. OUTPUT,
  24. NUM_OUTPUTS = OUTPUT + 4
  25. };
  26. enum LightIds {
  27. BUTTON_LIGHTS,
  28. ON_LEDS = BUTTON_LIGHTS + 4,
  29. NUM_LIGHTS = ON_LEDS + 4
  30. };
  31. SchmittTrigger button_triggers[4];
  32. bool button_on[4] = {0,0,0,0};
  33. float signal[4] = {0.0,0.0,0.0};
  34. float on[4] = {0.0,0.0,0.0};
  35. MentalGates() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  36. void step() override;
  37. json_t *toJson() override
  38. {
  39. json_t *rootJ = json_object();
  40. // button states
  41. json_t *button_statesJ = json_array();
  42. for (int i = 0; i < 4; i++)
  43. {
  44. json_t *button_stateJ = json_integer((int) button_on[i]);
  45. json_array_append_new(button_statesJ, button_stateJ);
  46. }
  47. json_object_set_new(rootJ, "buttons", button_statesJ);
  48. return rootJ;
  49. }
  50. void fromJson(json_t *rootJ) override
  51. {
  52. // button states
  53. json_t *button_statesJ = json_object_get(rootJ, "buttons");
  54. if (button_statesJ)
  55. {
  56. for (int i = 0; i < 4; i++)
  57. {
  58. json_t *button_stateJ = json_array_get(button_statesJ, i);
  59. if (button_stateJ)
  60. button_on[i] = !!json_integer_value(button_stateJ);
  61. }
  62. }
  63. }
  64. };
  65. /////////////////////////////////////////////////////
  66. void MentalGates::step() {
  67. for (int i = 0 ; i < 4 ; i++)
  68. {
  69. signal[i] = inputs[INPUT + i].value;
  70. on[i] = inputs[GATE_INPUT + i].value;
  71. if (button_triggers[i].process(params[BUTTON_PARAM + i].value))
  72. {
  73. button_on[i] = !button_on[i];
  74. }
  75. lights[BUTTON_LIGHTS + i ].value = (button_on[i]) ? 1.0 : 0.0;
  76. if (button_on[i] || ( on[i] > 0.0))
  77. {
  78. outputs[OUTPUT + i].value = 0.0;
  79. lights[ON_LEDS + i].value = 1.0;
  80. }
  81. else
  82. {
  83. outputs[OUTPUT + i].value = signal[i];
  84. lights[ON_LEDS + i].value = 0.0;
  85. }
  86. }
  87. }
  88. //////////////////////////////////////////////////////////////////
  89. struct MentalGatesWidget : ModuleWidget {
  90. MentalGatesWidget(MentalGates *module);
  91. };
  92. MentalGatesWidget::MentalGatesWidget(MentalGates *module) : ModuleWidget(module)
  93. {
  94. setPanel(SVG::load(assetPlugin(plugin, "res/MentalGates.svg")));
  95. int group_spacing = 85;
  96. for (int i = 0 ; i < 4 ; i++)
  97. {
  98. addInput(Port::create<InPort>(Vec(3, group_spacing * i + 60), Port::INPUT, module, MentalGates::INPUT + i));
  99. addInput(Port::create<GateInPort>(Vec(3, group_spacing * i + 28), Port::INPUT, module, MentalGates::GATE_INPUT + i));
  100. addOutput(Port::create<OutPort>(Vec(32, group_spacing * i + 60), Port::OUTPUT, module, MentalGates::OUTPUT + i));
  101. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(26, group_spacing * i + 17), module, MentalGates::ON_LEDS + i));
  102. addParam(ParamWidget::create<LEDButton>(Vec(35, group_spacing * i + 31), module, MentalGates::BUTTON_PARAM + i, 0.0, 1.0, 0.0));
  103. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(35+5, group_spacing * i + 31+5), module, MentalGates::BUTTON_LIGHTS + i));
  104. }
  105. }
  106. } // namespace rack_plugin_mental
  107. using namespace rack_plugin_mental;
  108. RACK_PLUGIN_MODEL_INIT(mental, MentalGates) {
  109. Model *modelMentalGates = Model::create<MentalGates, MentalGatesWidget>("mental", "MentalGates", "Gates", UTILITY_TAG);
  110. return modelMentalGates;
  111. }