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.

218 lines
6.5KB

  1. #include "Southpole.hpp"
  2. #include "dsp/digital.hpp"
  3. namespace rack_plugin_Southpole {
  4. #define NUMAUX 2
  5. struct Aux : Module {
  6. enum ParamIds {
  7. SEND1_PARAM,
  8. SEND2_PARAM,
  9. RETURN1_PARAM,
  10. RETURN2_PARAM,
  11. FEEDBACK1_PARAM,
  12. FEEDBACK2_PARAM,
  13. MUTE_PARAM,
  14. BYPASS_PARAM,
  15. NUM_PARAMS
  16. };
  17. enum InputIds {
  18. INL_INPUT,
  19. INR_INPUT,
  20. RETURN1L_INPUT,
  21. RETURN2L_INPUT,
  22. RETURN1R_INPUT,
  23. RETURN2R_INPUT,
  24. NUM_INPUTS
  25. };
  26. enum OutputIds {
  27. OUTL_OUTPUT,
  28. OUTR_OUTPUT,
  29. SEND1L_OUTPUT,
  30. SEND2L_OUTPUT,
  31. SEND1R_OUTPUT,
  32. SEND2R_OUTPUT,
  33. NUM_OUTPUTS
  34. };
  35. enum LightIds {
  36. MUTE_LIGHT,
  37. BYPASS_LIGHT,
  38. NUM_LIGHTS
  39. };
  40. SchmittTrigger muteTrigger;
  41. SchmittTrigger bypassTrigger;
  42. bool mute;
  43. bool bypass;
  44. Aux() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
  45. mute = 0;
  46. bypass = 0;
  47. }
  48. void step() override;
  49. json_t *toJson()override {
  50. json_t *rootJm = json_object();
  51. json_t *statesJ = json_array();
  52. json_t *muteJ = json_boolean(mute);
  53. json_array_append_new(statesJ, muteJ);
  54. json_t *bypassJ = json_boolean(bypass);
  55. json_array_append_new(statesJ, bypassJ);
  56. json_object_set_new(rootJm, "states", statesJ);
  57. return rootJm;
  58. }
  59. void fromJson(json_t *rootJm)override {
  60. json_t *statesJ = json_object_get(rootJm, "states");
  61. json_t *muteJ = json_array_get(statesJ, 0);
  62. json_t *bypassJ = json_array_get(statesJ, 1);
  63. mute = !!json_boolean_value(muteJ);
  64. bypass = !!json_boolean_value(bypassJ);
  65. }
  66. };
  67. void Aux::step() {
  68. if (muteTrigger.process(params[MUTE_PARAM].value)){
  69. mute = !mute;
  70. }
  71. lights[MUTE_LIGHT].value = mute ? 1.0 : 0.0;
  72. if (bypassTrigger.process(params[BYPASS_PARAM].value)){
  73. bypass = !bypass;
  74. }
  75. lights[BYPASS_LIGHT].value = bypass ? 1.0 : 0.0;
  76. float inl = 0.;
  77. float inr = 0.;
  78. if (!mute) {
  79. inl = inputs[INL_INPUT].normalize(0.);
  80. inr = inputs[INR_INPUT].normalize(inl);
  81. }
  82. float outl = inl;
  83. float outr = inr;
  84. float sl1 = params[SEND1_PARAM].value * inl;
  85. float sr1 = params[SEND1_PARAM].value * inr;
  86. float sl2 = params[SEND2_PARAM].value * inl;
  87. float sr2 = params[SEND2_PARAM].value * inr;
  88. float rl1 = inputs[RETURN1L_INPUT].normalize(0.);
  89. float rr1 = inputs[RETURN1R_INPUT].normalize(rl1);
  90. float rl2 = inputs[RETURN2L_INPUT].normalize(0.);
  91. float rr2 = inputs[RETURN2R_INPUT].normalize(rl2);
  92. float fb1 = params[FEEDBACK1_PARAM].value;
  93. float fb2 = params[FEEDBACK2_PARAM].value;
  94. if (fb1 >= 0.) {
  95. sl1 += fb1 * rl2;
  96. sr1 += fb1 * rr2;
  97. } else {
  98. sr1 -= fb1 * rl2;
  99. sl1 -= fb1 * rr2;
  100. }
  101. if (fb2 >= 0.) {
  102. sl2 += fb2 * rl1;
  103. sr2 += fb2 * rr1;
  104. } else {
  105. sr2 -= fb2 * rl1;
  106. sl2 -= fb2 * rr1;
  107. }
  108. outputs[SEND1L_OUTPUT].value = sl1;
  109. outputs[SEND1R_OUTPUT].value = sr1;
  110. outputs[SEND2L_OUTPUT].value = sl2;
  111. outputs[SEND2R_OUTPUT].value = sr2;
  112. if (!bypass) {
  113. outl += params[RETURN1_PARAM].value * rl1;
  114. outr += params[RETURN1_PARAM].value * rr1;
  115. outl += params[RETURN2_PARAM].value * rl2;
  116. outr += params[RETURN2_PARAM].value * rr2;
  117. }
  118. outputs[OUTL_OUTPUT].value = outl;
  119. outputs[OUTR_OUTPUT].value = outr;
  120. }
  121. struct AuxWidget : ModuleWidget {
  122. AuxWidget(Aux *module) : ModuleWidget(module) {
  123. box.size = Vec(15*4, 380);
  124. {
  125. SVGPanel *panel = new SVGPanel();
  126. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Aux_.svg")));
  127. panel->box.size = box.size;
  128. addChild(panel);
  129. }
  130. const float y1 = 42;
  131. const float yh = 26;
  132. const float x1 = 4.;
  133. //const float x2 = 20.;
  134. const float x3 = 36.;
  135. addOutput(Port::create<sp_Port>(Vec(x1, y1+ 0*yh), Port::OUTPUT, module, Aux::SEND1L_OUTPUT));
  136. addOutput(Port::create<sp_Port>(Vec(x1, y1+ 1*yh), Port::OUTPUT, module, Aux::SEND1R_OUTPUT));
  137. addInput(Port::create<sp_Port>( Vec(x3, y1+ 0*yh), Port::INPUT, module, Aux::RETURN1L_INPUT));
  138. addInput(Port::create<sp_Port>( Vec(x3, y1+ 1*yh), Port::INPUT, module, Aux::RETURN1R_INPUT));
  139. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+2*yh), module, Aux::SEND1_PARAM, 0.0, 1.0, 0.5));
  140. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x3, y1+2*yh), module, Aux::RETURN1_PARAM, 0.0, 1.0, 0.5));
  141. addParam(ParamWidget::create<sp_Trimpot>(Vec(x1, y1+3.5*yh), module, Aux::FEEDBACK1_PARAM, -1.0, 1.0, 0.0));
  142. addParam(ParamWidget::create<sp_Trimpot>(Vec(x3, y1+3.5*yh), module, Aux::FEEDBACK2_PARAM, -1.0, 1.0, 0.0));
  143. addOutput(Port::create<sp_Port>(Vec(x1, y1+ 5.5*yh), Port::OUTPUT, module, Aux::SEND2L_OUTPUT));
  144. addOutput(Port::create<sp_Port>(Vec(x1, y1+ 6.5*yh), Port::OUTPUT, module, Aux::SEND2R_OUTPUT));
  145. addInput(Port::create<sp_Port>( Vec(x3, y1+ 5.5*yh), Port::INPUT, module, Aux::RETURN2L_INPUT));
  146. addInput(Port::create<sp_Port>( Vec(x3, y1+ 6.5*yh), Port::INPUT, module, Aux::RETURN2R_INPUT));
  147. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x1, y1+7.5*yh), module, Aux::SEND2_PARAM, 0.0, 1.0, 0.5));
  148. addParam(ParamWidget::create<sp_SmallBlackKnob>(Vec(x3, y1+7.5*yh), module, Aux::RETURN2_PARAM, 0.0, 1.0, 0.5));
  149. addParam(ParamWidget::create<LEDButton> (Vec(x1, y1+ 9*yh ), module, Aux::MUTE_PARAM, 0.0, 1.0, 0.0));
  150. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(Vec(x1+2.2, y1+ 9*yh+2), module, Aux::MUTE_LIGHT));
  151. addParam(ParamWidget::create<LEDButton> (Vec(x3, y1+ 9*yh ), module, Aux::BYPASS_PARAM, 0.0, 1.0, 0.0));
  152. addChild(ModuleLightWidget::create<LargeLight<RedLight>>(Vec(x3+2.2, y1+ 9*yh+2), module, Aux::BYPASS_LIGHT));
  153. addInput(Port::create<sp_Port>( Vec(x1, y1+10*yh), Port::INPUT, module, Aux::INL_INPUT));
  154. addInput(Port::create<sp_Port>( Vec(x1, y1+11*yh), Port::INPUT, module, Aux::INR_INPUT));
  155. addOutput(Port::create<sp_Port>(Vec(x3, y1+10*yh), Port::OUTPUT, module, Aux::OUTL_OUTPUT));
  156. addOutput(Port::create<sp_Port>(Vec(x3, y1+11*yh), Port::OUTPUT, module, Aux::OUTR_OUTPUT));
  157. }
  158. };
  159. } // namespace rack_plugin_Southpole
  160. using namespace rack_plugin_Southpole;
  161. RACK_PLUGIN_MODEL_INIT(Southpole, Aux) {
  162. Model *modelAux = Model::create<Aux,AuxWidget>( "Southpole", "Aux", "Aux - effect loop", AMPLIFIER_TAG, MIXER_TAG);
  163. return modelAux;
  164. }