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.

148 lines
4.4KB

  1. #include "dsp/digital.hpp"
  2. #include "alikins.hpp"
  3. #include "MsDisplayWidget.hpp"
  4. /*
  5. This module was inspired by the question and discussion at:
  6. https://www.facebook.com/groups/vcvrack/permalink/161960391130780/
  7. "Okay , Rackheads... ;) Looking for a module that can "stretch" the length , extend the duration , of a gate/ trigger pulse."
  8. */
  9. namespace rack_plugin_Alikins {
  10. struct GateLength : Module {
  11. enum ParamIds {
  12. GATE_LENGTH_PARAM1,
  13. GATE_LENGTH_PARAM2,
  14. GATE_LENGTH_PARAM3,
  15. GATE_LENGTH_PARAM4,
  16. GATE_LENGTH_PARAM5,
  17. NUM_PARAMS
  18. };
  19. enum InputIds {
  20. TRIGGER_INPUT1,
  21. TRIGGER_INPUT2,
  22. TRIGGER_INPUT3,
  23. TRIGGER_INPUT4,
  24. TRIGGER_INPUT5,
  25. GATE_LENGTH_INPUT1,
  26. GATE_LENGTH_INPUT2,
  27. GATE_LENGTH_INPUT3,
  28. GATE_LENGTH_INPUT4,
  29. GATE_LENGTH_INPUT5,
  30. NUM_INPUTS
  31. };
  32. enum OutputIds {
  33. GATE_OUTPUT1,
  34. GATE_OUTPUT2,
  35. GATE_OUTPUT3,
  36. GATE_OUTPUT4,
  37. GATE_OUTPUT5,
  38. NUM_OUTPUTS
  39. };
  40. enum LightIds {
  41. NUM_LIGHTS
  42. };
  43. float gate_length[GATE_LENGTH_INPUTS];
  44. SchmittTrigger inputOnTrigger[GATE_LENGTH_INPUTS];
  45. PulseGenerator gateGenerator[GATE_LENGTH_INPUTS];
  46. GateLength() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  47. void step() override;
  48. void onReset() override {
  49. }
  50. };
  51. void GateLength::step() {
  52. // FIXME: add way to support >10.0s gate length
  53. float sample_time = engineGetSampleTime();
  54. for (int i = 0; i < GATE_LENGTH_INPUTS; i++) {
  55. gate_length[i] = clamp(params[GATE_LENGTH_PARAM1 + i].value + inputs[GATE_LENGTH_INPUT1 + i].value, 0.0f, 10.0f);
  56. if (inputOnTrigger[i].process(inputs[TRIGGER_INPUT1 + i].value)) {
  57. // debug("GL INPUT ON TRIGGER %d gate_length: %f", i, gate_length[i]);
  58. gateGenerator[i].trigger(gate_length[i]);
  59. }
  60. outputs[GATE_OUTPUT1 + i].value = gateGenerator[i].process(sample_time) ? 10.0f : 0.0f;
  61. }
  62. }
  63. struct GateLengthWidget : ModuleWidget {
  64. GateLengthWidget(GateLength *module);
  65. };
  66. GateLengthWidget::GateLengthWidget(GateLength *module) : ModuleWidget(module) {
  67. box.size = Vec(4 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  68. setPanel(SVG::load(assetPlugin(plugin, "res/GateLength.svg")));
  69. float y_pos = 2.0f;
  70. for (int i = 0; i < GATE_LENGTH_INPUTS; i++) {
  71. float x_pos = 4.0f;
  72. y_pos += 39.0f;
  73. addInput(Port::create<PJ301MPort>(Vec(x_pos, y_pos),
  74. Port::INPUT,
  75. module,
  76. GateLength::TRIGGER_INPUT1 + i));
  77. x_pos += 30.0f;
  78. MsDisplayWidget *gate_length_display = new MsDisplayWidget();
  79. gate_length_display->box.pos = Vec(x_pos, y_pos + 1.0f);
  80. gate_length_display->box.size = Vec(84, 24);
  81. gate_length_display->value = &module->gate_length[i];
  82. addChild(gate_length_display);
  83. // FIXME: use new sequential box hbox/vbox thing
  84. x_pos += 84.0f;
  85. x_pos += 4.0f;
  86. addOutput(Port::create<PJ301MPort>(Vec(x_pos, y_pos),
  87. Port::OUTPUT,
  88. module,
  89. GateLength::GATE_OUTPUT1 + i));
  90. x_pos = 4.0f;
  91. y_pos += 26.0f;
  92. addInput(Port::create<PJ301MPort>(Vec(x_pos, y_pos),
  93. Port::INPUT,
  94. module,
  95. GateLength::GATE_LENGTH_INPUT1 + i));
  96. x_pos += 30.0f;
  97. addParam(ParamWidget::create<Trimpot>(Vec(x_pos, y_pos + 3.0f),
  98. module,
  99. GateLength::GATE_LENGTH_PARAM1 + i,
  100. 0.0f, 10.0f, 0.1f));
  101. }
  102. addChild(Widget::create<ScrewSilver>(Vec(0.0f, 0.0f)));
  103. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15.0f, 0.0f)));
  104. addChild(Widget::create<ScrewSilver>(Vec(0.0f, 365.0f)));
  105. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15.0f, 365.0f)));
  106. }
  107. } // namespace rack_plugin_Alikins
  108. using namespace rack_plugin_Alikins;
  109. RACK_PLUGIN_MODEL_INIT(Alikins, GateLength) {
  110. Model *modelGateLength = Model::create<GateLength, GateLengthWidget>(
  111. "Alikins", "GateLength", "Gate Length", UTILITY_TAG);
  112. return modelGateLength;
  113. }