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.

182 lines
5.3KB

  1. /*
  2. Tails
  3. */////////////////////////////////////////////////////////////////////////////
  4. #include "pvc.hpp"
  5. #include "dsp/digital.hpp"
  6. namespace rack_plugin_PvC {
  7. struct Tails : Module {
  8. enum ParamIds {
  9. PROB_UI,
  10. TOSS_MODE,
  11. TOSS_UI,
  12. FLIP_UI,
  13. SET_A_UI,
  14. SET_B_UI,
  15. NUM_PARAMS
  16. };
  17. enum InputIds {
  18. SIG_IN,
  19. PROB_CV,
  20. TOSS_IN,
  21. FLIP_IN,
  22. SET_A_IN,
  23. SET_B_IN,
  24. NUM_INPUTS
  25. };
  26. enum OutputIds {
  27. SIG_A_OUT,
  28. SIG_B_OUT,
  29. GATE_A_OUT,
  30. GATE_B_OUT,
  31. TRIG_A_OUT,
  32. TRIG_B_OUT,
  33. NUM_OUTPUTS
  34. };
  35. enum LightIds {
  36. A_LED,
  37. B_LED,
  38. DIR_LED,
  39. FLP_LED,
  40. NUM_LIGHTS
  41. };
  42. bool gate = false;
  43. bool flipMode = false;
  44. SchmittTrigger tossTrigger;
  45. SchmittTrigger flipTrigger;
  46. SchmittTrigger resetTrigger;
  47. PulseGenerator gatePulse;
  48. Tails() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  49. void step() override;
  50. void reset() override {
  51. gate = false;
  52. flipMode = false;
  53. }
  54. json_t *toJson() override {
  55. json_t *rootJ = json_object();
  56. json_t *gateStateJ = json_boolean(gate);
  57. json_object_set_new(rootJ, "gateState", gateStateJ);
  58. return rootJ;
  59. }
  60. void fromJson(json_t *rootJ) override {
  61. json_t *gateStateJ = json_object_get(rootJ, "gateState");
  62. if (gateStateJ)
  63. gate = json_boolean_value(gateStateJ);
  64. }
  65. };
  66. void Tails::step() {
  67. flipMode = params[TOSS_MODE].value;
  68. if (tossTrigger.process(inputs[TOSS_IN].value + params[TOSS_UI].value)) {
  69. gatePulse.trigger(0.01f);
  70. if (flipMode)
  71. gate = (randomUniform() < params[PROB_UI].value + inputs[PROB_CV].value) ? !gate : gate; //
  72. else
  73. gate = (randomUniform() < (params[PROB_UI].value + inputs[PROB_CV].value*0.1f));
  74. }
  75. if (flipTrigger.process(inputs[FLIP_IN].value + params[FLIP_UI].value)) {
  76. gatePulse.trigger(0.01f);
  77. gate = !gate;
  78. }
  79. if (resetTrigger.process(inputs[SET_A_IN].value + params[SET_A_UI].value)) {
  80. gatePulse.trigger(0.01f);
  81. gate = false;
  82. }
  83. if (resetTrigger.process(inputs[SET_B_IN].value + params[SET_B_UI].value)) {
  84. gatePulse.trigger(0.01f);
  85. gate = true;
  86. }
  87. outputs[SIG_A_OUT].value = !gate * inputs[SIG_IN].value;
  88. outputs[GATE_A_OUT].value = !gate * 10.0f;
  89. outputs[TRIG_A_OUT].value = !gate * gatePulse.process(1.0/engineGetSampleRate()) * 10.0f;
  90. outputs[SIG_B_OUT].value = gate * inputs[SIG_IN].value;
  91. outputs[GATE_B_OUT].value = gate * 10.0f;
  92. outputs[TRIG_B_OUT].value = gate * gatePulse.process(1.0/engineGetSampleRate()) * 10.0f;
  93. lights[A_LED].value = !gate;
  94. lights[B_LED].value = gate;
  95. lights[DIR_LED].value = !flipMode;
  96. lights[FLP_LED].value = flipMode;
  97. }
  98. struct ModeToggle : SVGSwitch, ToggleSwitch {
  99. ModeToggle() {
  100. addFrame(SVG::load(assetPlugin(plugin, "res/components/empty.svg")));
  101. box.size = Vec(12,6);
  102. }
  103. };
  104. struct TailsWidget : ModuleWidget {
  105. TailsWidget(Tails *module);
  106. };
  107. TailsWidget::TailsWidget(Tails *module) : ModuleWidget(module) {
  108. setPanel(SVG::load(assetPlugin(plugin, "res/panels/Tails.svg")));
  109. // screws
  110. // addChild(Widget::create<ScrewHead1>(Vec(0, 0)));
  111. addChild(Widget::create<ScrewHead2>(Vec(box.size.x - 30, 0)));
  112. addChild(Widget::create<ScrewHead3>(Vec(15, 365)));
  113. addChild(Widget::create<ScrewHead4>(Vec(box.size.x - 15, 365)));
  114. addInput(Port::create<InPortAud>(Vec(19,22), Port::INPUT, module, Tails::SIG_IN));
  115. addParam(ParamWidget::create<PvCKnob>(Vec(19,64), module, Tails::PROB_UI, 0.0f, 1.0f, 0.5f));
  116. addInput(Port::create<InPortCtrl>(Vec(19,88), Port::INPUT, module, Tails::PROB_CV));
  117. addInput(Port::create<InPortBin>(Vec(19,124), Port::INPUT, module, Tails::TOSS_IN));
  118. addParam(ParamWidget::create<LabelButtonL>(Vec(12,149), module, Tails::TOSS_UI, 0, 1, 0));
  119. addChild(ModuleLightWidget::create<FourPixLight<OrangeLED>>(Vec(25,165),module, Tails::DIR_LED));
  120. addChild(ModuleLightWidget::create<FourPixLight<BlueLED>>(Vec(31,165),module, Tails::FLP_LED));
  121. addParam(ParamWidget::create<ModeToggle>(Vec(24,164), module, Tails::TOSS_MODE, 0, 1, 0));
  122. addInput(Port::create<InPortBin>(Vec(19,180), Port::INPUT, module, Tails::FLIP_IN));
  123. addParam(ParamWidget::create<LabelButtonL>(Vec(12,205), module, Tails::FLIP_UI, 0, 1, 0));
  124. addInput(Port::create<InPortBin>(Vec(4,222), Port::INPUT, module, Tails::SET_A_IN));
  125. addParam(ParamWidget::create<LabelButtonS>(Vec(3,247), module, Tails::SET_A_UI, 0, 1, 0));
  126. addChild(ModuleLightWidget::create<FourPixLight<CyanLED>>(Vec(13,267),module, Tails::A_LED));
  127. addOutput(Port::create<OutPortVal>(Vec(4,276), Port::OUTPUT, module, Tails::SIG_A_OUT));
  128. addOutput(Port::create<OutPortBin>(Vec(4,312), Port::OUTPUT, module, Tails::GATE_A_OUT));
  129. addOutput(Port::create<OutPortBin>(Vec(4,336), Port::OUTPUT, module, Tails::TRIG_A_OUT));
  130. addInput(Port::create<InPortBin>(Vec(34,222), Port::INPUT, module, Tails::SET_B_IN));
  131. addParam(ParamWidget::create<LabelButtonS>(Vec(33,247), module, Tails::SET_B_UI, 0, 1, 0));
  132. addChild(ModuleLightWidget::create<FourPixLight<PurpleLED>>(Vec(43,267),module, Tails::B_LED));
  133. addOutput(Port::create<OutPortVal>(Vec(34,276), Port::OUTPUT, module, Tails::SIG_B_OUT));
  134. addOutput(Port::create<OutPortBin>(Vec(34,312), Port::OUTPUT, module, Tails::GATE_B_OUT));
  135. addOutput(Port::create<OutPortBin>(Vec(34,336), Port::OUTPUT, module, Tails::TRIG_B_OUT));
  136. }
  137. } // namespace rack_plugin_PvC
  138. using namespace rack_plugin_PvC;
  139. RACK_PLUGIN_MODEL_INIT(PvC, Tails) {
  140. Model *modelTails = Model::create<Tails, TailsWidget>(
  141. "PvC", "Tails", "Tails", LOGIC_TAG, SWITCH_TAG, RANDOM_TAG);
  142. return modelTails;
  143. }