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.

130 lines
3.0KB

  1. #include "VU.hpp"
  2. void VU::onSampleRateChange() {
  3. _lRms.setSampleRate(engineGetSampleRate());
  4. _rRms.setSampleRate(engineGetSampleRate());
  5. }
  6. void VU::step() {
  7. float left = 0.0f;
  8. float right = 0.0f;
  9. if (inputs[L_INPUT].active) {
  10. left = inputs[L_INPUT].value;
  11. }
  12. if (inputs[R_INPUT].active) {
  13. right = inputs[R_INPUT].value;
  14. }
  15. else {
  16. right = left;
  17. }
  18. _lLevel = _lRms.next(left) / 5.0f;
  19. _rLevel = _rRms.next(right) / 5.0f;
  20. outputs[L_OUTPUT].value = left;
  21. outputs[R_OUTPUT].value = right;
  22. }
  23. struct VUDisplay : OpaqueWidget {
  24. struct Level {
  25. float db;
  26. NVGcolor color;
  27. Level(float db, const NVGcolor& color) : db(db), color(color) {}
  28. };
  29. const NVGcolor bgColor = nvgRGBA(0xaa, 0xaa, 0xaa, 0xff);
  30. VU* _module;
  31. std::vector<Level> _levels;
  32. VUDisplay(VU* module) : _module(module) {
  33. for (int i = 1; i <= 36; ++i) {
  34. float db = 12.0f - i*2.0f;
  35. _levels.push_back(Level(db, decibelsToColor(db)));
  36. }
  37. }
  38. void draw(NVGcontext* vg) override {
  39. float lDb = _module->_lLevel;
  40. if (lDb > 0.0f) {
  41. lDb = amplitudeToDecibels(lDb);
  42. }
  43. else {
  44. lDb = -100.0f;
  45. }
  46. float rDb = _module->_rLevel;
  47. if (rDb > 0.0f) {
  48. rDb = amplitudeToDecibels(rDb);
  49. }
  50. else {
  51. rDb = -100.0f;
  52. }
  53. nvgSave(vg);
  54. for (int i = 0; i < 180; i += 5) {
  55. const Level& l = _levels.at(i / 5);
  56. nvgBeginPath(vg);
  57. nvgRect(vg, 3, i + 1, 5, 4);
  58. nvgFillColor(vg, bgColor);
  59. nvgFill(vg);
  60. if (lDb > l.db) {
  61. nvgFillColor(vg, l.color);
  62. nvgFill(vg);
  63. }
  64. nvgBeginPath(vg);
  65. nvgRect(vg, 10, i + 1, 5, 4);
  66. nvgFillColor(vg, bgColor);
  67. nvgFill(vg);
  68. if (rDb > l.db) {
  69. nvgFillColor(vg, l.color);
  70. nvgFill(vg);
  71. }
  72. }
  73. nvgRestore(vg);
  74. }
  75. };
  76. struct VUWidget : ModuleWidget {
  77. static constexpr int hp = 3;
  78. VUWidget(VU* module) : ModuleWidget(module) {
  79. box.size = Vec(RACK_GRID_WIDTH * hp, RACK_GRID_HEIGHT);
  80. {
  81. SVGPanel *panel = new SVGPanel();
  82. panel->box.size = box.size;
  83. panel->setBackground(SVG::load(assetPlugin(plugin, "res/VU.svg")));
  84. addChild(panel);
  85. }
  86. {
  87. auto display = new VUDisplay(module);
  88. display->box.pos = Vec(13.5, 16.5);
  89. display->box.size = Vec(18, 180);
  90. addChild(display);
  91. }
  92. addChild(Widget::create<ScrewSilver>(Vec(0, 0)));
  93. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 15, 365)));
  94. // generated by svg_widgets.rb
  95. auto lInputPosition = Vec(10.5, 203.0);
  96. auto rInputPosition = Vec(10.5, 238.0);
  97. auto lOutputPosition = Vec(10.5, 276.0);
  98. auto rOutputPosition = Vec(10.5, 311.0);
  99. // end generated by svg_widgets.rb
  100. addInput(Port::create<Port24>(lInputPosition, Port::INPUT, module, VU::L_INPUT));
  101. addInput(Port::create<Port24>(rInputPosition, Port::INPUT, module, VU::R_INPUT));
  102. addOutput(Port::create<Port24>(lOutputPosition, Port::OUTPUT, module, VU::L_OUTPUT));
  103. addOutput(Port::create<Port24>(rOutputPosition, Port::OUTPUT, module, VU::R_OUTPUT));
  104. }
  105. };
  106. RACK_PLUGIN_MODEL_INIT(Bogaudio, VU) {
  107. Model *modelVU = createModel<VU, VUWidget>("Bogaudio-VU", "VU", "stereo signal meter", VISUAL_TAG, DUAL_TAG);
  108. return modelVU;
  109. }