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.

97 lines
2.9KB

  1. #include "Template.hpp"
  2. namespace rack_plugin_PG_Instruments {
  3. #define NUM_PANNERS 8
  4. #define LEFT_MARGIN 20
  5. #define TOP_MARGIN 60
  6. #define SPACING 36
  7. struct PGOctPanner : Module
  8. {
  9. enum ParamIds
  10. {
  11. ENUMS(LEVEL_PARAM, NUM_PANNERS),
  12. ENUMS(PAN_PARAM, NUM_PANNERS),
  13. NUM_PARAMS
  14. };
  15. enum InputIds
  16. {
  17. ENUMS(INPUT, NUM_PANNERS),
  18. NUM_INPUTS
  19. };
  20. enum OutputIds
  21. {
  22. LEFT_OUTPUT,
  23. RIGHT_OUTPUT,
  24. NUM_OUTPUTS
  25. };
  26. PGOctPanner() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, 0)
  27. {
  28. }
  29. void step() override
  30. {
  31. float left = 0.0f;
  32. float right = 0.0f;
  33. for(int i = 0; i < NUM_PANNERS; i++)
  34. {
  35. float input = inputs[INPUT + i].value;
  36. float panning = params[PAN_PARAM + i].value;
  37. float level = params[LEVEL_PARAM + i].value;
  38. float l, r;
  39. pan(input, panning, level, l, r);
  40. left += l;
  41. right += r;
  42. }
  43. outputs[LEFT_OUTPUT].value = left;
  44. outputs[RIGHT_OUTPUT].value = right;
  45. }
  46. void pan(float input, float panning, float level, float &left, float &right)
  47. {
  48. left = cosf(panning * M_PI / 2.0f) * input * level;
  49. right = sinf(panning * M_PI / 2.0f) * input * level;
  50. }
  51. };
  52. struct PGOctPannerWidget : ModuleWidget
  53. {
  54. PGOctPannerWidget(PGOctPanner *module) : ModuleWidget(module)
  55. {
  56. setPanel(SVG::load(assetPlugin(plugin, "res/PGOctPanner.svg")));
  57. addChild(Widget::create<ScrewSilver>(Vec(15, 0)));
  58. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 0)));
  59. addChild(Widget::create<ScrewSilver>(Vec(15, 365)));
  60. addChild(Widget::create<ScrewSilver>(Vec(box.size.x-30, 365)));
  61. for(int i = 0; i < NUM_PANNERS; i++)
  62. {
  63. addInput(Port::create<PJ301MPort>(Vec(LEFT_MARGIN, TOP_MARGIN + SPACING * i), Port::INPUT, module, PGOctPanner::INPUT + i));
  64. addParam(ParamWidget::create<RoundBlackKnob>(Vec(LEFT_MARGIN + 40, TOP_MARGIN + SPACING * i), module, PGOctPanner::PAN_PARAM + i, 0.0f, 1.0, 0.5f));
  65. addParam(ParamWidget::create<RoundBlackKnob>(Vec(LEFT_MARGIN + 80, TOP_MARGIN + SPACING * i), module, PGOctPanner::LEVEL_PARAM + i, 0.0f, 1.0f, 0.7f));
  66. }
  67. addOutput(Port::create<PJ301MPort>(Vec(LEFT_MARGIN + 120, TOP_MARGIN + SPACING), Port::OUTPUT, module, PGOctPanner::LEFT_OUTPUT));
  68. addOutput(Port::create<PJ301MPort>(Vec(LEFT_MARGIN + 120, TOP_MARGIN + SPACING * 2), Port::OUTPUT, module, PGOctPanner::RIGHT_OUTPUT));
  69. }
  70. };
  71. } // namespace rack_plugin_PG_Instruments
  72. using namespace rack_plugin_PG_Instruments;
  73. RACK_PLUGIN_MODEL_INIT(PG_Instruments, PGOctPanner) {
  74. Model *modelPGOctPanner = Model::create<PGOctPanner, PGOctPannerWidget>("PG-Instruments", "PGOctPanner", "PG Oct Panner", ATTENUATOR_TAG);
  75. return modelPGOctPanner;
  76. }