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.

81 lines
2.0KB

  1. #pragma once
  2. #include <assert.h>
  3. /** For Tremolo: lets you smoothly adjust phase and skew
  4. * turns a ramp into a continuously variable dual slope ramp:
  5. * at one extreme it is increasing ramp
  6. * at other extreme it is decreasing
  7. * in between it it triangle
  8. */
  9. class AsymRampShaperParams
  10. {
  11. public:
  12. float k; //when input < k we are in the rising phase
  13. float a1; // in rising phase, f(x) = a1 * x;
  14. float a2;
  15. float b2; // in falling phase, f(x) = a2 * x + b2
  16. float phaseOffset; // between 0 and 1
  17. bool valid()
  18. {
  19. bool ret = true;
  20. ret &= (k > 0 && k < 1);
  21. ret &= (phaseOffset >= 0 && phaseOffset <= 1);
  22. return ret;
  23. }
  24. };
  25. class AsymRampShaper
  26. {
  27. public:
  28. /* skew = -1..1, zero is triangle
  29. * phase = -1..1, zero is no shift
  30. */
  31. static void setup(AsymRampShaperParams& params, float skew, float phase)
  32. {
  33. // first deal with phase
  34. if (phase < 0) phase += 1; // adjust phase into range convenient for us
  35. // (it all wraps around two pi anyway)
  36. assert(phase >= 0 && phase <= 1);
  37. params.phaseOffset = phase;
  38. // now skew
  39. assert(skew > -1 && skew < 1);
  40. params.k = (skew + 1) / (float) 2; // between 0 and 1
  41. params.a1 = float(1.0 / params.k); // as x goes 0..k, f(x) 0..1
  42. params.a2 = float(1.0 / (params.k - 1.0));
  43. params.b2 = -params.a2;
  44. assert(params.valid());
  45. //char buf[512];
  46. //sprintf(buf, "set k=%f a1=%f a2=%f b2=%f\n", params.k, params.a1, params.a2, params.b2);
  47. //DebugUtil::trace(buf);
  48. }
  49. static float proc_1(AsymRampShaperParams& params, float input)
  50. {
  51. assert(params.valid());
  52. input += params.phaseOffset;
  53. if (input > 1) input -= 1;
  54. float ret = 0;
  55. if (input < params.k) {
  56. ret = input * params.a1;
  57. } else {
  58. ret = params.b2 + input * params.a2;
  59. }
  60. assert(ret >= 0 && ret <= 1);
  61. return ret;
  62. }
  63. };