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.

112 lines
3.4KB

  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();
  28. void step();
  29. float getOutput(int outputId);
  30. };
  31. Branches::Branches() {
  32. params.resize(NUM_PARAMS);
  33. inputs.resize(NUM_INPUTS);
  34. outputs.resize(NUM_OUTPUTS);
  35. }
  36. static void computeChannel(const float *in, const float *p, float threshold, float mode, bool *lastGate, bool *outcome, float *out1, float *out2, float *light) {
  37. float out = getf(in);
  38. bool gate = (out >= 1.0);
  39. if (gate && !*lastGate) {
  40. // trigger
  41. float r = randomf();
  42. bool toss = (r < threshold + getf(p));
  43. if (mode < 0.5) {
  44. // direct mode
  45. *outcome = toss;
  46. }
  47. else {
  48. // toggle mode
  49. *outcome = *outcome != toss;
  50. }
  51. }
  52. *lastGate = gate;
  53. *light = *outcome ? out : -out;
  54. if (out1) {
  55. *out1 = *outcome ? 0.0 : out;
  56. }
  57. if (out2) {
  58. *out2 = *outcome ? out : 0.0;
  59. }
  60. }
  61. void Branches::step() {
  62. computeChannel(inputs[IN1_INPUT], inputs[P1_INPUT], params[THRESHOLD1_PARAM], params[MODE1_PARAM], &lastGate[0], &outcome[0], outputs[OUT1A_OUTPUT], outputs[OUT1B_OUTPUT], &light[0]);
  63. if(inputs[IN2_INPUT])
  64. computeChannel(inputs[IN2_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]);
  65. else
  66. computeChannel(inputs[IN1_INPUT], inputs[P2_INPUT], params[THRESHOLD2_PARAM], params[MODE2_PARAM], &lastGate[1], &outcome[1], outputs[OUT2A_OUTPUT], outputs[OUT2B_OUTPUT], &light[1]);
  67. }
  68. BranchesWidget::BranchesWidget() {
  69. Branches *module = new Branches();
  70. setModule(module);
  71. box.size = Vec(15*6, 380);
  72. {
  73. Panel *panel = new LightPanel();
  74. panel->backgroundImage = Image::load(assetPlugin(plugin, "res/Branches.png"));
  75. panel->box.size = box.size;
  76. addChild(panel);
  77. }
  78. addChild(createScrew<ScrewSilver>(Vec(15, 0)));
  79. addChild(createScrew<ScrewSilver>(Vec(15, 365)));
  80. addParam(createParam<Rogan1PSRed>(Vec(24, 64), module, Branches::THRESHOLD1_PARAM, 0.0, 1.0, 0.5));
  81. // addParam(createParam<MediumToggleSwitch>(Vec(69, 58), module, Branches::MODE1_PARAM, 0.0, 1.0, 0.0));
  82. addInput(createInput<PJ3410Port>(Vec(5, 119), module, Branches::IN1_INPUT));
  83. addInput(createInput<PJ3410Port>(Vec(52, 119), module, Branches::P1_INPUT));
  84. addOutput(createOutput<PJ3410Port>(Vec(5, 157), module, Branches::OUT1A_OUTPUT));
  85. addOutput(createOutput<PJ3410Port>(Vec(52, 157), module, Branches::OUT1B_OUTPUT));
  86. addParam(createParam<Rogan1PSGreen>(Vec(24, 220), module, Branches::THRESHOLD2_PARAM, 0.0, 1.0, 0.5));
  87. // addParam(createParam<MediumToggleSwitch>(Vec(69, 214), module, Branches::MODE2_PARAM, 0.0, 1.0, 0.0));
  88. addInput(createInput<PJ3410Port>(Vec(5, 275), module, Branches::IN2_INPUT));
  89. addInput(createInput<PJ3410Port>(Vec(52, 275), module, Branches::P2_INPUT));
  90. addOutput(createOutput<PJ3410Port>(Vec(5, 313), module, Branches::OUT2A_OUTPUT));
  91. addOutput(createOutput<PJ3410Port>(Vec(52, 313), module, Branches::OUT2B_OUTPUT));
  92. addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 169), &module->light[0]));
  93. addChild(createValueLight<SmallLight<GreenRedPolarityLight>>(Vec(40, 325), &module->light[1]));
  94. }