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.

172 lines
5.4KB

  1. #include "Fundamental.hpp"
  2. struct VCA : Module {
  3. enum ParamIds {
  4. LEVEL1_PARAM,
  5. LEVEL2_PARAM,
  6. NUM_PARAMS
  7. };
  8. enum InputIds {
  9. EXP1_INPUT,
  10. LIN1_INPUT,
  11. IN1_INPUT,
  12. EXP2_INPUT,
  13. LIN2_INPUT,
  14. IN2_INPUT,
  15. NUM_INPUTS
  16. };
  17. enum OutputIds {
  18. OUT1_OUTPUT,
  19. OUT2_OUTPUT,
  20. NUM_OUTPUTS
  21. };
  22. VCA() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {}
  23. void step() override;
  24. };
  25. static void stepChannel(Input &in, Param &level, Input &lin, Input &exp, Output &out) {
  26. float v = in.value * level.value;
  27. if (lin.active)
  28. v *= clamp(lin.value / 10.0f, 0.0f, 1.0f);
  29. const float expBase = 50.0f;
  30. if (exp.active)
  31. v *= rescale(powf(expBase, clamp(exp.value / 10.0f, 0.0f, 1.0f)), 1.0f, expBase, 0.0f, 1.0f);
  32. out.value = v;
  33. }
  34. void VCA::step() {
  35. stepChannel(inputs[IN1_INPUT], params[LEVEL1_PARAM], inputs[LIN1_INPUT], inputs[EXP1_INPUT], outputs[OUT1_OUTPUT]);
  36. stepChannel(inputs[IN2_INPUT], params[LEVEL2_PARAM], inputs[LIN2_INPUT], inputs[EXP2_INPUT], outputs[OUT2_OUTPUT]);
  37. }
  38. struct VCAWidget : ModuleWidget {
  39. VCAWidget(VCA *module);
  40. };
  41. VCAWidget::VCAWidget(VCA *module) : ModuleWidget(module) {
  42. setPanel(SVG::load(assetPlugin(plugin, "res/VCA.svg")));
  43. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  44. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  45. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  46. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  47. addParam(createParam<RoundLargeBlackKnob>(mm2px(Vec(6.35, 19.11753)), module, VCA::LEVEL1_PARAM, 0.0, 1.0, 0.0));
  48. addParam(createParam<RoundLargeBlackKnob>(mm2px(Vec(6.35, 74.80544)), module, VCA::LEVEL2_PARAM, 0.0, 1.0, 0.0));
  49. addInput(createPort<PJ301MPort>(mm2px(Vec(2.5907, 38.19371)), PortWidget::INPUT, module, VCA::EXP1_INPUT));
  50. addInput(createPort<PJ301MPort>(mm2px(Vec(14.59752, 38.19371)), PortWidget::INPUT, module, VCA::LIN1_INPUT));
  51. addInput(createPort<PJ301MPort>(mm2px(Vec(2.5907, 52.80642)), PortWidget::INPUT, module, VCA::IN1_INPUT));
  52. addInput(createPort<PJ301MPort>(mm2px(Vec(2.5907, 93.53435)), PortWidget::INPUT, module, VCA::EXP2_INPUT));
  53. addInput(createPort<PJ301MPort>(mm2px(Vec(14.59752, 93.53435)), PortWidget::INPUT, module, VCA::LIN2_INPUT));
  54. addInput(createPort<PJ301MPort>(mm2px(Vec(2.5907, 108.14706)), PortWidget::INPUT, module, VCA::IN2_INPUT));
  55. addOutput(createPort<PJ301MPort>(mm2px(Vec(14.59752, 52.80642)), PortWidget::OUTPUT, module, VCA::OUT1_OUTPUT));
  56. addOutput(createPort<PJ301MPort>(mm2px(Vec(14.59752, 108.14706)), PortWidget::OUTPUT, module, VCA::OUT2_OUTPUT));
  57. }
  58. struct VCA_1 : Module {
  59. enum ParamIds {
  60. LEVEL_PARAM,
  61. EXP_PARAM,
  62. NUM_PARAMS
  63. };
  64. enum InputIds {
  65. CV_INPUT,
  66. IN_INPUT,
  67. NUM_INPUTS
  68. };
  69. enum OutputIds {
  70. OUT_OUTPUT,
  71. NUM_OUTPUTS
  72. };
  73. enum LightIds {
  74. NUM_LIGHTS
  75. };
  76. float lastCv = 0.f;
  77. VCA_1() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  78. void step() override {
  79. float cv = inputs[CV_INPUT].normalize(10.f) / 10.f;
  80. if ((int) params[EXP_PARAM].value == 0)
  81. cv = powf(cv, 4.f);
  82. lastCv = cv;
  83. outputs[OUT_OUTPUT].value = inputs[IN_INPUT].value * params[LEVEL_PARAM].value * cv;
  84. }
  85. };
  86. struct VCA_1VUKnob : Knob {
  87. VCA_1 *module = NULL;
  88. VCA_1VUKnob() {
  89. box.size = mm2px(Vec(10, 46));
  90. }
  91. void draw(NVGcontext *vg) override {
  92. if (!quantity)
  93. return;
  94. float lastCv = module ? module->lastCv : 1.f;
  95. nvgBeginPath(vg);
  96. nvgRoundedRect(vg, 0, 0, box.size.x, box.size.y, 2.0);
  97. nvgFillColor(vg, nvgRGB(0, 0, 0));
  98. nvgFill(vg);
  99. const int segs = 25;
  100. const Vec margin = Vec(4, 4);
  101. Rect r = box.zeroPos().grow(margin);
  102. for (int i = 0; i < segs; i++) {
  103. float value = quantity->getValue();
  104. float segValue = clamp(value * segs - (segs - i - 1), 0.f, 1.f);
  105. float amplitude = value * lastCv;
  106. float segAmplitude = clamp(amplitude * segs - (segs - i - 1), 0.f, 1.f);
  107. nvgBeginPath(vg);
  108. nvgRect(vg, r.pos.x, r.pos.y + r.size.y / segs * i + 0.5,
  109. r.size.x, r.size.y / segs - 1.0);
  110. if (segValue > 0.f) {
  111. nvgFillColor(vg, colorAlpha(nvgRGBf(0.33, 0.33, 0.33), segValue));
  112. nvgFill(vg);
  113. }
  114. if (segAmplitude > 0.f) {
  115. nvgFillColor(vg, colorAlpha(COLOR_GREEN, segAmplitude));
  116. nvgFill(vg);
  117. }
  118. }
  119. }
  120. };
  121. struct VCA_1Widget : ModuleWidget {
  122. VCA_1Widget(VCA_1 *module) : ModuleWidget(module) {
  123. setPanel(SVG::load(assetPlugin(plugin, "res/VCA-1.svg")));
  124. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  125. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  126. addChild(createWidget<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  127. addChild(createWidget<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  128. VCA_1VUKnob *levelParam = createParam<VCA_1VUKnob>(mm2px(Vec(2.62103, 12.31692)), module, VCA_1::LEVEL_PARAM, 0.0, 1.0, 1.0);
  129. levelParam->module = module;
  130. addParam(levelParam);
  131. addParam(createParam<CKSS>(mm2px(Vec(5.24619, 79.9593)), module, VCA_1::EXP_PARAM, 0.0, 1.0, 1.0));
  132. addInput(createPort<PJ301MPort>(mm2px(Vec(3.51261, 60.4008)), PortWidget::INPUT, module, VCA_1::CV_INPUT));
  133. addInput(createPort<PJ301MPort>(mm2px(Vec(3.51398, 97.74977)), PortWidget::INPUT, module, VCA_1::IN_INPUT));
  134. addOutput(createPort<PJ301MPort>(mm2px(Vec(3.51398, 108.64454)), PortWidget::OUTPUT, module, VCA_1::OUT_OUTPUT));
  135. }
  136. };
  137. Model *modelVCA_1 = createModel<VCA_1, VCA_1Widget>("VCA-1");
  138. Model *modelVCA = createModel<VCA, VCAWidget>("VCA");