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.

160 lines
6.0KB

  1. #include "common.hpp"
  2. #include "uncert.hpp"
  3. namespace rack_plugin_TheXOR {
  4. void Uncertain::on_loaded()
  5. {
  6. load();
  7. }
  8. void Uncertain::load()
  9. {
  10. fluctParams.reset();
  11. }
  12. void Uncertain::step()
  13. {
  14. if(inputs[CLOCK_FLUCT].active)
  15. out_fluct(clock_fluct.process(inputs[CLOCK_FLUCT].value));
  16. else
  17. fluctParams.reset();
  18. if(inputs[CLOCK_QUANTIZED].active)
  19. out_quantized(clock_quantized.process(inputs[CLOCK_QUANTIZED].value));
  20. if(inputs[CLOCK_STORED].active)
  21. out_stored(clock_stored.process(inputs[CLOCK_STORED].value));
  22. }
  23. void Uncertain::out_quantized(int clk)
  24. {
  25. if(clk == 1)
  26. {
  27. int position = getInt(QUANTIZED_AMT, IN_QUANTIZED, 0.0, 5.0)+1;
  28. outputs[OUT_QUANTIZED_N1].value = roundf(rescale(randomUniform(), 0.0, 1.0, 0.0, position)); // 1V
  29. float n2= roundf(rescale(randomUniform(), 0.0, 1.0, 1.0, 2 << position));
  30. outputs[OUT_QUANTIZED_2N].value = clamp(Uncertain::SEMITONE*n2, 0.0, 10.0);
  31. }
  32. }
  33. void Uncertain::out_stored(int clk)
  34. {
  35. if(clk == 1)
  36. {
  37. outputs[OUT_STORED_RND].value = clamp(roundf(rescale(randomUniform(), 0.0, 1.0, 0.0, 1000.0)) * MIN_VOLTAGE, 0.0,10.0);
  38. outputs[OUT_STORED_BELL].value = rndGaussianVoltage();
  39. }
  40. }
  41. float Uncertain::rndGaussianVoltage()
  42. {
  43. float mu = getFloat(STORED_AMT, IN_STORED, MIN_VOLTAGE, MAX_VOLTAGE);
  44. float sigma = getFloat(CURVEAMP_AMT, IN_CURVEAMP, 0.01, 2.0);
  45. float u1 = 1.0 - randomUniform();
  46. float u2 = 1.0 - randomUniform();
  47. float randStdNormal = sqrtf(-2.0 * logf(u1)) * sinf(2.0 * M_PI * u2); //random normal(0,1)
  48. return clamp(mu + sigma * randStdNormal, MIN_VOLTAGE, MAX_VOLTAGE);
  49. }
  50. float Uncertain::rndFluctVoltage()
  51. {
  52. float vmax = getFloat(FLUCT_AMT, IN_FLUCT, MIN_VOLTAGE, MAX_VOLTAGE);
  53. return clamp(rescale(randomUniform(), 0.0, 1.0, MIN_VOLTAGE, vmax), MIN_VOLTAGE, MAX_VOLTAGE);
  54. }
  55. void Uncertain::out_fluct(int clk)
  56. {
  57. switch(clk)
  58. {
  59. case 1: //rise
  60. {
  61. if(fluctParams.duration == 0) // 0 if first cycle
  62. {
  63. outputs[OUT_FLUCT].value = fluctParams.vA = fluctParams.vB = rndFluctVoltage();
  64. }
  65. fluctParams.tStart = clock();
  66. }
  67. break;
  68. case -1: //fall
  69. {
  70. fluctParams.vB = rndFluctVoltage();
  71. fluctParams.duration = clock() - fluctParams.tStart;
  72. fluctParams.tStart = 0;
  73. if(fluctParams.duration > 0)
  74. {
  75. fluctParams.vA = outputs[OUT_FLUCT].value;
  76. fluctParams.deltaV = (fluctParams.vB - fluctParams.vA) / fluctParams.duration;
  77. }
  78. }
  79. break;
  80. default: // in progress
  81. {
  82. if(fluctParams.duration != 0 && fluctParams.tStart != 0) // 0 if first cycle
  83. {
  84. clock_t elapsed = clock() - fluctParams.tStart;
  85. float v = fluctParams.vA + fluctParams.deltaV * elapsed;
  86. outputs[OUT_FLUCT].value = clamp(v, MIN_VOLTAGE, MAX_VOLTAGE);
  87. }
  88. }
  89. break;
  90. }
  91. }
  92. float Uncertain::getFloat(ParamIds p_id, InputIds i_id, float minValue, float maxValue)
  93. {
  94. float offs = inputs[i_id].active ? rescale(inputs[i_id].value, 0.0, 5.0, minValue, maxValue) : 0.0;
  95. return clamp(offs + params[p_id].value, minValue, maxValue);
  96. }
  97. UncertainWidget::UncertainWidget(Uncertain *module) : SequencerWidget(module)
  98. {
  99. box.size = Vec(12 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  100. {
  101. SVGPanel *panel = new SVGPanel();
  102. panel->box.size = box.size;
  103. panel->setBackground(SVG::load(assetPlugin(plugin, "res/modules/uncert.svg")));
  104. addChild(panel);
  105. }
  106. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, 0)));
  107. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  108. addChild(Widget::create<ScrewBlack>(Vec(RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  109. addChild(Widget::create<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y - RACK_GRID_WIDTH)));
  110. float lft_x = mm2px(4.726);
  111. float rgt_x = mm2px(47.988);
  112. float center_x = mm2px(25.717);
  113. addInput(Port::create<PJ301RPort>(Vec(lft_x, yncscape(107.334,8.255)), Port::INPUT, module, Uncertain::CLOCK_FLUCT));
  114. addInput(Port::create<PJ301BPort>(Vec(lft_x, yncscape(89.809, 8.255)), Port::INPUT, module, Uncertain::IN_FLUCT));
  115. addParam(ParamWidget::create<Davies1900hFixRedKnob>(Vec(center_x, yncscape(97.936, 9.525)), module, Uncertain::FLUCT_AMT, Uncertain::MIN_VOLTAGE, Uncertain::MAX_VOLTAGE, Uncertain::MIN_VOLTAGE));
  116. addOutput(Port::create<PJ301GPort>(Vec(rgt_x, yncscape(98.571, 8.255)), Port::OUTPUT, module, Uncertain::OUT_FLUCT));
  117. addInput(Port::create<PJ301RPort>(Vec(lft_x, yncscape(68.885, 8.255)), Port::INPUT, module, Uncertain::CLOCK_QUANTIZED));
  118. addInput(Port::create<PJ301BPort>(Vec(lft_x, yncscape(51.360, 8.255)), Port::INPUT, module, Uncertain::IN_QUANTIZED));
  119. ParamWidget *pw = ParamWidget::create<Davies1900hFixWhiteKnob>(Vec(center_x, yncscape(59.487, 9.525)), module, Uncertain::QUANTIZED_AMT, 0.0, 5.0, 0.0);
  120. ((Davies1900hKnob *)pw)->snap = true;
  121. addParam(pw);
  122. addOutput(Port::create<PJ301GPort>(Vec(rgt_x, yncscape(68.885, 8.255)), Port::OUTPUT, module, Uncertain::OUT_QUANTIZED_N1));
  123. addOutput(Port::create<PJ301GPort>(Vec(rgt_x, yncscape(51.360, 8.255)), Port::OUTPUT, module, Uncertain::OUT_QUANTIZED_2N));
  124. addInput(Port::create<PJ301RPort>(Vec(lft_x, yncscape(28.407, 8.255)), Port::INPUT, module, Uncertain::CLOCK_STORED));
  125. addInput(Port::create<PJ301BPort>(Vec(lft_x, yncscape(10.882, 8.255)), Port::INPUT, module, Uncertain::IN_STORED));
  126. addInput(Port::create<PJ301BPort>(Vec(mm2px(23.591), yncscape(10.882, 8.255)), Port::INPUT, module, Uncertain::IN_CURVEAMP));
  127. addParam(ParamWidget::create<Davies1900hFixBlackKnob>(Vec(mm2px(16.285), yncscape(19.010, 9.525)), module, Uncertain::STORED_AMT, Uncertain::MIN_VOLTAGE + 2.5, Uncertain::MAX_VOLTAGE - 2.5, 5.0));
  128. addParam(ParamWidget::create<Davies1900hFixBlackKnob>(Vec(mm2px(35.150), yncscape(19.010, 9.525)), module, Uncertain::CURVEAMP_AMT, 0.0,2.0,1.0));
  129. addOutput(Port::create<PJ301GPort>(Vec(rgt_x, yncscape(28.407, 8.255)), Port::OUTPUT, module, Uncertain::OUT_STORED_RND));
  130. addOutput(Port::create<PJ301GPort>(Vec(rgt_x, yncscape(10.882, 8.255)), Port::OUTPUT, module, Uncertain::OUT_STORED_BELL));
  131. }
  132. } // namespace rack_plugin_TheXOR
  133. using namespace rack_plugin_TheXOR;
  134. RACK_PLUGIN_MODEL_INIT(TheXOR, Uncertain) {
  135. return Model::create<Uncertain, UncertainWidget>("TheXOR", "Uncertain", "Uncertain", RANDOM_TAG);
  136. }