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.

260 lines
9.7KB

  1. #include "dBiz.hpp"
  2. namespace rack_plugin_dBiz {
  3. struct Remix : Module {
  4. enum ParamIds
  5. {
  6. SCAN_PARAM,
  7. CV_SCAN_PARAM,
  8. WIDTH_PARAM,
  9. CV_WIDTH_PARAM,
  10. LEVEL_PARAM,
  11. SLOPE_PARAM,
  12. CV_LEVEL_PARAM,
  13. CH1_LEVEL_PARAM,
  14. CH2_LEVEL_PARAM,
  15. CH3_LEVEL_PARAM,
  16. CH4_LEVEL_PARAM,
  17. CH5_LEVEL_PARAM,
  18. CH6_LEVEL_PARAM,
  19. NUM_PARAMS
  20. };
  21. enum InputIds
  22. {
  23. CH1_INPUT,
  24. CH2_INPUT,
  25. CH3_INPUT,
  26. CH4_INPUT,
  27. CH5_INPUT,
  28. CH6_INPUT,
  29. SLOPE_INPUT,
  30. SCAN_INPUT,
  31. WIDTH_INPUT,
  32. LEVEL_INPUT,
  33. NUM_INPUTS
  34. };
  35. enum OutputIds
  36. {
  37. OUT1_OUTPUT,
  38. OUT2_OUTPUT,
  39. OUT3_OUTPUT,
  40. OUT4_OUTPUT,
  41. OUT5_OUTPUT,
  42. OUT6_OUTPUT,
  43. A_OUTPUT,
  44. B_OUTPUT,
  45. C_OUTPUT,
  46. NUM_OUTPUTS
  47. };
  48. enum LightIds
  49. {
  50. CH1_LIGHT,
  51. CH2_LIGHT,
  52. CH3_LIGHT,
  53. CH4_LIGHT,
  54. CH5_LIGHT,
  55. CH6_LIGHT,
  56. NUM_LIGHTS
  57. };
  58. float ins[6] = {};
  59. float outs[6] = {};
  60. float inMults[6] = {};
  61. float widthTable[7] = {0.0f, 0.285f, 0.285f, 0.2608f, 0.23523f, 0.2125f, 0.193f};
  62. Remix() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  63. void step() override;
  64. int clampInt(const int _in, const int min = 0, const int max = 5)
  65. {
  66. if (_in > max)
  67. return max;
  68. if (_in < min)
  69. return min;
  70. return _in;
  71. }
  72. float triShape(float _in)
  73. {
  74. _in = _in - round(_in);
  75. return std::abs(_in + _in);
  76. }
  77. float LERP(const float _amountOfA, const float _inA, const float _inB)
  78. {
  79. return ((_amountOfA * _inA) + ((1.0f - _amountOfA) * _inB));
  80. }
  81. };
  82. void Remix::step()
  83. {
  84. float allInValue = 0.0f;
  85. for (int i = 0; i < 6; i++)
  86. {
  87. if (!inputs[CH1_INPUT + i].active)
  88. ins[i] = allInValue;
  89. else
  90. ins[i] = inputs[CH1_INPUT + i].value*params[CH1_LEVEL_PARAM+i].value;
  91. }
  92. int stages = 6;
  93. const float invStages = 1.0f / stages;
  94. const float halfStages = stages * 0.5f;
  95. const float remainInvStages = 1.0f - invStages;
  96. float widthControl = params[WIDTH_PARAM].value + inputs[WIDTH_INPUT].value*params[CV_WIDTH_PARAM].value;
  97. widthControl = clamp(widthControl, 0.0f, 5.0f) * 0.2f;
  98. widthControl = widthControl * widthControl * widthTable[stages];
  99. float scanControl = params[SCAN_PARAM].value + inputs[SCAN_INPUT].value*params[CV_SCAN_PARAM].value;
  100. scanControl = clamp(scanControl, 0.0f, 5.0f) * 0.2f;
  101. float slopeControl = params[SLOPE_PARAM].value + inputs[SLOPE_INPUT].value;
  102. slopeControl = clamp(slopeControl, 0.0f, 5.0f) * 0.2f;
  103. float scanFactor1 = LERP(widthControl, halfStages, invStages);
  104. float scanFactor2 = LERP(widthControl, halfStages + remainInvStages, 1.0f);
  105. float scanFinal = LERP(scanControl, scanFactor2, scanFactor1);
  106. float invWidth = 1.0f / (LERP(widthControl, float(stages), invStages + invStages));
  107. float subStage = 0.0f;
  108. for (int i = 0; i < 6; i++)
  109. {
  110. inMults[i] = (scanFinal + subStage) * invWidth;
  111. subStage = subStage - invStages;
  112. }
  113. for (int i = 0; i < 6; i++)
  114. {
  115. inMults[i] = clamp(inMults[i], 0.0f, 1.0f);
  116. inMults[i] = triShape(inMults[i]);
  117. inMults[i] = clamp(inMults[i], 0.0f, 1.0f);
  118. const float shaped = (2.0f - inMults[i]) * inMults[i];
  119. inMults[i] = LERP(slopeControl, shaped, inMults[i]);
  120. }
  121. outputs[A_OUTPUT].value = 0.0f;
  122. outputs[B_OUTPUT].value = 0.0f;
  123. outputs[C_OUTPUT].value = 0.0f;
  124. for (int i = 0; i < 6; i++)
  125. {
  126. outputs[i].value = ins[i] * inMults[i];
  127. lights[CH1_LIGHT + i].setBrightnessSmooth(fmaxf(0.0, inMults[i]));
  128. outputs[B_OUTPUT].value = outputs[B_OUTPUT].value + outputs[i].value;
  129. if (i <= 1)
  130. {
  131. outputs[A_OUTPUT].value = outputs[A_OUTPUT].value + outputs[i].value;
  132. }
  133. else if (i >= 4)
  134. {
  135. outputs[C_OUTPUT].value = outputs[C_OUTPUT].value + outputs[i].value;
  136. }
  137. outputs[A_OUTPUT].value = crossfade(outputs[A_OUTPUT].value * params[LEVEL_PARAM].value, outputs[A_OUTPUT].value * params[LEVEL_PARAM].value*clamp(inputs[LEVEL_INPUT].normalize(10)/10,0.0f,1.0f),params[CV_LEVEL_PARAM].value);
  138. outputs[B_OUTPUT].value = crossfade(outputs[B_OUTPUT].value * params[LEVEL_PARAM].value, outputs[B_OUTPUT].value * params[LEVEL_PARAM].value*clamp(inputs[LEVEL_INPUT].normalize(10)/10,0.0f,1.0f),params[CV_LEVEL_PARAM].value);
  139. outputs[C_OUTPUT].value = crossfade(outputs[C_OUTPUT].value * params[LEVEL_PARAM].value, outputs[C_OUTPUT].value * params[LEVEL_PARAM].value*clamp(inputs[LEVEL_INPUT].normalize(10)/10,0.0f,1.0f),params[CV_LEVEL_PARAM].value);
  140. }
  141. }
  142. struct RemixWidget : ModuleWidget
  143. {
  144. RemixWidget(Remix *module) : ModuleWidget(module)
  145. {
  146. box.size = Vec(14 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
  147. {
  148. SVGPanel *panel = new SVGPanel();
  149. panel->box.size = box.size;
  150. panel->setBackground(SVG::load(assetPlugin(plugin, "res/Remix.svg")));
  151. addChild(panel);
  152. }
  153. int knob = 32;
  154. int jack = 27;
  155. int board =20;
  156. int light = 15;
  157. float mid = (14*15)/2;
  158. float midy= 190;
  159. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, 0)));
  160. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, 0)));
  161. addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  162. addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
  163. addParam(ParamWidget::create<RoundRed>(Vec(board, midy+10), module, Remix::SCAN_PARAM,0.0, 5.0,0.0));
  164. addParam(ParamWidget::create<RoundWhy>(Vec(board, midy+10+knob+10), module, Remix::CV_SCAN_PARAM, 0.0, 1.0, 0.0));
  165. addParam(ParamWidget::create<RoundRed>(Vec(mid-15, midy+10), module, Remix::WIDTH_PARAM, 0.0, 5.0, 0.0));
  166. addParam(ParamWidget::create<RoundWhy>(Vec(mid-15, midy+10+knob+10), module, Remix::CV_WIDTH_PARAM, 0.0, 1.0, 0.0));
  167. addParam(ParamWidget::create<Trimpot>(Vec(mid - 20, 322.5), module, Remix::SLOPE_PARAM, 0.0, 5.0, 0.0));
  168. addInput(Port::create<PJ301MPort>(Vec(mid +10 , 320), Port::INPUT, module, Remix::SLOPE_INPUT));
  169. addParam(ParamWidget::create<RoundRed>(Vec(box.size.x - board - 32.5, midy+10), module, Remix::LEVEL_PARAM, 0.0, 1.0, 0.0));
  170. addParam(ParamWidget::create<RoundWhy>(Vec(box.size.x - board - 32.5, midy+10+knob+10), module, Remix::CV_LEVEL_PARAM, 0.0, 1.0, 0.0));
  171. addOutput(Port::create<PJ301MPort>(Vec(board + 7.5, 20), Port::OUTPUT, module, Remix::A_OUTPUT));
  172. addInput(Port::create<PJ301MPort>(Vec(board+7.5, 320), Port::INPUT, module, Remix::SCAN_INPUT));
  173. addOutput(Port::create<PJ301MPort>(Vec(mid-15 + 7.5, 20), Port::OUTPUT, module, Remix::B_OUTPUT));
  174. addInput(Port::create<PJ301MPort>(Vec(mid-15+ 7.5, 290), Port::INPUT, module, Remix::WIDTH_INPUT));
  175. addOutput(Port::create<PJ301MPort>(Vec(box.size.x-knob-board + 7.5, 20), Port::OUTPUT, module, Remix::C_OUTPUT));
  176. addInput(Port::create<PJ301MPort>(Vec(box.size.x-knob-board + 7.5, 320), Port::INPUT, module, Remix::LEVEL_INPUT));
  177. addInput(Port::create<PJ301MPort>(Vec(board +5+ jack*0, 70), Port::INPUT, module, Remix::CH1_INPUT));
  178. addParam(ParamWidget::create<Trimpot>(Vec(board +10+ jack*0,130),module,Remix::CH1_LEVEL_PARAM,0.0,1.0,0.0));
  179. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board+30+light*0,midy),module,Remix::CH1_LIGHT));
  180. addInput(Port::create<PJ301MPort>(Vec(board + 5 + jack * 1, 70), Port::INPUT, module, Remix::CH2_INPUT));
  181. addParam(ParamWidget::create<Trimpot>(Vec(board + 10 + jack * 1, 130), module, Remix::CH2_LEVEL_PARAM, 0.0, 1.0, 0.0));
  182. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board + 30 + light * 1, midy), module, Remix::CH2_LIGHT));
  183. addInput(Port::create<PJ301MPort>(Vec(board + 5 + jack * 2, 70), Port::INPUT, module, Remix::CH3_INPUT));
  184. addParam(ParamWidget::create<Trimpot>(Vec(board + 10 + jack * 2, 130), module, Remix::CH3_LEVEL_PARAM, 0.0, 1.0, 0.0));
  185. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board + 30 + light * 2, midy), module, Remix::CH3_LIGHT));
  186. addInput(Port::create<PJ301MPort>(Vec(board +10+ jack*3+7.5, 70), Port::INPUT, module, Remix::CH4_INPUT));
  187. addParam(ParamWidget::create<Trimpot>(Vec(board +10+ jack*3+9,130),module,Remix::CH4_LEVEL_PARAM,0.0,1.0,0.0));
  188. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board+60+light*3,midy),module,Remix::CH4_LIGHT));
  189. addInput(Port::create<PJ301MPort>(Vec(board + 10 + jack * 4 + 7.5, 70), Port::INPUT, module, Remix::CH5_INPUT));
  190. addParam(ParamWidget::create<Trimpot>(Vec(board + 10 + jack * 4 + 9, 130), module, Remix::CH5_LEVEL_PARAM, 0.0, 1.0, 0.0));
  191. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board + 60 + light * 4, midy), module, Remix::CH5_LIGHT));
  192. addInput(Port::create<PJ301MPort>(Vec(board + 10 + jack * 5 + 7.5, 70), Port::INPUT, module, Remix::CH6_INPUT));
  193. addParam(ParamWidget::create<Trimpot>(Vec(board + 10 + jack * 5 +9, 130), module, Remix::CH6_LEVEL_PARAM , 0.0, 1.0, 0.0));
  194. addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(board + 60 + light * 5, midy), module, Remix::CH6_LIGHT));
  195. // addChild(GrayModuleLightWidget::create<MediumLight<RedLight>>(Vec(41, 59), module, Remix::CH_LIGHT));
  196. }
  197. };
  198. } // namespace rack_plugin_dBiz
  199. using namespace rack_plugin_dBiz;
  200. RACK_PLUGIN_MODEL_INIT(dBiz, Remix) {
  201. Model *modelRemix = Model::create<Remix, RemixWidget>("dBiz", "Remix", "Remix", MIXER_TAG);
  202. return modelRemix;
  203. }