3#include <pulp/signal/detail/modular_sequencing_common.hpp>
65template <
typename SampleType =
float>
113 slew_.set_time_ms(0.0);
118 sample_rate_ = sample_rate > 0.0 ? sample_rate : sample_rate_;
120 slew_.prepare(sample_rate_);
127 if (stage_ >= num_stages_) stage_ = 0;
135 if (in_range(s) && std::isfinite(
static_cast<double>(volts))) pitch_v_[s] = volts;
137 SampleType
stage_pitch(
int s)
const {
return in_range(s) ? pitch_v_[s] : SampleType{0}; }
145 if (in_range(s)) gate_mode_[s] = m;
152 if (in_range(s)) slide_[s] = on;
154 bool stage_slide(
int s)
const {
return in_range(s) && slide_[s]; }
157 if (in_range(s)) skip_[s] = on;
159 bool stage_skip(
int s)
const {
return in_range(s) && skip_[s]; }
170 void set_repeat_duty(
double duty) { repeat_duty_ = seq_detail::clamp_finite(duty, 0.0, 1.0); }
173 void set_seed(std::uint32_t seed) { rng_.set_seed(seed); }
186 stage_ = first_playable_from(0);
199 target_pitch_ = SampleType{0};
208 bool gate()
const {
return gate_; }
209 SampleType
pitch_v()
const {
return slew_.value(); }
210 int stage()
const {
return stage_; }
212 int pulse()
const {
return pulse_; }
217 Frame
process(
bool run_high,
bool reset_edge,
bool clock_edge) {
222 return Frame{slew_.value(),
false};
233 const double measured =
static_cast<double>(since_clock_);
234 period_ = (measured > 0.0 && measured <= max_period_samples_) ? measured : 0.0;
241 gate_ = compute_gate();
242 const SampleType pitch = slew_.process(target_pitch_);
243 return Frame{pitch, gate_};
247 static bool in_range(
int s) {
return s >= 0 && s <
kMaxStages; }
251 int first_playable_from(
int from)
const {
252 const int n = num_stages_;
253 for (
int i = 0;
i < n; ++
i) {
254 const int s = (from +
i) % n;
255 if (!skip_[s])
return s;
260 bool has_playable()
const {
261 for (
int i = 0;
i < num_stages_; ++
i)
262 if (!skip_[
i])
return true;
270 slew_.set_time_ms(slide_[stage_] ? slide_ms_ : 0.0);
271 target_pitch_ = pitch_v_[stage_];
278 if (!has_playable())
return;
288 stage_ = first_playable_from(stage_);
295 if (pulse_ < pulse_count_[stage_])
return;
303 const int n = num_stages_;
306 switch (direction_) {
308 for (
int i = 0;
i <
n; ++
i) {
309 stage_ = (stage_ + 1) % n;
310 if (!skip_[stage_])
return;
314 for (
int i = 0;
i <
n; ++
i) {
315 stage_ = (stage_ - 1 +
n) % n;
316 if (!skip_[stage_])
return;
322 for (
int i = 0;
i < 2 *
n; ++
i) {
324 if (!skip_[stage_])
return;
333 void pingpong_step() {
334 const int n = num_stages_;
336 if (stage_ >= n - 1) {
353 const int n = num_stages_;
362 static_cast<int>(rng_.next_uint() %
static_cast<std::uint32_t
>(n));
363 if (!skip_[candidate]) {
368 stage_ = first_playable_from((stage_ + 1) % n);
371 bool compute_gate()
const {
372 if (!started_)
return false;
373 switch (gate_mode_[stage_]) {
387 if (period_ <= 0.0)
return true;
388 return static_cast<double>(since_clock_) < repeat_duty_ * period_;
394 double sample_rate_ = 44100.0;
395 double max_period_samples_ = 44100.0 * 4.0;
409 bool ascending_ =
true;
410 bool started_ =
false;
412 std::int64_t since_clock_ = 0;
413 double period_ = 0.0;
414 bool have_clock_ =
false;
415 SampleType target_pitch_ = SampleType{0};
416 ConstantTimeSlewLimiterT<SampleType> slew_{};
The pulse-count stage sequencer.
Definition stage_sequencer.hpp:66
static constexpr int latency_samples()
Definition stage_sequencer.hpp:206
Frame process(bool run_high, bool reset_edge, bool clock_edge)
Advances one sample. See the header's order-of-operations rule.
Definition stage_sequencer.hpp:217
static constexpr int kMaxPulseCount
Definition stage_sequencer.hpp:75
void set_stage_pulse_count(int s, int count)
Definition stage_sequencer.hpp:139
bool gate() const
Definition stage_sequencer.hpp:208
static constexpr double kSlideMs
Definition stage_sequencer.hpp:84
static constexpr double kMaxSlideMs
Definition stage_sequencer.hpp:165
static constexpr double kMaxPeriodMs
Definition stage_sequencer.hpp:103
SampleType pitch_v() const
Definition stage_sequencer.hpp:209
SampleType stage_pitch(int s) const
Definition stage_sequencer.hpp:137
static constexpr int kMaxStages
Definition stage_sequencer.hpp:70
int stage_pulse_count(int s) const
Definition stage_sequencer.hpp:142
bool stage_skip(int s) const
Definition stage_sequencer.hpp:159
static constexpr int kRandomDrawAttempts
Definition stage_sequencer.hpp:97
StageGateMode stage_gate_mode(int s) const
Definition stage_sequencer.hpp:147
void set_stage_slide(int s, bool on)
Definition stage_sequencer.hpp:151
static constexpr int kDefaultStages
Definition stage_sequencer.hpp:71
double repeat_duty() const
Definition stage_sequencer.hpp:171
void set_stage_gate_mode(int s, StageGateMode m)
Definition stage_sequencer.hpp:144
void reset()
The lifecycle verb (verb 1): everything apply_reset_edge() does, plus held outputs to zero,...
Definition stage_sequencer.hpp:196
void set_slide_ms(double ms)
Definition stage_sequencer.hpp:167
static constexpr double kRepeatDuty
Definition stage_sequencer.hpp:79
bool stage_slide(int s) const
Definition stage_sequencer.hpp:154
void prepare(double sample_rate)
Definition stage_sequencer.hpp:117
StageSeqT()
Definition stage_sequencer.hpp:111
SeqDirection direction() const
Definition stage_sequencer.hpp:132
void set_direction(SeqDirection d)
Definition stage_sequencer.hpp:131
double slide_ms() const
Definition stage_sequencer.hpp:168
bool started() const
True once the first clock after a reset has landed.
Definition stage_sequencer.hpp:214
void set_num_stages(int n)
Definition stage_sequencer.hpp:125
void apply_reset_edge()
The modular reset jack (verb 2): position to the top of the pattern, gate low, pitch CV held,...
Definition stage_sequencer.hpp:185
static constexpr int kMinPulseCount
Definition stage_sequencer.hpp:74
static constexpr std::uint32_t kRandomSeed
Definition stage_sequencer.hpp:89
void set_seed(std::uint32_t seed)
Definition stage_sequencer.hpp:173
void set_repeat_duty(double duty)
Definition stage_sequencer.hpp:170
int num_stages() const
Definition stage_sequencer.hpp:129
void set_stage_pitch(int s, SampleType volts)
Definition stage_sequencer.hpp:134
void set_stage_skip(int s, bool on)
Definition stage_sequencer.hpp:156
int stage() const
Definition stage_sequencer.hpp:210
int pulse() const
0-based pulse index inside the current stage.
Definition stage_sequencer.hpp:212
T ms_to_samples(T ms, T sample_rate)
Milliseconds → samples at sample_rate Hz.
Definition units.hpp:147
Definition additive_bank.hpp:218
SeqDirection
How a StageSeqT walks from one stage to the next.
Definition stage_sequencer.hpp:17
@ reverse
(s − 1 + N) mod N.
Definition stage_sequencer.hpp:19
@ random
Seeded draw, rejection-sampled past skipped stages.
Definition stage_sequencer.hpp:21
@ forward
(s + 1) mod N.
Definition stage_sequencer.hpp:18
@ pingpong
Reflects at both ends without repeating them; period 2N − 2.
Definition stage_sequencer.hpp:20
@ linear
Definition mod_tools.hpp:106
StageSeqT< float > StageSeq
Definition stage_sequencer.hpp:420
@ hold
Definition envelope.hpp:59
StageGateMode
What the gate does across the clock pulses a stage occupies.
Definition stage_sequencer.hpp:25
@ repeat
A separate gate per pulse, at repeat_duty.
Definition stage_sequencer.hpp:27
@ rest
Low for the whole stage — silence with duration.
Definition stage_sequencer.hpp:29
@ hold
High for the whole stage.
Definition stage_sequencer.hpp:26
@ single
High on the first pulse only.
Definition stage_sequencer.hpp:28
StageSeqT< double > StageSeq64
Definition stage_sequencer.hpp:421
@ i
Definition formant_filter_bank.hpp:20
@ reverse
Rise to a peak, then cut.
Definition nonlin_ambience_design.hpp:246
@ n
Definition input_events.hpp:40
@ candidate
Definition waveform_editor_primitives.hpp:193
Deterministic randomness for modulation: a counter-free PRNG, a Gaussian draw, a stateless purpose-ke...
Compatibility include for the canonical modulation-toolkit slew limiter and sample-and-hold implement...
One sample of sequencer output.
Definition stage_sequencer.hpp:106
bool gate
Definition stage_sequencer.hpp:108
SampleType pitch_v
Definition stage_sequencer.hpp:107
The real-unit vocabulary shared by every DSP block in the catalog.