Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
transport_edge.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <pulp/signal/detail/modular_sequencing_common.hpp>
6
7#include <cmath>
8#include <cstdint>
9
10namespace pulp::signal {
11
12// ── Transport front end ───────────────────────────────────────────────────
13
32template <typename SampleType = float>
34public:
39 static constexpr double kRefractoryMs = 0.5;
40
42 struct Frame {
43 bool run_high = false;
44 bool reset_edge = false;
45 bool clock_edge = false;
46 };
47
48 void prepare(double sample_rate) {
49 if (std::isfinite(sample_rate) && sample_rate > 0.0) sample_rate_ = sample_rate;
50 update();
51 }
52
57 static constexpr double kMaxRefractoryMs = 1000.0;
58
59 void set_refractory_ms(double ms) {
60 refractory_ms_ = seq_detail::clamp_finite(ms, 0.0, kMaxRefractoryMs);
61 update();
62 }
63
66 void set_thresholds(double high, double low) {
67 run_.set_thresholds(high, low);
68 reset_.set_thresholds(high, low);
69 clock_.set_thresholds(high, low);
70 }
71
72 void reset() {
73 run_.reset();
74 reset_.reset();
75 clock_.reset();
76 refractory_ = 0;
77 }
78
79 static constexpr int latency_samples() { return 0; }
80
82 Frame process(SampleType run, SampleType reset_in, SampleType clock) {
83 Frame f{};
84 run_.process(run);
85 f.run_high = run_.high();
86
87 const bool raw_reset = reset_.process(reset_in);
88 if (refractory_ > 0) --refractory_;
89 if (raw_reset && refractory_ == 0) {
90 f.reset_edge = true;
91 refractory_ = refractory_samples_;
92 }
93
94 f.clock_edge = clock_.process(clock);
95 return f;
96 }
97
100 Frame process(SampleType run, SampleType reset_in) {
101 return process(run, reset_in, SampleType{0});
102 }
103
104private:
105 void update() {
106 refractory_samples_ = static_cast<std::int64_t>(
107 std::llround(units::ms_to_samples(refractory_ms_, sample_rate_)));
108 if (refractory_samples_ < 0) refractory_samples_ = 0;
109 }
110
111 double sample_rate_ = 44100.0;
112 double refractory_ms_ = kRefractoryMs;
113 std::int64_t refractory_samples_ = 0;
114 std::int64_t refractory_ = 0;
115 HystereticTriggerDetectT<SampleType> run_{};
116 HystereticTriggerDetectT<SampleType> reset_{};
117 HystereticTriggerDetectT<SampleType> clock_{};
118};
119
122
123} // namespace pulp::signal
Converts a run level and a reset level into the (run_high, reset_edge) pair the sequencers consume,...
Definition transport_edge.hpp:33
Frame process(SampleType run, SampleType reset_in, SampleType clock)
Decodes run, reset and clock levels for one sample.
Definition transport_edge.hpp:82
Frame process(SampleType run, SampleType reset_in)
Run and reset only, for a caller whose clock edge already arrives as a boolean (a ClockDividerT outpu...
Definition transport_edge.hpp:100
static constexpr int latency_samples()
Definition transport_edge.hpp:79
static constexpr double kRefractoryMs
Definition transport_edge.hpp:39
static constexpr double kMaxRefractoryMs
Definition transport_edge.hpp:57
void set_refractory_ms(double ms)
Definition transport_edge.hpp:59
void prepare(double sample_rate)
Definition transport_edge.hpp:48
void reset()
Definition transport_edge.hpp:72
void set_thresholds(double high, double low)
Sets the hysteresis window used for all three inputs, so a patch running at ±5 V and one running at 0...
Definition transport_edge.hpp:66
T ms_to_samples(T ms, T sample_rate)
Milliseconds → samples at sample_rate Hz.
Definition units.hpp:147
Definition additive_bank.hpp:218
TransportEdgeT< double > TransportEdge64
Definition transport_edge.hpp:121
TransportEdgeT< float > TransportEdge
Definition transport_edge.hpp:120
One sample of transport, decoded.
Definition transport_edge.hpp:42
bool clock_edge
Definition transport_edge.hpp:45
bool run_high
Definition transport_edge.hpp:43
bool reset_edge
Definition transport_edge.hpp:44
The real-unit vocabulary shared by every DSP block in the catalog.