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.

181 lines
4.6KB

  1. #include <sstream>
  2. #include "Squinky.hpp"
  3. #include "WidgetComposite.h"
  4. #include "LFN.h"
  5. /**
  6. */
  7. struct LFNModule : Module
  8. {
  9. public:
  10. LFNModule();
  11. /**
  12. *
  13. * Overrides of Module functions
  14. */
  15. void step() override;
  16. void onSampleRateChange() override;
  17. LFN<WidgetComposite> lfn;
  18. private:
  19. };
  20. void LFNModule::onSampleRateChange()
  21. {
  22. // engineGetSampleTime();
  23. // float rate = Module::engineGetSampleRate();
  24. // float rate = 1.0f / engineGetSampleTime(); // TODO: what's up with this? this used to work!
  25. lfn.setSampleTime(engineGetSampleTime());
  26. }
  27. LFNModule::LFNModule()
  28. : Module(lfn.NUM_PARAMS,
  29. lfn.NUM_INPUTS,
  30. lfn.NUM_OUTPUTS,
  31. lfn.NUM_LIGHTS),
  32. lfn(this)
  33. {
  34. onSampleRateChange();
  35. lfn.init();
  36. }
  37. void LFNModule::step()
  38. {
  39. lfn.step();
  40. }
  41. ////////////////////
  42. // module widget
  43. ////////////////////
  44. class LFNLabelUpdater
  45. {
  46. public:
  47. void update(struct LFNWidget& widget);
  48. void makeLabel(struct LFNWidget& widget, int index, float x, float y);
  49. private:
  50. LFNModule * module;
  51. Label* labels[5] = {0,0,0,0,0};
  52. float baseFrequency = -1;
  53. };
  54. struct LFNWidget : ModuleWidget
  55. {
  56. LFNWidget(LFNModule *);
  57. Label* addLabel(const Vec& v, const char* str, const NVGcolor& color = COLOR_BLACK)
  58. {
  59. Label* label = new Label();
  60. label->box.pos = v;
  61. label->text = str;
  62. label->color = color;
  63. addChild(label);
  64. return label;
  65. }
  66. void draw(NVGcontext *vg) override
  67. {
  68. updater.update(*this);
  69. module.lfn.pollForChangeOnUIThread();
  70. ModuleWidget::draw(vg);
  71. }
  72. void addStage(int i);
  73. LFNLabelUpdater updater;
  74. LFNModule& module;
  75. };
  76. static const float knobX = 42;
  77. static const float knobY = 100;
  78. static const float knobDy = 50;
  79. static const float inputY = knobY + 16;
  80. static const float inputX = 6;
  81. static const float labelX = 2;
  82. void LFNWidget::addStage(int index)
  83. {
  84. const float gmin = -5;
  85. const float gmax = 5;
  86. const float gdef = 0;
  87. addParam(ParamWidget::create<Rogan1PSBlue>(
  88. Vec(knobX, knobY + index * knobDy),
  89. &module, module.lfn.EQ0_PARAM + index, gmin, gmax, gdef));
  90. updater.makeLabel((*this), index, labelX, knobY - 2 + index * knobDy);
  91. addInput(Port::create<PJ301MPort>(Vec(inputX, inputY + index * knobDy),
  92. Port::INPUT, &module, module.lfn.EQ0_INPUT + index));
  93. }
  94. /**
  95. * Widget constructor will describe my implementation structure and
  96. * provide meta-data.
  97. * This is not shared by all modules in the DLL, just one
  98. */
  99. LFNWidget::LFNWidget(LFNModule *module) : ModuleWidget(module), module(*module)
  100. {
  101. box.size = Vec(6 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  102. {
  103. SVGPanel *panel = new SVGPanel();
  104. panel->box.size = box.size;
  105. panel->setBackground(SVG::load(assetPlugin(plugin, "res/lfn_panel.svg")));
  106. addChild(panel);
  107. }
  108. addOutput(Port::create<PJ301MPort>(
  109. Vec(59, inputY - knobDy -1), Port::OUTPUT, module, module->lfn.OUTPUT));
  110. addLabel(
  111. Vec(54 , inputY - knobDy - 18), "out", COLOR_WHITE);
  112. addParam(ParamWidget::create<Rogan1PSBlue>(
  113. Vec(10, knobY - 1 * knobDy), module, module->lfn.FREQ_RANGE_PARAM, -5, 5, 0));
  114. // addLabel(Vec(59, knobY - 1 * knobDy), "R");
  115. for (int i = 0; i < 5; ++i) {
  116. addStage(i);
  117. }
  118. // screws
  119. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  120. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  121. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  122. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  123. }
  124. void LFNLabelUpdater::makeLabel(struct LFNWidget& widget, int index, float x, float y)
  125. {
  126. labels[index] = widget.addLabel(Vec(x, y), "Hz");
  127. }
  128. void LFNLabelUpdater::update(struct LFNWidget& widget)
  129. {
  130. float baseFreq = widget.module.lfn.getBaseFrequency();
  131. if (baseFreq != baseFrequency) {
  132. baseFrequency = baseFreq;
  133. for (int i = 0; i < 5; ++i) {
  134. std::stringstream str;
  135. str.precision(1);
  136. str.setf(std::ios::fixed, std::ios::floatfield);
  137. str << baseFreq;
  138. labels[i]->text = str.str();
  139. baseFreq *= 2.0f;
  140. }
  141. }
  142. }
  143. RACK_PLUGIN_MODEL_INIT(squinkylabs_plug1, LFN) {
  144. Model *modelLFNModule = Model::create<LFNModule,
  145. LFNWidget>("Squinky Labs",
  146. "squinkylabs-lfn",
  147. "LFN: Random Voltages", NOISE_TAG, RANDOM_TAG, LFO_TAG);
  148. return modelLFNModule;
  149. }