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.

91 lines
1.8KB

  1. #pragma once
  2. #include "util/math.hpp"
  3. namespace rack {
  4. /** Turns HIGH when value reaches 1.f, turns LOW when value reaches 0.f. */
  5. struct SchmittTrigger {
  6. // UNKNOWN is used to represent a stable state when the previous state is not yet set
  7. enum State {
  8. UNKNOWN,
  9. LOW,
  10. HIGH
  11. };
  12. State state;
  13. SchmittTrigger() {
  14. reset();
  15. }
  16. void reset() {
  17. state = UNKNOWN;
  18. }
  19. /** Updates the state of the Schmitt Trigger given a value.
  20. Returns true if triggered, i.e. the value increases from 0 to 1.
  21. If different trigger thresholds are needed, use
  22. process(rescale(in, low, high, 0.f, 1.f))
  23. for example.
  24. */
  25. bool process(float in) {
  26. switch (state) {
  27. case LOW:
  28. if (in >= 1.f) {
  29. state = HIGH;
  30. return true;
  31. }
  32. break;
  33. case HIGH:
  34. if (in <= 0.f) {
  35. state = LOW;
  36. }
  37. break;
  38. default:
  39. if (in >= 1.f) {
  40. state = HIGH;
  41. }
  42. else if (in <= 0.f) {
  43. state = LOW;
  44. }
  45. break;
  46. }
  47. return false;
  48. }
  49. bool isHigh() {
  50. return state == HIGH;
  51. }
  52. };
  53. /** When triggered, holds a high value for a specified time before going low again */
  54. struct PulseGenerator {
  55. float time;
  56. float triggerDuration;
  57. PulseGenerator() {
  58. reset();
  59. }
  60. /** Immediately resets the state to LOW */
  61. void reset() {
  62. time = 0.f;
  63. triggerDuration = 0.f;
  64. }
  65. /** Advances the state by `deltaTime`. Returns whether the pulse is in the HIGH state. */
  66. bool process(float deltaTime) {
  67. time += deltaTime;
  68. return time < triggerDuration;
  69. }
  70. /** Begins a trigger with the given `triggerDuration`. */
  71. void trigger(float triggerDuration) {
  72. // Keep the previous triggerDuration if the existing pulse would be held longer than the currently requested one.
  73. if (time + triggerDuration >= this->triggerDuration) {
  74. time = 0.f;
  75. this->triggerDuration = triggerDuration;
  76. }
  77. }
  78. };
  79. } // namespace rack