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.

98 lines
3.1KB

  1. #include "AudibleInstruments.hpp"
  2. struct Branches : Module {
  3. enum ParamIds {
  4. THRESHOLD1_PARAM,
  5. THRESHOLD2_PARAM,
  6. MODE1_PARAM,
  7. MODE2_PARAM,
  8. NUM_PARAMS
  9. };
  10. enum InputIds {
  11. IN1_INPUT,
  12. P1_INPUT,
  13. IN2_INPUT,
  14. P2_INPUT,
  15. NUM_INPUTS
  16. };
  17. enum OutputIds {
  18. OUT1A_OUTPUT,
  19. OUT1B_OUTPUT,
  20. OUT2A_OUTPUT,
  21. OUT2B_OUTPUT,
  22. NUM_OUTPUTS
  23. };
  24. bool lastGate[2] = {};
  25. bool outcome[2] = {};
  26. float light[2] = {};
  27. Branches() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {}
  28. void step();
  29. float getOutput(int outputId);
  30. };
  31. static void processChannel(Input &in, Input &p, Param &threshold, Param &mode, bool *lastGate, bool *outcome, Output &out1, Output &out2, float *light) {
  32. float out = in.value;
  33. bool gate = (out >= 1.0);
  34. if (gate && !*lastGate) {
  35. // trigger
  36. float r = randomf();
  37. bool toss = (r < threshold.value + p.value);
  38. if (mode.value < 0.5) {
  39. // direct mode
  40. *outcome = toss;
  41. }
  42. else {
  43. // toggle mode
  44. *outcome = *outcome != toss;
  45. }
  46. }
  47. *lastGate = gate;
  48. *light = *outcome ? out : -out;
  49. out1.value = *outcome ? 0.0 : out;
  50. out2.value = *outcome ? out : 0.0;
  51. }
  52. void Branches::step() {
  53. processChannel(inputs[IN1_INPUT], inputs[P1_INPUT], params[THRESHOLD1_PARAM], params[MODE1_PARAM], &lastGate[0], &outcome[0], outputs[OUT1A_OUTPUT], outputs[OUT1B_OUTPUT], &light[0]);
  54. processChannel(inputs[IN2_INPUT].active ? inputs[IN2_INPUT] : inputs[IN1_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]);
  55. }
  56. BranchesWidget::BranchesWidget() {
  57. Branches *module = new Branches();
  58. setModule(module);
  59. box.size = Vec(15*6, 380);
  60. {
  61. Panel *panel = new LightPanel();
  62. panel->backgroundImage = Image::load(assetPlugin(plugin, "res/Branches.png"));
  63. panel->box.size = box.size;
  64. addChild(panel);
  65. }
  66. addChild(createScrew<ScrewSilver>(Vec(15, 0)));
  67. addChild(createScrew<ScrewSilver>(Vec(15, 365)));
  68. addParam(createParam<Rogan1PSRed>(Vec(24, 64), module, Branches::THRESHOLD1_PARAM, 0.0, 1.0, 0.5));
  69. // addParam(createParam<MediumToggleSwitch>(Vec(69, 58), module, Branches::MODE1_PARAM, 0.0, 1.0, 0.0));
  70. addInput(createInput<PJ3410Port>(Vec(5, 119), module, Branches::IN1_INPUT));
  71. addInput(createInput<PJ3410Port>(Vec(52, 119), module, Branches::P1_INPUT));
  72. addOutput(createOutput<PJ3410Port>(Vec(5, 157), module, Branches::OUT1A_OUTPUT));
  73. addOutput(createOutput<PJ3410Port>(Vec(52, 157), module, Branches::OUT1B_OUTPUT));
  74. addParam(createParam<Rogan1PSGreen>(Vec(24, 220), module, Branches::THRESHOLD2_PARAM, 0.0, 1.0, 0.5));
  75. // addParam(createParam<MediumToggleSwitch>(Vec(69, 214), module, Branches::MODE2_PARAM, 0.0, 1.0, 0.0));
  76. addInput(createInput<PJ3410Port>(Vec(5, 275), module, Branches::IN2_INPUT));
  77. addInput(createInput<PJ3410Port>(Vec(52, 275), module, Branches::P2_INPUT));
  78. addOutput(createOutput<PJ3410Port>(Vec(5, 313), module, Branches::OUT2A_OUTPUT));
  79. addOutput(createOutput<PJ3410Port>(Vec(52, 313), module, Branches::OUT2B_OUTPUT));
  80. addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 169), &module->light[0]));
  81. addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 325), &module->light[1]));
  82. }