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.

167 lines
4.7KB

  1. #include "HetrickCV.hpp"
  2. namespace rack_plugin_HetrickCV {
  3. #ifdef USE_VST2
  4. #define plugin "HetrickCV"
  5. #endif // USE_VST2
  6. struct Rotator : Module
  7. {
  8. enum ParamIds
  9. {
  10. ROTATE_PARAM,
  11. STAGES_PARAM,
  12. NUM_PARAMS
  13. };
  14. enum InputIds
  15. {
  16. IN1_INPUT,
  17. IN2_INPUT,
  18. IN3_INPUT,
  19. IN4_INPUT,
  20. IN5_INPUT,
  21. IN6_INPUT,
  22. IN7_INPUT,
  23. IN8_INPUT,
  24. ROTATE_INPUT,
  25. STAGES_INPUT,
  26. NUM_INPUTS
  27. };
  28. enum OutputIds
  29. {
  30. OUT1_OUTPUT,
  31. OUT2_OUTPUT,
  32. OUT3_OUTPUT,
  33. OUT4_OUTPUT,
  34. OUT5_OUTPUT,
  35. OUT6_OUTPUT,
  36. OUT7_OUTPUT,
  37. OUT8_OUTPUT,
  38. NUM_OUTPUTS
  39. };
  40. enum LightIds
  41. {
  42. IN1_POS_LIGHT, IN1_NEG_LIGHT,
  43. IN2_POS_LIGHT, IN2_NEG_LIGHT,
  44. IN3_POS_LIGHT, IN3_NEG_LIGHT,
  45. IN4_POS_LIGHT, IN4_NEG_LIGHT,
  46. IN5_POS_LIGHT, IN5_NEG_LIGHT,
  47. IN6_POS_LIGHT, IN6_NEG_LIGHT,
  48. IN7_POS_LIGHT, IN7_NEG_LIGHT,
  49. IN8_POS_LIGHT, IN8_NEG_LIGHT,
  50. OUT1_POS_LIGHT, OUT1_NEG_LIGHT,
  51. OUT2_POS_LIGHT, OUT2_NEG_LIGHT,
  52. OUT3_POS_LIGHT, OUT3_NEG_LIGHT,
  53. OUT4_POS_LIGHT, OUT4_NEG_LIGHT,
  54. OUT5_POS_LIGHT, OUT5_NEG_LIGHT,
  55. OUT6_POS_LIGHT, OUT6_NEG_LIGHT,
  56. OUT7_POS_LIGHT, OUT7_NEG_LIGHT,
  57. OUT8_POS_LIGHT, OUT8_NEG_LIGHT,
  58. NUM_LIGHTS
  59. };
  60. float ins[8] = {};
  61. float outs[8] = {};
  62. Rotator() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS)
  63. {
  64. }
  65. void step() override;
  66. int clampInt(const int _in, const int min = 0, const int max = 7)
  67. {
  68. if (_in > max) return max;
  69. if (_in < min) return min;
  70. return _in;
  71. }
  72. // For more advanced Module features, read Rack's engine.hpp header file
  73. // - toJson, fromJson: serialization of internal data
  74. // - onSampleRateChange: event triggered by a change of sample rate
  75. // - reset, randomize: implements special behavior when user clicks these from the context menu
  76. };
  77. void Rotator::step()
  78. {
  79. int rotation = round(params[ROTATE_PARAM].value + inputs[ROTATE_INPUT].value);
  80. int stages = round(params[STAGES_PARAM].value + inputs[STAGES_INPUT].value);
  81. rotation = clampInt(rotation);
  82. stages = clampInt(stages) + 1;
  83. for(int i = 0; i < 8; i++)
  84. {
  85. const int input = (rotation + i) % stages;
  86. outputs[i].value = inputs[input].value;
  87. lights[IN1_POS_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, inputs[i].value / 5.0));
  88. lights[IN1_NEG_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, inputs[i].value / -5.0));
  89. lights[OUT1_POS_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, outputs[i].value / 5.0));
  90. lights[OUT1_NEG_LIGHT + 2*i].setBrightnessSmooth(fmaxf(0.0, outputs[i].value / -5.0));
  91. }
  92. }
  93. struct RotatorWidget : ModuleWidget { RotatorWidget(Rotator *module); };
  94. RotatorWidget::RotatorWidget(Rotator *module) : ModuleWidget(module)
  95. {
  96. box.size = Vec(12 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  97. {
  98. auto *panel = new SVGPanel();
  99. panel->box.size = box.size;
  100. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Rotator.svg")));
  101. addChild(panel);
  102. }
  103. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  104. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)));
  105. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  106. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)));
  107. //////PARAMS//////
  108. addParam(ParamWidget::create<Davies1900hBlackKnob>(Vec(70, 85), module, Rotator::ROTATE_PARAM, 0, 7.0, 0.0));
  109. addParam(ParamWidget::create<Davies1900hBlackKnob>(Vec(70, 245), module, Rotator::STAGES_PARAM, 0, 7.0, 7.0));
  110. addInput(Port::create<PJ301MPort>(Vec(75, 150), Port::INPUT, module, Rotator::ROTATE_INPUT));
  111. addInput(Port::create<PJ301MPort>(Vec(75, 310), Port::INPUT, module, Rotator::STAGES_INPUT));
  112. const int inXPos = 10;
  113. const int outXPos = 145;
  114. const int inLightX = 50;
  115. const int outLightX = 120;
  116. for(int i = 0; i < 8; i++)
  117. {
  118. const int yPos = 50 + (40 * i);
  119. const int lightY = 59 + (40 * i);
  120. //////INPUTS//////
  121. addInput(Port::create<PJ301MPort>(Vec(inXPos, yPos), Port::INPUT, module, i));
  122. //////OUTPUTS//////
  123. addOutput(Port::create<PJ301MPort>(Vec(outXPos, yPos), Port::OUTPUT, module, i));
  124. //////BLINKENLIGHTS//////
  125. addChild(ModuleLightWidget::create<SmallLight<GreenRedLight>>(Vec(inLightX, lightY), module, Rotator::IN1_POS_LIGHT + 2*i));
  126. addChild(ModuleLightWidget::create<SmallLight<GreenRedLight>>(Vec(outLightX, lightY), module, Rotator::OUT1_POS_LIGHT + 2*i));
  127. }
  128. }
  129. } // namespace rack_plugin_HetrickCV
  130. using namespace rack_plugin_HetrickCV;
  131. RACK_PLUGIN_MODEL_INIT(HetrickCV, Rotator) {
  132. Model *modelRotator = Model::create<Rotator, RotatorWidget>("HetrickCV", "Rotator", "Rotator", SWITCH_TAG);
  133. return modelRotator;
  134. }