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.

114 lines
2.9KB

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