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.

141 lines
4.2KB

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