Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
rise_fall_generator.hpp
Go to the documentation of this file.
1#pragma once
2
10
12
13#include <array>
14#include <cmath>
15#include <cstdint>
16
17namespace pulp::signal {
18
19enum class RiseFallStage : std::uint8_t { idle, rising, falling };
20
21template <typename SampleType = float> class RiseFallGeneratorT {
22 public:
24
25 RiseFallGeneratorT() noexcept {
26 rebuild_();
27 }
28
29 [[nodiscard]] BreakpointEnvelopeStatus prepare(double sample_rate) noexcept {
30 return engine_.prepare(sample_rate);
31 }
32
33 [[nodiscard]] bool set_levels(SampleType low, SampleType high) noexcept {
34 if (!std::isfinite(static_cast<double>(low)) || !std::isfinite(static_cast<double>(high)))
35 return false;
36 low_ = low;
37 high_ = high;
38 rebuild_();
39 return true;
40 }
41
42 [[nodiscard]] bool set_times_ms(double rise_ms, double fall_ms) noexcept {
43 if (!valid_time_(rise_ms) || !valid_time_(fall_ms) ||
45 return false;
46 rise_ms_ = rise_ms;
47 fall_ms_ = fall_ms;
48 rebuild_();
49 return true;
50 }
51
52 void set_rise_curve(ModulationCurve curve) noexcept {
53 rise_curve_ = sanitize_modulation_curve(curve);
54 rebuild_();
55 }
56
57 void set_fall_curve(ModulationCurve curve) noexcept {
58 fall_curve_ = sanitize_modulation_curve(curve);
59 rebuild_();
60 }
61
62 void set_looping(bool looping) noexcept {
63 looping_ = looping;
64 apply_loop_();
65 }
66
67 void trigger() noexcept {
68 engine_.trigger();
69 }
70 void reset() noexcept {
71 engine_.reset();
72 }
73 SampleType next() noexcept {
74 return engine_.next();
75 }
76 void process(std::span<SampleType> output) noexcept {
77 engine_.process(output);
78 }
79
80 SampleType current() const noexcept {
81 return engine_.current();
82 }
83 bool active() const noexcept {
84 return engine_.active();
85 }
86 bool looping() const noexcept {
87 return looping_;
88 }
89 double rise_ms() const noexcept {
90 return rise_ms_;
91 }
92 double fall_ms() const noexcept {
93 return fall_ms_;
94 }
95 SampleType low() const noexcept {
96 return low_;
97 }
98 SampleType high() const noexcept {
99 return high_;
100 }
101
102 RiseFallStage stage() const noexcept {
103 if (!engine_.active())
104 return RiseFallStage::idle;
105 return engine_.current_segment() == 0 ? RiseFallStage::rising : RiseFallStage::falling;
106 }
107
108 private:
109 static bool valid_time_(double time_ms) noexcept {
110 return std::isfinite(time_ms) && time_ms >= 0.0 && time_ms <= Engine::kMaxProgramTimeMs;
111 }
112
113 void rebuild_() noexcept {
114 const std::array<typename Engine::Point, 3> points{{
115 {0.0, low_, rise_curve_},
116 {rise_ms_, high_, fall_curve_},
117 {rise_ms_ + fall_ms_, low_, {}},
118 }};
119 (void)engine_.configure(points);
120 apply_loop_();
121 }
122
123 void apply_loop_() noexcept {
124 if (looping_)
125 (void)engine_.set_loop(0, 2, Engine::kLoopForever);
126 else
127 engine_.clear_loop();
128 }
129
130 Engine engine_{};
131 double rise_ms_ = 10.0;
132 double fall_ms_ = 100.0;
133 SampleType low_ = SampleType{0};
134 SampleType high_ = SampleType{1};
135 ModulationCurve rise_curve_{};
136 ModulationCurve fall_curve_{};
137 bool looping_ = false;
138};
139
142
143} // namespace pulp::signal
Fixed-capacity, sample-accurate breakpoint modulation envelope.
Definition breakpoint_envelope.hpp:58
static constexpr double kMaxProgramTimeMs
Definition breakpoint_envelope.hpp:68
static constexpr std::uint32_t kLoopForever
Definition breakpoint_envelope.hpp:69
Definition rise_fall_generator.hpp:21
void reset() noexcept
Definition rise_fall_generator.hpp:70
SampleType current() const noexcept
Definition rise_fall_generator.hpp:80
void set_fall_curve(ModulationCurve curve) noexcept
Definition rise_fall_generator.hpp:57
float low() const noexcept
Definition rise_fall_generator.hpp:95
void set_looping(bool looping) noexcept
Definition rise_fall_generator.hpp:62
bool set_times_ms(double rise_ms, double fall_ms) noexcept
Definition rise_fall_generator.hpp:42
BreakpointEnvelopeStatus prepare(double sample_rate) noexcept
Definition rise_fall_generator.hpp:29
bool looping() const noexcept
Definition rise_fall_generator.hpp:86
BreakpointEnvelopeT< SampleType, 3 > Engine
Definition rise_fall_generator.hpp:23
RiseFallStage stage() const noexcept
Definition rise_fall_generator.hpp:102
void trigger() noexcept
Definition rise_fall_generator.hpp:67
bool set_levels(SampleType low, SampleType high) noexcept
Definition rise_fall_generator.hpp:33
void set_rise_curve(ModulationCurve curve) noexcept
Definition rise_fall_generator.hpp:52
float high() const noexcept
Definition rise_fall_generator.hpp:98
double rise_ms() const noexcept
Definition rise_fall_generator.hpp:89
SampleType next() noexcept
Definition rise_fall_generator.hpp:73
void process(std::span< SampleType > output) noexcept
Definition rise_fall_generator.hpp:76
double fall_ms() const noexcept
Definition rise_fall_generator.hpp:92
bool active() const noexcept
Definition rise_fall_generator.hpp:83
RiseFallGeneratorT() noexcept
Definition rise_fall_generator.hpp:25
Definition additive_bank.hpp:218
RiseFallStage
Definition rise_fall_generator.hpp:19
@ falling
Definition rise_fall_generator.hpp:19
@ rising
Definition rise_fall_generator.hpp:19
@ idle
Definition rise_fall_generator.hpp:19
@ idle
Definition envelope.hpp:56
ModulationCurve sanitize_modulation_curve(ModulationCurve curve) noexcept
Definition modulation_curve.hpp:42
RiseFallGeneratorT< float > RiseFallGenerator
Definition rise_fall_generator.hpp:140
BreakpointEnvelopeStatus
Definition breakpoint_envelope.hpp:35
RiseFallGeneratorT< double > RiseFallGenerator64
Definition rise_fall_generator.hpp:141
Curve strength is dimensionless and legal in [0, 1].
Definition modulation_curve.hpp:37