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.

169 lines
6.1KB

  1. #include "EightOne.hpp"
  2. #define SELECT_ON_CLOCK "select_on_clock"
  3. void EightOne::onReset() {
  4. _step = 0;
  5. _clock.reset();
  6. _reset.reset();
  7. }
  8. void EightOne::onSampleRateChange() {
  9. _timer.setParams(engineGetSampleRate(), 0.001f);
  10. }
  11. json_t* EightOne::toJson() {
  12. json_t* root = json_object();
  13. json_object_set_new(root, SELECT_ON_CLOCK, json_boolean(_selectOnClock));
  14. return root;
  15. }
  16. void EightOne::fromJson(json_t* root) {
  17. json_t* s = json_object_get(root, SELECT_ON_CLOCK);
  18. if (s) {
  19. _selectOnClock = json_is_true(s);
  20. }
  21. }
  22. void EightOne::step() {
  23. bool reset = _reset.process(inputs[RESET_INPUT].value);
  24. if (reset) {
  25. _timer.reset();
  26. }
  27. bool timer = _timer.next();
  28. bool clock = _clock.process(inputs[CLOCK_INPUT].value) && !timer;
  29. int steps = clamp(params[STEPS_PARAM].value, 1.0f, 8.0f);
  30. int reverse = 1 - 2 * (params[DIRECTION_PARAM].value == 0.0f);
  31. _step = (_step + reverse * clock) % steps;
  32. _step += (_step < 0) * steps;
  33. _step -= _step * reset;
  34. int select = params[SELECT_PARAM].value;
  35. select += clamp(inputs[SELECT_INPUT].value, 0.0f, 10.0f) * 0.1f * 8.0f;
  36. if (!_selectOnClock || clock) {
  37. _select = select;
  38. }
  39. int step = _step + _select;
  40. step = step % 8;
  41. float out = 0.0f;
  42. for (int i = 0; i < 8; ++i) {
  43. out += inputs[IN1_INPUT + i].value * (step == i);
  44. lights[IN1_LIGHT + i].value = step == i;
  45. }
  46. outputs[OUT_OUTPUT].value = out;
  47. }
  48. struct SelectOnClockMenuItem : MenuItem {
  49. EightOne* _module;
  50. SelectOnClockMenuItem(EightOne* module, const char* label)
  51. : _module(module)
  52. {
  53. this->text = label;
  54. }
  55. void onAction(EventAction &e) override {
  56. _module->_selectOnClock = !_module->_selectOnClock;
  57. }
  58. void step() override {
  59. rightText = _module->_selectOnClock ? "?" : "";
  60. }
  61. };
  62. struct EightOneWidget : ModuleWidget {
  63. static constexpr int hp = 6;
  64. EightOneWidget(EightOne* module) : ModuleWidget(module) {
  65. box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
  66. {
  67. SVGPanel *panel = new SVGPanel();
  68. panel->box.size = box.size;
  69. panel->setBackground(SVG::load(assetPlugin(plugin, "res/EightOne.svg")));
  70. addChild(panel);
  71. }
  72. addChild(Widget::create<ScrewSilver>(Vec(0, 0)));
  73. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15, 365)));
  74. // generated by svg_widgets.rb
  75. auto stepsParamPosition = Vec(58.5, 131.5);
  76. auto directionParamPosition = Vec(58.5, 167.5);
  77. auto selectParamPosition = Vec(52.0, 230.0);
  78. auto in1InputPosition = Vec(11.5, 35.0);
  79. auto in2InputPosition = Vec(11.5, 76.3);
  80. auto in3InputPosition = Vec(11.5, 118.6);
  81. auto in4InputPosition = Vec(11.5, 158.9);
  82. auto in5InputPosition = Vec(11.5, 200.1);
  83. auto in6InputPosition = Vec(11.5, 241.4);
  84. auto in7InputPosition = Vec(11.5, 282.7);
  85. auto in8InputPosition = Vec(11.5, 324.0);
  86. auto clockInputPosition = Vec(54.5, 35.0);
  87. auto resetInputPosition = Vec(54.5, 72.0);
  88. auto selectInputPosition = Vec(54.5, 270.0);
  89. auto outOutputPosition = Vec(54.5, 324.0);
  90. auto in1LightPosition = Vec(23.5, 61.5);
  91. auto in2LightPosition = Vec(23.5, 102.8);
  92. auto in3LightPosition = Vec(23.5, 145.1);
  93. auto in4LightPosition = Vec(23.5, 185.4);
  94. auto in5LightPosition = Vec(23.5, 226.6);
  95. auto in6LightPosition = Vec(23.5, 267.9);
  96. auto in7LightPosition = Vec(23.5, 309.2);
  97. auto in8LightPosition = Vec(23.5, 350.5);
  98. // end generated by svg_widgets.rb
  99. {
  100. auto w = ParamWidget::create<Knob16>(stepsParamPosition, module, EightOne::STEPS_PARAM, 1.0, 8.0, 8.0);
  101. dynamic_cast<Knob*>(w)->snap = true;
  102. addParam(w);
  103. }
  104. addParam(ParamWidget::create<SliderSwitch2State14>(directionParamPosition, module, EightOne::DIRECTION_PARAM, 0.0, 1.0, 1.0));
  105. {
  106. auto w = ParamWidget::create<Knob29>(selectParamPosition, module, EightOne::SELECT_PARAM, 0.0, 7.0, 0.0);
  107. dynamic_cast<Knob*>(w)->snap = true;
  108. addParam(w);
  109. }
  110. addInput(Port::create<Port24>(in1InputPosition, Port::INPUT, module, EightOne::IN1_INPUT));
  111. addInput(Port::create<Port24>(in2InputPosition, Port::INPUT, module, EightOne::IN2_INPUT));
  112. addInput(Port::create<Port24>(in3InputPosition, Port::INPUT, module, EightOne::IN3_INPUT));
  113. addInput(Port::create<Port24>(in4InputPosition, Port::INPUT, module, EightOne::IN4_INPUT));
  114. addInput(Port::create<Port24>(in5InputPosition, Port::INPUT, module, EightOne::IN5_INPUT));
  115. addInput(Port::create<Port24>(in6InputPosition, Port::INPUT, module, EightOne::IN6_INPUT));
  116. addInput(Port::create<Port24>(in7InputPosition, Port::INPUT, module, EightOne::IN7_INPUT));
  117. addInput(Port::create<Port24>(in8InputPosition, Port::INPUT, module, EightOne::IN8_INPUT));
  118. addInput(Port::create<Port24>(clockInputPosition, Port::INPUT, module, EightOne::CLOCK_INPUT));
  119. addInput(Port::create<Port24>(resetInputPosition, Port::INPUT, module, EightOne::RESET_INPUT));
  120. addInput(Port::create<Port24>(selectInputPosition, Port::INPUT, module, EightOne::SELECT_INPUT));
  121. addOutput(Port::create<Port24>(outOutputPosition, Port::OUTPUT, module, EightOne::OUT_OUTPUT));
  122. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in1LightPosition, module, EightOne::IN1_LIGHT));
  123. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in2LightPosition, module, EightOne::IN2_LIGHT));
  124. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in3LightPosition, module, EightOne::IN3_LIGHT));
  125. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in4LightPosition, module, EightOne::IN4_LIGHT));
  126. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in5LightPosition, module, EightOne::IN5_LIGHT));
  127. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in6LightPosition, module, EightOne::IN6_LIGHT));
  128. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in7LightPosition, module, EightOne::IN7_LIGHT));
  129. addChild(ModuleLightWidget::create<SmallLight<GreenLight>>(in8LightPosition, module, EightOne::IN8_LIGHT));
  130. }
  131. void appendContextMenu(Menu* menu) override {
  132. EightOne* m = dynamic_cast<EightOne*>(module);
  133. assert(m);
  134. menu->addChild(new MenuLabel());
  135. menu->addChild(new SelectOnClockMenuItem(m, "Select on clock"));
  136. }
  137. };
  138. RACK_PLUGIN_MODEL_INIT(Bogaudio, EightOne) {
  139. Model* modelEightOne = createModel<EightOne, EightOneWidget>("Bogaudio-EightOne", "8:1", "demux & sequential switch", SWITCH_TAG);
  140. return modelEightOne;
  141. }