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.

112 lines
2.6KB

  1. #pragma once
  2. #include <rack.hpp>
  3. #include <dsp/common.hpp>
  4. struct BefacoTinyKnobRed : app::SvgKnob {
  5. BefacoTinyKnobRed() {
  6. minAngle = -0.8 * M_PI;
  7. maxAngle = 0.8 * M_PI;
  8. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobRed.svg")));
  9. }
  10. };
  11. struct BefacoTinyKnobWhite : app::SvgKnob {
  12. BefacoTinyKnobWhite() {
  13. minAngle = -0.8 * M_PI;
  14. maxAngle = 0.8 * M_PI;
  15. setSvg(APP->window->loadSvg(asset::system("res/ComponentLibrary/BefacoTinyKnob.svg")));
  16. }
  17. };
  18. struct BefacoTinyKnobGrey : app::SvgKnob {
  19. BefacoTinyKnobGrey() {
  20. minAngle = -0.8 * M_PI;
  21. maxAngle = 0.8 * M_PI;
  22. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoTinyKnobGrey.svg")));
  23. }
  24. };
  25. struct Davies1900hLargeGreyKnob : Davies1900hKnob {
  26. Davies1900hLargeGreyKnob() {
  27. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/Davies1900hLargeGrey.svg")));
  28. }
  29. };
  30. struct BefacoOutputPort : app::SvgPort {
  31. BefacoOutputPort() {
  32. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoOutputPort.svg")));
  33. }
  34. };
  35. struct BefacoInputPort : app::SvgPort {
  36. BefacoInputPort() {
  37. setSvg(APP->window->loadSvg(asset::plugin(pluginInstance, "res/BefacoInputPort.svg")));
  38. }
  39. };
  40. template <typename T>
  41. T sin2pi_pade_05_5_4(T x) {
  42. x -= 0.5f;
  43. return (T(-6.283185307) * x + T(33.19863968) * simd::pow(x, 3) - T(32.44191367) * simd::pow(x, 5))
  44. / (1 + T(1.296008659) * simd::pow(x, 2) + T(0.7028072946) * simd::pow(x, 4));
  45. }
  46. template <typename T>
  47. T tanh_pade(T x) {
  48. T x2 = x * x;
  49. T q = 12.f + x2;
  50. return 12.f * x * q / (36.f * x2 + q * q);
  51. }
  52. struct ADEnvelope {
  53. enum Stage {
  54. STAGE_OFF,
  55. STAGE_ATTACK,
  56. STAGE_DECAY
  57. };
  58. Stage stage = STAGE_OFF;
  59. float env = 0.f;
  60. float attackTime = 0.1, decayTime = 0.1;
  61. float attackShape = 1.0, decayShape = 1.0;
  62. ADEnvelope() { };
  63. void process(const float& sampleTime) {
  64. if (stage == STAGE_OFF) {
  65. env = envLinear = 0.0f;
  66. }
  67. else if (stage == STAGE_ATTACK) {
  68. envLinear += sampleTime / attackTime;
  69. env = std::pow(envLinear, attackShape);
  70. }
  71. else if (stage == STAGE_DECAY) {
  72. envLinear -= sampleTime / decayTime;
  73. env = std::pow(envLinear, decayShape);
  74. }
  75. if (envLinear >= 1.0f) {
  76. stage = STAGE_DECAY;
  77. env = envLinear = 1.0f;
  78. }
  79. else if (envLinear <= 0.0f) {
  80. stage = STAGE_OFF;
  81. env = envLinear = 0.0f;
  82. }
  83. }
  84. void trigger() {
  85. stage = ADEnvelope::STAGE_ATTACK;
  86. // non-linear envelopes won't retrigger at the correct starting point if
  87. // attackShape != decayShape, so we advance the linear envelope
  88. envLinear = std::pow(env, 1.0f / attackShape);
  89. }
  90. private:
  91. float envLinear = 0.f;
  92. };