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.

106 lines
3.4KB

  1. #include "Befaco.hpp"
  2. #include "dsp/functions.hpp"
  3. struct ABC : Module {
  4. enum ParamIds {
  5. B1_LEVEL_PARAM,
  6. C1_LEVEL_PARAM,
  7. B2_LEVEL_PARAM,
  8. C2_LEVEL_PARAM,
  9. NUM_PARAMS
  10. };
  11. enum InputIds {
  12. A1_INPUT,
  13. B1_INPUT,
  14. C1_INPUT,
  15. A2_INPUT,
  16. B2_INPUT,
  17. C2_INPUT,
  18. NUM_INPUTS
  19. };
  20. enum OutputIds {
  21. OUT1_OUTPUT,
  22. OUT2_OUTPUT,
  23. NUM_OUTPUTS
  24. };
  25. enum LightIds {
  26. OUT1_POS_LIGHT,
  27. OUT1_NEG_LIGHT,
  28. OUT2_POS_LIGHT,
  29. OUT2_NEG_LIGHT,
  30. NUM_LIGHTS
  31. };
  32. ABC() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  33. void step() override;
  34. };
  35. static float clip(float x) {
  36. x = clamp(x, -2.0f, 2.0f);
  37. return x / powf(1.0 + powf(x, 24.0), 1/24.0);
  38. }
  39. void ABC::step() {
  40. float a1 = inputs[A1_INPUT].value;
  41. float b1 = inputs[B1_INPUT].normalize(5.0) * 2.0*exponentialBipolar(80.0, params[B1_LEVEL_PARAM].value);
  42. float c1 = inputs[C1_INPUT].normalize(10.0) * exponentialBipolar(80.0, params[C1_LEVEL_PARAM].value);
  43. float out1 = a1 * b1 / 5.0 + c1;
  44. float a2 = inputs[A2_INPUT].value;
  45. float b2 = inputs[B2_INPUT].normalize(5.0) * 2.0*exponentialBipolar(80.0, params[B2_LEVEL_PARAM].value);
  46. float c2 = inputs[C2_INPUT].normalize(10.0) * exponentialBipolar(80.0, params[C2_LEVEL_PARAM].value);
  47. float out2 = a2 * b2 / 5.0 + c2;
  48. // Set outputs
  49. if (outputs[OUT1_OUTPUT].active) {
  50. outputs[OUT1_OUTPUT].value = clip(out1 / 10.0) * 10.0;
  51. }
  52. else {
  53. out2 += out1;
  54. }
  55. if (outputs[OUT2_OUTPUT].active) {
  56. outputs[OUT2_OUTPUT].value = clip(out2 / 10.0) * 10.0;
  57. }
  58. // Lights
  59. lights[OUT1_POS_LIGHT].value = fmaxf(0.0, out1 / 5.0);
  60. lights[OUT1_NEG_LIGHT].value = fmaxf(0.0, -out1 / 5.0);
  61. lights[OUT2_POS_LIGHT].value = fmaxf(0.0, out2 / 5.0);
  62. lights[OUT2_NEG_LIGHT].value = fmaxf(0.0, -out2 / 5.0);
  63. }
  64. struct ABCWidget : ModuleWidget {
  65. ABCWidget(ABC *module) : ModuleWidget(module) {
  66. setPanel(SVG::load(assetPlugin(plugin, "res/ABC.svg")));
  67. addChild(Widget::create<Knurlie>(Vec(15, 0)));
  68. addChild(Widget::create<Knurlie>(Vec(15, 365)));
  69. addParam(ParamWidget::create<Davies1900hRedKnob>(Vec(45, 37), module, ABC::B1_LEVEL_PARAM, -1.0, 1.0, 0.0));
  70. addParam(ParamWidget::create<Davies1900hWhiteKnob>(Vec(45, 107), module, ABC::C1_LEVEL_PARAM, -1.0, 1.0, 0.0));
  71. addParam(ParamWidget::create<Davies1900hRedKnob>(Vec(45, 204), module, ABC::B2_LEVEL_PARAM, -1.0, 1.0, 0.0));
  72. addParam(ParamWidget::create<Davies1900hWhiteKnob>(Vec(45, 274), module, ABC::C2_LEVEL_PARAM, -1.0, 1.0, 0.0));
  73. addInput(Port::create<PJ301MPort>(Vec(7, 28), Port::INPUT, module, ABC::A1_INPUT));
  74. addInput(Port::create<PJ301MPort>(Vec(7, 70), Port::INPUT, module, ABC::B1_INPUT));
  75. addInput(Port::create<PJ301MPort>(Vec(7, 112), Port::INPUT, module, ABC::C1_INPUT));
  76. addOutput(Port::create<PJ301MPort>(Vec(7, 154), Port::OUTPUT, module, ABC::OUT1_OUTPUT));
  77. addInput(Port::create<PJ301MPort>(Vec(7, 195), Port::INPUT, module, ABC::A2_INPUT));
  78. addInput(Port::create<PJ301MPort>(Vec(7, 237), Port::INPUT, module, ABC::B2_INPUT));
  79. addInput(Port::create<PJ301MPort>(Vec(7, 279), Port::INPUT, module, ABC::C2_INPUT));
  80. addOutput(Port::create<PJ301MPort>(Vec(7, 321), Port::OUTPUT, module, ABC::OUT2_OUTPUT));
  81. addChild(ModuleLightWidget::create<MediumLight<GreenRedLight>>(Vec(37, 162), module, ABC::OUT1_POS_LIGHT));
  82. addChild(ModuleLightWidget::create<MediumLight<GreenRedLight>>(Vec(37, 329), module, ABC::OUT2_POS_LIGHT));
  83. }
  84. };
  85. RACK_PLUGIN_MODEL_INIT(Befaco, ABC) {
  86. Model *modelABC = Model::create<ABC, ABCWidget>("Befaco", "ABC", "A*B+C", RING_MODULATOR_TAG, ATTENUATOR_TAG, DUAL_TAG);
  87. return modelABC;
  88. }