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.

123 lines
2.9KB

  1. #include "HetrickCV.hpp"
  2. namespace rack_plugin_HetrickCV {
  3. struct Crackle : Module
  4. {
  5. enum ParamIds
  6. {
  7. RATE_PARAM,
  8. BROKEN_PARAM,
  9. NUM_PARAMS
  10. };
  11. enum InputIds
  12. {
  13. RATE_INPUT,
  14. NUM_INPUTS
  15. };
  16. enum OutputIds
  17. {
  18. MAIN_OUTPUT,
  19. NUM_OUTPUTS
  20. };
  21. float lastDensity = 1.0;
  22. float densityScaled = 1.0;
  23. float y1 = 0.2643;
  24. float y2 = 0.0;
  25. float lasty1 = 0.2643f;
  26. Crackle() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS)
  27. {
  28. y1 = randomf();
  29. y2 = 0.0f;
  30. lasty1 = 0.0f;
  31. }
  32. void step() override;
  33. void reset() override
  34. {
  35. y1 = randomf();
  36. y2 = 0.0f;
  37. lasty1 = 0.0f;
  38. }
  39. // For more advanced Module features, read Rack's engine.hpp header file
  40. // - toJson, fromJson: serialization of internal data
  41. // - onSampleRateChange: event triggered by a change of sample rate
  42. // - reset, randomize: implements special behavior when user clicks these from the context menu
  43. };
  44. void Crackle::step()
  45. {
  46. const float densityInput = params[RATE_PARAM].value + inputs[RATE_INPUT].value;
  47. if(lastDensity != densityInput)
  48. {
  49. densityScaled = clampf(densityInput, 0.0f, 2.0f)/2.0f;
  50. densityScaled = powf(densityScaled, 3.0f) + 1.0f;
  51. lastDensity = densityInput;
  52. }
  53. const bool brokenMode = (params[BROKEN_PARAM].value == 0.0);
  54. if(brokenMode)
  55. {
  56. const float y0 = fabs(y1 * densityScaled - y2 - 0.05f);
  57. y2 = y1;
  58. y1 = lasty1;
  59. lasty1 = clampf(y0, -1.0f, 1.0f);
  60. outputs[MAIN_OUTPUT].value = clampf(y0 * 5.0f, -5.0, 5.0);
  61. }
  62. else
  63. {
  64. const float y0 = fabs(y1 * densityScaled - y2 - 0.05f);
  65. y2 = y1;
  66. y1 = y0;
  67. outputs[MAIN_OUTPUT].value = clampf(y0 * 5.0f, -5.0, 5.0);
  68. }
  69. }
  70. struct CrackleWidget : ModuleWidget { CrackleWidget(Crackle *module); };
  71. CrackleWidget::CrackleWidget(Crackle *module) : ModuleWidget(module)
  72. {
  73. box.size = Vec(6 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  74. {
  75. auto *panel = new SVGPanel();
  76. panel->box.size = box.size;
  77. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Crackle.svg")));
  78. addChild(panel);
  79. }
  80. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  81. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 0)));
  82. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  83. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 30, 365)));
  84. //////PARAMS//////
  85. addParam(ParamWidget::create<Davies1900hBlackKnob>(Vec(28, 87), module, Crackle::RATE_PARAM, 0.0, 2.0, 1.7));
  86. addParam(ParamWidget::create<CKSS>(Vec(37, 220), module, Crackle::BROKEN_PARAM, 0.0, 1.0, 1.0));
  87. //////INPUTS//////
  88. addInput(Port::create<PJ301MPort>(Vec(33, 146), Port::INPUT, module, Crackle::RATE_INPUT));
  89. //////OUTPUTS//////
  90. addOutput(Port::create<PJ301MPort>(Vec(33, 285), Port::OUTPUT, module, Crackle::MAIN_OUTPUT));
  91. }
  92. } // namespace rack_plugin_HetrickCV
  93. using namespace rack_plugin_HetrickCV;
  94. RACK_PLUGIN_MODEL_INIT(HetrickCV, Crackle) {
  95. Model *modelCrackle = Model::create<Crackle, CrackleWidget>("HetrickCV", "Crackle", "Crackle", NOISE_TAG);
  96. return modelCrackle;
  97. }