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.

143 lines
4.1KB

  1. ///////////////////////////////////////////////////
  2. //
  3. // A/B Switches VCV Module
  4. //
  5. // Strum 2017
  6. //
  7. ///////////////////////////////////////////////////
  8. #include "mental.hpp"
  9. #include "dsp/digital.hpp"
  10. namespace rack_plugin_mental {
  11. /////////////////////////////////////////////////
  12. struct MentalABSwitches : Module {
  13. enum ParamIds {
  14. BUTTON_PARAM,
  15. NUM_PARAMS = BUTTON_PARAM + 4
  16. };
  17. enum InputIds {
  18. INPUT,
  19. SEL_INPUT = INPUT + 4,
  20. NUM_INPUTS = SEL_INPUT + 4
  21. };
  22. enum OutputIds {
  23. OUTPUT_A,
  24. OUTPUT_B = OUTPUT_A + 4,
  25. NUM_OUTPUTS = OUTPUT_B + 4
  26. };
  27. enum LightIds {
  28. BUTTON_LIGHTS,
  29. A_LEDS = BUTTON_LIGHTS + 4,
  30. B_LEDS = A_LEDS + 4,
  31. NUM_LIGHTS = B_LEDS + 4
  32. };
  33. SchmittTrigger button_triggers[4];
  34. bool button_on[4] = {0,0,0,0};
  35. MentalABSwitches() : 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 MentalABSwitches::step() {
  67. for (int i = 0 ; i < 4 ; i++)
  68. {
  69. float signal = inputs[INPUT + i].value;
  70. float sel = inputs[SEL_INPUT + i].value;
  71. if (button_triggers[i].process(params[BUTTON_PARAM + i].value))
  72. {
  73. button_on[i] = !button_on[i];
  74. }
  75. if (button_on[i] || ( sel > 0.0))
  76. {
  77. outputs[OUTPUT_A + i].value = 0.0;
  78. outputs[OUTPUT_B + i].value = signal;
  79. lights[B_LEDS + i].value = 1.0;
  80. lights[A_LEDS + i].value = 0.0;
  81. }
  82. else
  83. {
  84. outputs[OUTPUT_A + i].value = signal;
  85. outputs[OUTPUT_B + i].value = 0.0;
  86. lights[B_LEDS + i].value = 0.0;
  87. lights[A_LEDS + i].value = 1.0;
  88. }
  89. }
  90. }
  91. //////////////////////////////////////////////////////////////////
  92. struct MentalABSwitchesWidget : ModuleWidget {
  93. MentalABSwitchesWidget(MentalABSwitches *module);
  94. };
  95. MentalABSwitchesWidget::MentalABSwitchesWidget(MentalABSwitches *module) : ModuleWidget(module)
  96. {
  97. setPanel(SVG::load(assetPlugin(plugin, "res/MentalABSwitches.svg")));
  98. int group_spacing = 85;
  99. for (int i = 0 ; i < 4 ; i++)
  100. {
  101. addInput(Port::create<InPort>(Vec(3, group_spacing * i + 25), Port::INPUT, module, MentalABSwitches::INPUT + i));
  102. addInput(Port::create<GateInPort>(Vec(3, group_spacing * i + 75), Port::INPUT, module, MentalABSwitches::SEL_INPUT + i));
  103. addOutput(Port::create<OutPort>(Vec(33, group_spacing * i + 25), Port::OUTPUT, module, MentalABSwitches::OUTPUT_A + i));
  104. addOutput(Port::create<OutPort>(Vec(33, group_spacing * i + 50), Port::OUTPUT, module, MentalABSwitches::OUTPUT_B + i));
  105. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(62, group_spacing * i + 34), module, MentalABSwitches::A_LEDS + i ));
  106. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(62, group_spacing * i + 59), module, MentalABSwitches::B_LEDS + i));
  107. addParam(ParamWidget::create<LEDButton>(Vec(6, group_spacing * i + 54), module, MentalABSwitches::BUTTON_PARAM + i, 0.0, 1.0, 0.0));
  108. addChild(ModuleLightWidget::create<MedLight<BlueLED>>(Vec(6+5, group_spacing * i + 54+5), module, MentalABSwitches::BUTTON_LIGHTS + i));
  109. }
  110. }
  111. } // namespace rack_plugin_mental
  112. using namespace rack_plugin_mental;
  113. RACK_PLUGIN_MODEL_INIT(mental, MentalABSwitches) {
  114. Model *modelMentalABSwitches = Model::create<MentalABSwitches, MentalABSwitchesWidget>("mental", "MentalABSwitches", "A/B Switches", SWITCH_TAG, UTILITY_TAG);
  115. return modelMentalABSwitches;
  116. }