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.

230 lines
8.3KB

  1. /*
  2. BangDaButton
  3. a cv sending button to trigger/switch things.
  4. button provides gate/trig outs for press and release events as well
  5. as two flipflops.
  6. it also opens/closes 4 A/B switches 2 x 1to2 and 2 x 2to1
  7. a "hidden" gate port can be used to control the button with external sources.
  8. TODO:
  9. toggle/momentary modes for the channels
  10. toggles for the flipflops
  11. */////////////////////////////////////////////////////////////////////////////
  12. #include "pvc.hpp"
  13. #include "dsp/digital.hpp" // SchmittTrigger // PulseGenerator
  14. namespace rack_plugin_PvC {
  15. struct BangDaButton : Module {
  16. enum ParamIds {
  17. DA_BUTTON,
  18. NUM_PARAMS
  19. };
  20. enum InputIds {
  21. UP_SW_A_IN,
  22. UP_SW_B_IN,
  23. UP_CH1_IN,
  24. UP_MUX_IN,
  25. UP_CH2_IN,
  26. DOWN_SW_A_IN,
  27. DOWN_SW_B_IN,
  28. DOWN_CH1_IN,
  29. DOWN_MUX_IN,
  30. DOWN_CH2_IN,
  31. DA_BUTTON_TRIG,
  32. NUM_INPUTS
  33. };
  34. enum OutputIds {
  35. UP_SW_OUT,
  36. UP_CH1_OUT,
  37. UP_MUX_A_OUT, UP_MUX_B_OUT,
  38. UP_CH2_OUT,
  39. UP_FLIP_OUT, UP_TRIG_OUT, UP_GATE_OUT,
  40. DOWN_GATE_OUT, DOWN_TRIG_OUT, DOWN_FLIP_OUT,
  41. DOWN_CH1_OUT,
  42. DOWN_MUX_A_OUT, DOWN_MUX_B_OUT,
  43. DOWN_CH2_OUT,
  44. DOWN_SW_OUT,
  45. NUM_OUTPUTS
  46. };
  47. enum LightIds {
  48. UP_LED,
  49. DOWN_LED,
  50. NUM_LIGHTS
  51. };
  52. bool pressed = false;
  53. bool flipUp = true;
  54. bool flipDn = false;
  55. SchmittTrigger upFlipTrg;
  56. SchmittTrigger dnFlipTrg;
  57. PulseGenerator upPulse;
  58. PulseGenerator dnPulse;
  59. BangDaButton() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  60. void step() override;
  61. void reset() override {
  62. pressed = false;
  63. flipUp = true;
  64. flipDn = false;
  65. }
  66. };
  67. void BangDaButton::step() {
  68. pressed = params[DA_BUTTON].value;
  69. if (inputs[DA_BUTTON_TRIG].active) {
  70. pressed = inputs[DA_BUTTON_TRIG].value > 0 ? !pressed : pressed;
  71. }
  72. if (dnFlipTrg.process(pressed)) { // HOLD
  73. flipDn = !flipDn;
  74. dnPulse.trigger(0.01);
  75. }
  76. if (upFlipTrg.process(!pressed)){ // RELEASE
  77. flipUp = !flipUp;
  78. upPulse.trigger(0.01);
  79. }
  80. // outputs[UP_CH1_OUT].value = pressed ? inputs[UP_CH1_IN].normalize(0.0) : 0.0f;
  81. // outputs[UP_CH2_OUT].value = pressed ? 0.0f : inputs[UP_CH2_IN].normalize(0.0);
  82. outputs[UP_SW_OUT].value = pressed ? inputs[UP_SW_A_IN].normalize(0.0f) : inputs[UP_SW_B_IN].normalize(0.0f);
  83. outputs[UP_MUX_A_OUT].value = pressed * inputs[UP_MUX_IN].normalize(0.0f);
  84. outputs[UP_MUX_B_OUT].value = !pressed * inputs[UP_MUX_IN].normalize(0.0f);
  85. // outputs[DOWN_CH1_OUT].value = pressed ? inputs[DOWN_CH1_IN].normalize(0.0f) : 0.0f;
  86. // outputs[DOWN_CH2_OUT].value = pressed ? 0.0f : inputs[DOWN_CH2_IN].normalize(0.0f);
  87. outputs[DOWN_SW_OUT].value = pressed ? inputs[DOWN_SW_B_IN].normalize(0.0f) : inputs[DOWN_SW_A_IN].normalize(0.0f);
  88. outputs[DOWN_MUX_A_OUT].value = !pressed * inputs[DOWN_MUX_IN].normalize(0.0f);
  89. outputs[DOWN_MUX_B_OUT].value = pressed * inputs[DOWN_MUX_IN].normalize(0.0f);
  90. outputs[UP_GATE_OUT].value = !pressed * 10.0f;
  91. outputs[DOWN_GATE_OUT].value = pressed * 10.0f;
  92. outputs[UP_FLIP_OUT].value = flipUp * 10.0f;
  93. outputs[DOWN_FLIP_OUT].value = flipDn * 10.0f;
  94. outputs[UP_TRIG_OUT].value = upPulse.process(1.0/engineGetSampleRate()) * 10.0f;
  95. outputs[DOWN_TRIG_OUT].value = dnPulse.process(1.0/engineGetSampleRate()) * 10.0f;
  96. lights[DOWN_LED].value = pressed;
  97. lights[UP_LED].value = !pressed;
  98. }
  99. struct DaButton : SVGSwitch, MomentarySwitch {
  100. DaButton() {
  101. addFrame(SVG::load(assetPlugin(plugin, "res/components/DaButton_up.svg")));
  102. addFrame(SVG::load(assetPlugin(plugin, "res/components/DaButton_dn.svg")));
  103. box.size = Vec(82,82);
  104. }
  105. };
  106. struct InPortT : SVGPort {
  107. InPortT() {
  108. background->svg = SVG::load(assetPlugin(plugin, "res/components/empty.svg"));
  109. background->wrap();
  110. box.size = Vec(22,22);
  111. }
  112. };
  113. struct BangDaButtonWidget : ModuleWidget {
  114. BangDaButtonWidget(BangDaButton *module);
  115. };
  116. BangDaButtonWidget::BangDaButtonWidget(BangDaButton *module) : ModuleWidget(module) {
  117. setPanel(SVG::load(assetPlugin(plugin, "res/panels/BangDaButton.svg")));
  118. // screws
  119. addChild(Widget::create<ScrewHead3>(Vec(15, 0)));
  120. addChild(Widget::create<ScrewHead2>(Vec(box.size.x - 30, 0)));
  121. addChild(Widget::create<ScrewHead4>(Vec(15, 365)));
  122. addChild(Widget::create<ScrewHead1>(Vec(box.size.x - 30, 365)));
  123. addInput(Port::create<InPortAud>(Vec(4,22), Port::INPUT, module,BangDaButton::UP_SW_A_IN));
  124. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(28,30.5),module,BangDaButton::DOWN_LED));
  125. addOutput(Port::create<OutPortVal>(Vec(34,22), Port::OUTPUT, module,BangDaButton::UP_SW_OUT));
  126. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(57,30.5),module,BangDaButton::UP_LED));
  127. addInput(Port::create<InPortAud>(Vec(64,22), Port::INPUT, module,BangDaButton::UP_SW_B_IN));
  128. // addInput(Port::create<InPortAud>(Vec(4,44), Port::INPUT, module,BangDaButton::UP_CH1_IN));
  129. // addChild(ModuleLightWidget::create<FourPixLight<RedLight>>(Vec(27,52),module,BangDaButton::UP_LED));
  130. // addOutput(Port::create<OutPortVal>(Vec(34,44), Port::OUTPUT, module,BangDaButton::UP_CH1_OUT));
  131. addOutput(Port::create<OutPortVal>(Vec(4,68), Port::OUTPUT, module,BangDaButton::UP_MUX_A_OUT));
  132. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(27,76.5),module,BangDaButton::DOWN_LED));
  133. addInput(Port::create<InPortAud>(Vec(34,68), Port::INPUT, module,BangDaButton::UP_MUX_IN));
  134. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(57,76.5),module,BangDaButton::UP_LED));
  135. addOutput(Port::create<OutPortVal>(Vec(64,68), Port::OUTPUT, module,BangDaButton::UP_MUX_B_OUT));
  136. // addInput(Port::create<InPortAud>(Vec(34,92), Port::INPUT, module,BangDaButton::UP_CH2_IN));
  137. // addChild(ModuleLightWidget::create<FourPixLight<RedLight>>(Vec(57,100),module,BangDaButton::DOWN_LED));
  138. // addOutput(Port::create<OutPortVal>(Vec(64,92), Port::OUTPUT, module,BangDaButton::UP_CH2_OUT));
  139. addOutput(Port::create<OutPortBin>(Vec(6,124), Port::OUTPUT, module,BangDaButton::UP_GATE_OUT));
  140. addOutput(Port::create<OutPortBin>(Vec(34,124), Port::OUTPUT, module,BangDaButton::UP_TRIG_OUT));
  141. addOutput(Port::create<OutPortBin>(Vec(62,124), Port::OUTPUT, module,BangDaButton::UP_FLIP_OUT));
  142. addParam(ParamWidget::create<DaButton>(Vec(4,149),module,BangDaButton::DA_BUTTON, 0, 1, 0));
  143. addInput(Port::create<InPortT>(Vec(4,179), Port::INPUT, module,BangDaButton::DA_BUTTON_TRIG));
  144. addOutput(Port::create<OutPortBin>(Vec(6,234), Port::OUTPUT, module,BangDaButton::DOWN_FLIP_OUT));
  145. addOutput(Port::create<OutPortBin>(Vec(34,234), Port::OUTPUT, module,BangDaButton::DOWN_TRIG_OUT));
  146. addOutput(Port::create<OutPortBin>(Vec(62,234), Port::OUTPUT, module,BangDaButton::DOWN_GATE_OUT));
  147. // addInput(Port::create<InPortAud>(Vec(4,266), Port::INPUT, module,BangDaButton::DOWN_CH1_IN));
  148. // addChild(ModuleLightWidget::create<FourPixLight<RedLight>>(Vec(27,274),module,BangDaButton::UP_LED));
  149. // addOutput(Port::create<OutPortVal>(Vec(34,266), Port::OUTPUT, module,BangDaButton::DOWN_CH1_OUT));
  150. addOutput(Port::create<OutPortVal>(Vec(4,290), Port::OUTPUT, module,BangDaButton::DOWN_MUX_A_OUT));
  151. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(27,298.5),module,BangDaButton::UP_LED));
  152. addInput(Port::create<InPortAud>(Vec(34,290), Port::INPUT, module,BangDaButton::DOWN_MUX_IN));
  153. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(57,298.5),module,BangDaButton::DOWN_LED));
  154. addOutput(Port::create<OutPortVal>(Vec(64,290), Port::OUTPUT, module,BangDaButton::DOWN_MUX_B_OUT));
  155. // addInput(Port::create<InPortAud>(Vec(34,314), Port::INPUT, module,BangDaButton::DOWN_CH2_IN));
  156. // addChild(ModuleLightWidget::create<FourPixLight<RedLight>>(Vec(57,322),module,BangDaButton::DOWN_LED));
  157. // addOutput(Port::create<OutPortVal>(Vec(64,314), Port::OUTPUT, module,BangDaButton::DOWN_CH2_OUT));
  158. addInput(Port::create<InPortAud>(Vec(4,336), Port::INPUT, module,BangDaButton::DOWN_SW_A_IN));
  159. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(27,344.5),module,BangDaButton::UP_LED));
  160. addOutput(Port::create<OutPortVal>(Vec(34,336), Port::OUTPUT, module,BangDaButton::DOWN_SW_OUT));
  161. addChild(ModuleLightWidget::create<FourPixLight<GreenLED>>(Vec(57,344.5),module,BangDaButton::DOWN_LED));
  162. addInput(Port::create<InPortAud>(Vec(64,336), Port::INPUT, module,BangDaButton::DOWN_SW_B_IN));
  163. }
  164. } // namespace rack_plugin_PvC
  165. using namespace rack_plugin_PvC;
  166. RACK_PLUGIN_MODEL_INIT(PvC, BangDaButton) {
  167. Model *modelBangDaButton = Model::create<BangDaButton, BangDaButtonWidget>(
  168. "PvC", "BangDaButton", "BangDaButton", CONTROLLER_TAG, SWITCH_TAG);
  169. return modelBangDaButton;
  170. }