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.

239 lines
7.2KB

  1. #include "common.hpp"
  2. #include "burst.hpp"
  3. namespace rack_plugin_TheXOR {
  4. void Burst::on_loaded()
  5. {
  6. load();
  7. }
  8. void Burst::load()
  9. {
  10. trigger_pending = false;
  11. all_off();
  12. }
  13. void Burst::all_off()
  14. {
  15. for(int k = 0; k < NUM_BURST_PORTS; k++)
  16. port(k, false);
  17. active = false;
  18. }
  19. void Burst::step()
  20. {
  21. if(resetTrigger.process(inputs[RESET].value))
  22. {
  23. reset();
  24. } else
  25. {
  26. if(!active && !trigger_pending)
  27. {
  28. float tv = inputs[TRIGGER_THRESH_IN].active && inputs[TRIGGER_THRESH_IN].value > params[TRIG_THRESH].value ? 1.0 : 0.0;
  29. trigger_pending = trigger.process(params[TRIGGER].value + tv);
  30. }
  31. int clk = clock.process(inputs[CLOCK_IN].value); // 1=rise, -1=fall
  32. if(clk == 1)
  33. {
  34. if(!active && trigger_pending)
  35. {
  36. prepare_step();
  37. }
  38. if(active)
  39. next_step();
  40. } else if(active && clk == -1)
  41. end_step();
  42. }
  43. }
  44. void Burst::prepare_step()
  45. {
  46. activating_params.first_cycle = true;
  47. activating_params.cycle_counter = activating_params.out_span = 0;
  48. activating_params.max_span = getInt(OUT_SPAN, OUT_SPAN_IN, 1, NUM_BURST_PORTS);
  49. activating_params.mode = (enum Burst::MODE)int(roundf(params[MODE].value));
  50. activating_params.invert_mode = roundf(params[MODE_INVERT].value) > 0.5;
  51. activating_params.retrogade = false;
  52. activating_params.max_cycle = getInt(EVENT_COUNT, EVENT_COUNT_IN, 0, 23) + 1;
  53. trigger_pending = false;
  54. active = true;
  55. }
  56. void Burst::end_step()
  57. {
  58. if(activating_params.cycle_counter >= activating_params.max_cycle)
  59. {
  60. all_off(); // ciclo terminato
  61. } else
  62. {
  63. switch(activating_params.mode)
  64. {
  65. case Burst::RAND:
  66. {
  67. port(activating_params.out_span, false);
  68. }
  69. break;
  70. case Burst::PEND:
  71. case Burst::FWD:
  72. {
  73. if(!activating_params.invert_mode)
  74. {
  75. port(activating_params.out_span, false);
  76. }
  77. }
  78. break;
  79. }
  80. }
  81. }
  82. void Burst::next_step()
  83. {
  84. switch(activating_params.mode)
  85. {
  86. case Burst::RAND:
  87. {
  88. activating_params.out_span = int(rescale(randomUniform(), 0.0, 1.0, 0.0, activating_params.max_span));
  89. port(activating_params.out_span, true);
  90. activating_params.cycle_counter++;
  91. }
  92. break;
  93. case Burst::FWD:
  94. {
  95. if(activating_params.first_cycle)
  96. activating_params.first_cycle = false;
  97. else
  98. {
  99. if(++activating_params.out_span >= activating_params.max_span)
  100. {
  101. activating_params.out_span = 0;
  102. activating_params.cycle_counter++;
  103. }
  104. }
  105. if(activating_params.cycle_counter < activating_params.max_cycle)
  106. {
  107. if(activating_params.invert_mode)
  108. invert_port(activating_params.out_span);
  109. else
  110. {
  111. port(activating_params.out_span, true);
  112. }
  113. }
  114. }
  115. break;
  116. case Burst::PEND:
  117. {
  118. if(activating_params.first_cycle)
  119. activating_params.first_cycle = false;
  120. else
  121. {
  122. if(activating_params.retrogade)
  123. {
  124. if(--activating_params.out_span < 0)
  125. {
  126. if(activating_params.max_span > 0)
  127. activating_params.out_span = activating_params.invert_mode ? 0 : 1;
  128. else
  129. activating_params.out_span = 0;
  130. activating_params.retrogade = false;
  131. activating_params.cycle_counter++;
  132. }
  133. } else
  134. {
  135. if(++activating_params.out_span >= activating_params.max_span)
  136. {
  137. if(activating_params.max_span > 1)
  138. activating_params.out_span = activating_params.invert_mode ? activating_params.out_span-1 : activating_params.out_span - 2;
  139. else
  140. activating_params.out_span = 0;
  141. activating_params.retrogade = true;
  142. activating_params.cycle_counter++;
  143. }
  144. }
  145. }
  146. if(activating_params.cycle_counter < activating_params.max_cycle)
  147. {
  148. if(activating_params.invert_mode)
  149. invert_port(activating_params.out_span);
  150. else
  151. port(activating_params.out_span, true);
  152. }
  153. }
  154. break;
  155. }
  156. }
  157. int Burst::getInt(ParamIds p_id, InputIds i_id, float minValue, float maxValue)
  158. {
  159. float offs = inputs[i_id].active ? rescale(inputs[i_id].value, 0.0, 5.0, minValue, maxValue) : 0.0;
  160. return (int)clamp(offs + params[p_id].value, minValue, maxValue);
  161. }
  162. BurstWidget::BurstWidget(Burst *module) : SequencerWidget(module)
  163. {
  164. box.size = Vec(16 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  165. {
  166. SVGPanel *panel = new SVGPanel();
  167. panel->box.size = box.size;
  168. panel->setBackground(SVG::load(assetPlugin(plugin, "res/modules/Burst.svg")));
  169. addChild(panel);
  170. }
  171. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  172. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  173. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  174. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  175. float lft_x = mm2px(3.428);
  176. addInput(Port::create<PJ301RPort>(Vec(lft_x, yncscape(108.765, 8.255)), Port::INPUT, module, Burst::CLOCK_IN));
  177. addParam(ParamWidget::create<CKSSThreeFix>(Vec(mm2px(31.624), yncscape(105.749, 10.0)), module, Burst::MODE, 0.0, 2.0, 0.0));
  178. addParam(ParamWidget::create<CKSSFix>(Vec(mm2px(71.875), yncscape(107.990, 5.46)), module, Burst::MODE_INVERT, 0.0, 1.0, 0.0));
  179. addInput(Port::create<PJ301BPort>(Vec(lft_x, yncscape(74.386, 8.255)), Port::INPUT, module, Burst::OUT_SPAN_IN));
  180. ParamWidget *pwdg = ParamWidget::create<Davies1900hFixWhiteKnob>(Vec(mm2px(22.644), yncscape(73.751, 9.525)), module, Burst::OUT_SPAN, 1.0, NUM_BURST_PORTS, 1.0);
  181. ((Davies1900hKnob *)pwdg)->snap = true;
  182. addParam(pwdg);
  183. pwdg = ParamWidget::create<Davies1900hFixWhiteKnob>(Vec(mm2px(49.111), yncscape(73.751, 9.525)), module, Burst::EVENT_COUNT, 0.0, 23.0, 0.0);
  184. ((Davies1900hKnob *)pwdg)->snap = true;
  185. addParam(pwdg);
  186. addInput(Port::create<PJ301BPort>(Vec(mm2px(69.597), yncscape(74.386, 8.255)), Port::INPUT, module, Burst::EVENT_COUNT_IN));
  187. addInput(Port::create<PJ301BPort>(Vec(lft_x, yncscape(43.036, 8.255)), Port::INPUT, module, Burst::TRIGGER_THRESH_IN));
  188. addParam(ParamWidget::create<Davies1900hFixRedKnob>(Vec(mm2px(16.027), yncscape(42.401, 9.525)), module, Burst::TRIG_THRESH, LVL_OFF, LVL_ON, LVL_OFF));
  189. addInput(Port::create<PJ301YPort>(Vec(mm2px(56.363), yncscape(43.036, 8.255)), Port::INPUT, module, Burst::RESET));
  190. addParam(ParamWidget::create<BefacoPushBig>(Vec(mm2px(69.224), yncscape(42.664, 8.999)), module, Burst::TRIGGER, 0.0, 1.0, 0.0));
  191. float ysup_port = yncscape(17.532, 8.255);
  192. float yinf_port = yncscape(4.832, 8.255);
  193. float ysup_led = yncscape(19.070, 5.179);
  194. float yinf_led = yncscape(6.370, 5.179);
  195. float x_ports[NUM_BURST_PORTS] = {3.428, 16.662, 29.895, 43.129, 56.363, 69.597};
  196. float x_leds[NUM_BURST_PORTS] = {4.966, 18.200, 31.434, 44.667, 57.901, 71.135};
  197. for(int k = 0; k < NUM_BURST_PORTS; k++)
  198. {
  199. if(k < NUM_BURST_PORTS / 2)
  200. {
  201. addOutput(Port::create<PJ301WPort>(Vec(mm2px(x_ports[k]), ysup_port), Port::OUTPUT, module, Burst::OUT_1+k));
  202. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(Vec(mm2px(x_leds[k]), yinf_led), module, Burst::LEDOUT_1 + k));
  203. } else
  204. {
  205. addOutput(Port::create<PJ301WPort>(Vec(mm2px(x_ports[k]), yinf_port), Port::OUTPUT, module, Burst::OUT_1 + k));
  206. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(Vec(mm2px(x_leds[k]), ysup_led), module, Burst::LEDOUT_1 + k));
  207. }
  208. }
  209. }
  210. } // namespace rack_plugin_TheXOR
  211. using namespace rack_plugin_TheXOR;
  212. RACK_PLUGIN_MODEL_INIT(TheXOR, Burst) {
  213. return Model::create<Burst, BurstWidget>("TheXOR", "Burst", "Burst", SEQUENCER_TAG);
  214. }