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.

224 lines
6.0KB

  1. #pragma once
  2. #include <rack.hpp>
  3. using namespace rack;
  4. extern Plugin* pluginInstance;
  5. extern Model* modelEvenVCO;
  6. extern Model* modelRampage;
  7. extern Model* modelABC;
  8. extern Model* modelSpringReverb;
  9. extern Model* modelMixer;
  10. extern Model* modelSlewLimiter;
  11. extern Model* modelDualAtenuverter;
  12. extern Model* modelPercall;
  13. extern Model* modelHexmixVCA;
  14. extern Model* modelChoppingKinky;
  15. extern Model* modelKickall;
  16. extern Model* modelSamplingModulator;
  17. extern Model* modelMorphader;
  18. extern Model* modelADSR;
  19. extern Model* modelSTMix;
  20. extern Model* modelMuxlicer;
  21. extern Model* modelMex;
  22. struct Knurlie : SvgScrew {
  23. Knurlie() {
  24. sw->svg = APP->window->loadSvg(asset::plugin(pluginInstance, "res/Knurlie.svg"));
  25. sw->wrap();
  26. box.size = sw->box.size;
  27. }
  28. };
  29. struct BefacoTinyKnobRed : app::SvgKnob {
  30. BefacoTinyKnobRed() {
  31. minAngle = -0.8 * M_PI;
  32. maxAngle = 0.8 * M_PI;
  33. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobRed.svg")));
  34. }
  35. };
  36. struct BefacoTinyKnobWhite : app::SvgKnob {
  37. BefacoTinyKnobWhite() {
  38. minAngle = -0.8 * M_PI;
  39. maxAngle = 0.8 * M_PI;
  40. setSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/BefacoTinyKnob.svg")));
  41. }
  42. };
  43. struct BefacoTinyKnobDarkGrey : app::SvgKnob {
  44. BefacoTinyKnobDarkGrey() {
  45. minAngle = -0.8 * M_PI;
  46. maxAngle = 0.8 * M_PI;
  47. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobDarkGrey.svg")));
  48. }
  49. };
  50. struct BefacoTinyKnobLightGrey : app::SvgKnob {
  51. BefacoTinyKnobLightGrey() {
  52. minAngle = -0.8 * M_PI;
  53. maxAngle = 0.8 * M_PI;
  54. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobLightGrey.svg")));
  55. }
  56. };
  57. struct BefacoTinyKnobBlack : app::SvgKnob {
  58. BefacoTinyKnobBlack() {
  59. minAngle = -0.8 * M_PI;
  60. maxAngle = 0.8 * M_PI;
  61. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobBlack.svg")));
  62. }
  63. };
  64. struct Davies1900hLargeGreyKnob : Davies1900hKnob {
  65. Davies1900hLargeGreyKnob() {
  66. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hLargeGrey.svg")));
  67. }
  68. };
  69. struct Davies1900hLightGreyKnob : Davies1900hWhiteKnob {
  70. Davies1900hLightGreyKnob() {
  71. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hLightGrey.svg")));
  72. }
  73. };
  74. struct Davies1900hDarkGreyKnob : Davies1900hWhiteKnob {
  75. Davies1900hDarkGreyKnob() {
  76. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hDarkGrey.svg")));
  77. }
  78. };
  79. // library black Davies1900h doesn't work well on black backgrounds
  80. struct Davies1900hDarkBlackAlt : Davies1900hWhiteKnob {
  81. Davies1900hDarkBlackAlt() {
  82. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hBlack.svg")));
  83. }
  84. };
  85. struct BefacoOutputPort : app::SvgPort {
  86. BefacoOutputPort() {
  87. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoOutputPort.svg")));
  88. }
  89. };
  90. struct BefacoInputPort : app::SvgPort {
  91. BefacoInputPort() {
  92. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoInputPort.svg")));
  93. }
  94. };
  95. struct CKSSNarrow : app::SvgSwitch {
  96. CKSSNarrow() {
  97. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SwitchNarrow_0.svg")));
  98. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/SwitchNarrow_1.svg")));
  99. }
  100. };
  101. struct Crossfader : app::SvgSlider {
  102. Crossfader() {
  103. setBackgroundSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CrossfaderBackground.svg")));
  104. setHandleSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/CrossfaderHandle.svg")));
  105. minHandlePos = mm2px(Vec(4.5f, -0.8f));
  106. maxHandlePos = mm2px(Vec(34.5, -0.8f));
  107. horizontal = true;
  108. math::Vec margin = math::Vec(15, 5);
  109. background->box.pos = margin;
  110. box.size = background->box.size.plus(margin.mult(2));
  111. }
  112. };
  113. struct BefacoButton : app::SvgSwitch {
  114. BefacoButton() {
  115. momentary = true;
  116. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoButton_0.svg")));
  117. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoButton_1.svg")));
  118. }
  119. };
  120. struct BefacoSwitchHorizontal : app::SvgSwitch {
  121. BefacoSwitchHorizontal() {
  122. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoSwitchHoriz_0.svg")));
  123. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoSwitchHoriz_1.svg")));
  124. addFrame(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoSwitchHoriz_2.svg")));
  125. }
  126. };
  127. struct BefacoTinyKnobSnap : BefacoTinyKnob {
  128. BefacoTinyKnobSnap() {
  129. snap = true;
  130. minAngle = -0.80 * M_PI;
  131. maxAngle = 0.80 * M_PI;
  132. }
  133. };
  134. template <typename T>
  135. T sin2pi_pade_05_5_4(T x) {
  136. x -= 0.5f;
  137. return (T(-6.283185307) * x + T(33.19863968) * simd::pow(x, 3) - T(32.44191367) * simd::pow(x, 5))
  138. / (1 + T(1.296008659) * simd::pow(x, 2) + T(0.7028072946) * simd::pow(x, 4));
  139. }
  140. template <typename T>
  141. T tanh_pade(T x) {
  142. T x2 = x * x;
  143. T q = 12.f + x2;
  144. return 12.f * x * q / (36.f * x2 + q * q);
  145. }
  146. template <typename T>
  147. T exponentialBipolar80Pade_5_4(T x) {
  148. return (T(0.109568) * x + T(0.281588) * simd::pow(x, 3) + T(0.133841) * simd::pow(x, 5))
  149. / (T(1.) - T(0.630374) * simd::pow(x, 2) + T(0.166271) * simd::pow(x, 4));
  150. }
  151. struct ADEnvelope {
  152. enum Stage {
  153. STAGE_OFF,
  154. STAGE_ATTACK,
  155. STAGE_DECAY
  156. };
  157. Stage stage = STAGE_OFF;
  158. float env = 0.f;
  159. float attackTime = 0.1, decayTime = 0.1;
  160. float attackShape = 1.0, decayShape = 1.0;
  161. ADEnvelope() { };
  162. void process(const float& sampleTime) {
  163. if (stage == STAGE_OFF) {
  164. env = envLinear = 0.0f;
  165. }
  166. else if (stage == STAGE_ATTACK) {
  167. envLinear += sampleTime / attackTime;
  168. env = std::pow(envLinear, attackShape);
  169. }
  170. else if (stage == STAGE_DECAY) {
  171. envLinear -= sampleTime / decayTime;
  172. env = std::pow(envLinear, decayShape);
  173. }
  174. if (envLinear >= 1.0f) {
  175. stage = STAGE_DECAY;
  176. env = envLinear = 1.0f;
  177. }
  178. else if (envLinear <= 0.0f) {
  179. stage = STAGE_OFF;
  180. env = envLinear = 0.0f;
  181. }
  182. }
  183. void trigger() {
  184. stage = ADEnvelope::STAGE_ATTACK;
  185. // non-linear envelopes won't retrigger at the correct starting point if
  186. // attackShape != decayShape, so we advance the linear envelope
  187. envLinear = std::pow(env, 1.0f / attackShape);
  188. }
  189. private:
  190. float envLinear = 0.f;
  191. };