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.

160 lines
2.6KB

  1. #pragma once
  2. #include <dsp/common.hpp>
  3. namespace rack {
  4. namespace dsp {
  5. /** Detects when a boolean changes from false to true */
  6. struct BooleanTrigger {
  7. bool state = true;
  8. void reset() {
  9. state = true;
  10. }
  11. bool process(bool state) {
  12. bool triggered = (state && !this->state);
  13. this->state = state;
  14. return triggered;
  15. }
  16. };
  17. /** Turns HIGH when value reaches 1.f, turns LOW when value reaches 0.f. */
  18. struct SchmittTrigger {
  19. bool state = true;
  20. void reset() {
  21. state = true;
  22. }
  23. /** Updates the state of the Schmitt Trigger given a value.
  24. Returns true if triggered, i.e. the value increases from 0 to 1.
  25. If different trigger thresholds are needed, use
  26. process(rescale(in, low, high, 0.f, 1.f))
  27. for example.
  28. */
  29. bool process(float in) {
  30. if (state) {
  31. // HIGH to LOW
  32. if (in <= 0.f) {
  33. state = false;
  34. }
  35. }
  36. else {
  37. // LOW to HIGH
  38. if (in >= 1.f) {
  39. state = true;
  40. return true;
  41. }
  42. }
  43. return false;
  44. }
  45. bool isHigh() {
  46. return state;
  47. }
  48. };
  49. template <typename T>
  50. struct TSchmittTrigger {
  51. T state;
  52. TSchmittTrigger() {
  53. reset();
  54. }
  55. void reset() {
  56. state = T::mask();
  57. }
  58. T process(T in) {
  59. T on = (in >= 1.f);
  60. T off = (in <= 0.f);
  61. T triggered = ~state & on;
  62. state = on | (state & ~off);
  63. return triggered;
  64. }
  65. };
  66. /** When triggered, holds a high value for a specified time before going low again */
  67. struct PulseGenerator {
  68. float remaining = 0.f;
  69. /** Immediately disables the pulse */
  70. void reset() {
  71. remaining = 0.f;
  72. }
  73. /** Advances the state by `deltaTime`. Returns whether the pulse is in the HIGH state. */
  74. bool process(float deltaTime) {
  75. if (remaining > 0.f) {
  76. remaining -= deltaTime;
  77. return true;
  78. }
  79. return false;
  80. }
  81. /** Begins a trigger with the given `duration`. */
  82. void trigger(float duration = 1e-3f) {
  83. // Keep the previous pulse if the existing pulse will be held longer than the currently requested one.
  84. if (duration > remaining) {
  85. remaining = duration;
  86. }
  87. }
  88. };
  89. struct Timer {
  90. float time = 0.f;
  91. void reset() {
  92. time = 0.f;
  93. }
  94. /** Returns the time since last reset or initialization. */
  95. float process(float deltaTime) {
  96. time += deltaTime;
  97. return time;
  98. }
  99. };
  100. struct ClockDivider {
  101. uint32_t clock = 0;
  102. uint32_t division = 1;
  103. void reset() {
  104. clock = 0;
  105. }
  106. void setDivision(uint32_t division) {
  107. this->division = division;
  108. }
  109. uint32_t getDivision() {
  110. return division;
  111. }
  112. uint32_t getClock() {
  113. return clock;
  114. }
  115. /** Returns true when the clock reaches `division` and resets. */
  116. bool process() {
  117. clock++;
  118. if (clock >= division) {
  119. clock = 0;
  120. return true;
  121. }
  122. return false;
  123. }
  124. };
  125. } // namespace dsp
  126. } // namespace rack