Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
forge_sequencing_catalog.hpp
Go to the documentation of this file.
1#pragma once
2
3// Sequencing — bake-layer catalog nodes for the CV/trigger domain.
4//
5// The home for `modular_sequencing.hpp`: the pulse-count stage sequencer, the
6// 2-D Cartesian walk, the Hordijk rungler, the scale quantizer, and the two
7// gate combinators. These are CONTROL nodes — every port carries CV or a gate,
8// not sound — so they belong upstream of the audio nodes, feeding a `vca`, a
9// `filter_cv`, or an oscillator's pitch. The `lofi` catalog's `lfo` node
10// established that an audio port may carry CV; this file is the rest of that
11// layer.
12//
13// ── PORTS carry patch cables; PARAMS carry transport ──────────────────────
14//
15// The one rule that decides every port list here. An input port exists so
16// ANOTHER NODE can drive it — a clock from a divider, a reset from a second
17// sequencer's end-of-cycle, a CV to quantize, a gate to combine. Those are
18// signals with a source inside the graph.
19//
20// `run` and `reset` are TRANSPORT, and in a baked artifact transport comes from
21// the host: a `run` level is a sample-accurate automation lane, which is exactly
22// what a baked param is, and a `reset` is a momentary action a user or an
23// automation lane fires. So `run` is a param on every node here.
24//
25// `reset` is the deliberate exception: it is a param on the two pure PROCESSORS
26// (`quantize_scale`, `prob_gate`), where it only clears a latch, and an input
27// PORT on all three SEQUENCERS, because the classic patch — one sequencer's
28// gate resetting another to build a polymeter — needs a cable, not an
29// automation lane. That asymmetry is the topology talking, not an oversight.
30//
31// ── REALIZATION vs INJECTABLE PARAM, applied per node ─────────────────────
32//
33// The series rule is that anything moving `latency_samples()` must be frozen at
34// registration. **That lever is inert in this module**: every block reports 0
35// unconditionally, a slide is a continuous smoother rather than a delay, and no
36// setting can change it. So the realizations here are forced by the other two
37// reasons, and it is worth being explicit about which:
38//
39// - **Seeds are realizations, always** (series law 2: "seeds never
40// automated/macro-exposed"). A seed is not a knob — it is which performance
41// you are playing. `stage_seq`'s random-direction seed, `rungler`'s seed
42// pattern and `prob_gate`'s seed are all construction arguments. NOTE that
43// the spec's own §10 tables list them as baked-param rows *annotated* "not
44// automatable", which is self-contradictory: a baked-param row IS an
45// automation lane. Resolved in favour of law 2.
46// - **Pattern data is a realization** — per-stage pitch/pulse/mode/slide/skip,
47// and the Cartesian grid. The spec says so directly ("array config, not
48// automatable params"), and the shape is right: a baked artifact plays a
49// composed pattern and automates how it is traversed.
50// - **A genuine topology change is a realization.** Two here:
51// * `rungler`'s REGISTER LENGTH. Not a stylistic call — the DSP reloads
52// the seed pattern when the length changes, because a shift register
53// whose length moves mid-orbit has no meaningful "same state" to keep.
54// As a param it would therefore re-pin the sequence every sample and
55// the node would emit one constant. `dac_bits` by contrast only
56// re-quantizes the same register, so it injects.
57// * `cartesian_walk`'s ACCESS MODE, split into two registered type ids
58// exactly as the diode-bridge member splits on detection topology. In
59// row-major an X wrap carries into Y and INPUT PORT 1 IS NOT READ AT
60// ALL. A node whose port silently stops being a port is a different
61// node, not a mode of one.
62// - **Everything else injects**, including the stepped switches: direction,
63// gate op, quantizer mode, grid dimensions, CV offsets. They are front-panel
64// selectors over an unchanged signal path with invariant latency.
65//
66// ── Levels ────────────────────────────────────────────────────────────────
67//
68// Gates in and out are 0/1, which sits inside the trigger kit's default
69// hysteresis window (rising above 0.5, falling below 0.25) — so any gate output
70// here drives any clock or reset input here with no level negotiation, which is
71// what makes the chaining patches work. Pitch CV is volts on the 1 V/octave
72// standard, so `stage_seq` → `quantize_scale` → an oscillator needs no
73// conversion.
74
77
79
80#include <algorithm>
81#include <array>
82#include <cmath>
83#include <cstddef>
84#include <cstdint>
85
87
90inline constexpr float kGateHigh = 1.0f;
91inline constexpr float kGateLow = 0.0f;
92
95inline bool param_high(float v) { return v >= static_cast<float>(signal::kTriggerHighThreshold); }
96
97// ══════════════════════════════════════════════════════════════════════════
98// Stage sequencer — the pulse-count (M-185 / Metropolis lineage) sequencer
99// ══════════════════════════════════════════════════════════════════════════
100namespace stage_seq {
101
102inline constexpr const char* kTypeId = "sequencing.stage_seq";
103
104// Node-local ids; the framework namespaces per node, so these restart at 1 in
105// every namespace below without colliding.
106inline constexpr state::ParamID kRun = 1; // stepped 0/1 — transport level
107inline constexpr state::ParamID kNumStages = 2; // count
108inline constexpr state::ParamID kDirection = 3; // stepped 0 fwd/1 rev/2 ping/3 rand
109inline constexpr state::ParamID kSlideMs = 4; // ms
110inline constexpr state::ParamID kRepeatDutyPct = 5; // %
111
113
115struct Stage {
116 float pitch_v = 0.0f;
117 int pulse_count = 1;
119 bool slide = false;
120 bool skip = false;
121};
122
123using Pattern = std::array<Stage, static_cast<std::size_t>(Seq::kMaxStages)>;
124
140 Pattern p{};
141 const int degrees[] = {0, 2, 4, 5, 7, 9, 11, 12};
142 for (std::size_t i = 0; i < p.size(); ++i) {
143 const int semitone = degrees[i % 8] + 12 * static_cast<int>(i / 8);
144 p[i].pitch_v = static_cast<float>(semitone) /
145 static_cast<float>(signal::units::kSemitonesPerOctave);
146 p[i].pulse_count = 1;
147 p[i].gate_mode = signal::StageGateMode::repeat;
148 p[i].slide = false;
149 p[i].skip = false;
150 }
151 return p;
152}
153
158
169
173float stage_seq_pitch_bound_v(const Pattern& pattern);
174
178 std::uint32_t seed = Seq::kRandomSeed);
179
181 return {"stage_seq", "Stage Sequencer", "A clocked stage sequencer with direction, slide, and repeated-gate shaping.",
182 {}, {{"default", kTypeId}},
183 {{"run", kRun, "Run", "", "Enables clocked advancement.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"stopped", "Stopped", 0}, {"running", "Running", 1}}},
184 {"num_stages", kNumStages, "Stages", "", "Sets the active pattern length.", ForgeParamKind::continuous, ForgeParamCurve::linear},
185 {"direction", kDirection, "Direction", "", "Selects stage traversal.", ForgeParamKind::stepped, ForgeParamCurve::linear,
186 {{"forward", "Forward", 0}, {"reverse", "Reverse", 1}, {"ping_pong", "Ping Pong", 2}, {"random", "Random", 3}}},
187 {"slide_ms", kSlideMs, "Slide", "ms", "Sets pitch glide between stages.", ForgeParamKind::continuous, ForgeParamCurve::logarithmic},
188 {"repeat_duty_pct", kRepeatDutyPct, "Repeat Duty", "%", "Sets repeated-gate pulse width.", ForgeParamKind::continuous, ForgeParamCurve::linear}}};
189}
190
191} // namespace stage_seq
192
193// ══════════════════════════════════════════════════════════════════════════
194// Cartesian walk — the 2-D (René lineage) sequencer
195// ══════════════════════════════════════════════════════════════════════════
196namespace cartesian {
197
199inline constexpr const char* kTypeId = "sequencing.cartesian_walk";
201inline constexpr const char* kRowMajorTypeId = "sequencing.cartesian_walk_row_major";
202
203inline constexpr state::ParamID kRun = 1; // stepped 0/1
204inline constexpr state::ParamID kGridW = 2; // cells
205inline constexpr state::ParamID kGridH = 3; // cells
206inline constexpr state::ParamID kXOffset = 4; // cells, added to the X counter
207inline constexpr state::ParamID kYOffset = 5; // cells, added to the Y counter
208
210
211using Grid = std::array<float, static_cast<std::size_t>(Walk::kMaxDim * Walk::kMaxDim)>;
212
217 Grid g{};
218 for (std::size_t i = 0; i < g.size(); ++i)
219 g[i] = static_cast<float>(i) / static_cast<float>(signal::units::kSemitonesPerOctave);
220 return g;
221}
222
223struct Instance {
225 signal::TransportEdge transport; // run + reset + the X clock
226 signal::HystereticTriggerDetectT<float> y_detect; // the second clock, same edge definition
227};
228
235
238
243
245 return {"cartesian_walk", "Cartesian Walk", "Walks a two-dimensional value grid from independent clock inputs.",
246 {{"order", "Order", "Selects Cartesian or row-major traversal.",
247 {{"cartesian", "Cartesian", 0}, {"row_major", "Row Major", 1}}}},
248 {{"cartesian", kTypeId, {{"order", "cartesian"}}},
249 {"row_major", kRowMajorTypeId, {{"order", "row_major"}}}},
250 {{"run", kRun, "Run", "", "Enables grid traversal.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"stopped", "Stopped", 0}, {"running", "Running", 1}}},
251 {"grid_width", kGridW, "Grid Width", "cell", "Sets the active grid width.", ForgeParamKind::continuous, ForgeParamCurve::linear},
252 {"grid_height", kGridH, "Grid Height", "cell", "Sets the active grid height.", ForgeParamKind::continuous, ForgeParamCurve::linear},
253 {"x_offset", kXOffset, "X Offset", "cell", "Offsets the horizontal counter.", ForgeParamKind::continuous, ForgeParamCurve::linear},
254 {"y_offset", kYOffset, "Y Offset", "cell", "Offsets the vertical counter.", ForgeParamKind::continuous, ForgeParamCurve::linear}}};
255}
256
257} // namespace cartesian
258
259// ══════════════════════════════════════════════════════════════════════════
260// Rungler — the Hordijk shift-register / DAC chaos source
261// ══════════════════════════════════════════════════════════════════════════
262namespace rungler {
263
264inline constexpr const char* kTypeId = "sequencing.rungler";
265
266inline constexpr state::ParamID kRun = 1; // stepped 0/1
267inline constexpr state::ParamID kDacBits = 2; // bits → 2^D levels
268inline constexpr state::ParamID kFeedbackTap = 3; // register index
269inline constexpr state::ParamID kRangeV = 4; // volts
270inline constexpr state::ParamID kExternalData = 5; // stepped 0/1
271inline constexpr state::ParamID kDataIn = 6; // stepped 0/1 — the steering bit
272
274
279
294
298
307 std::uint32_t seed_pattern = Rung::kSeedPattern);
308
310 return {"rungler", "Rungler", "A clocked shift-register sequencer producing stepped pseudo-random control voltage.",
311 {}, {{"default", kTypeId}},
312 {{"run", kRun, "Run", "", "Enables register advancement.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"stopped", "Stopped", 0}, {"running", "Running", 1}}},
313 {"dac_bits", kDacBits, "DAC Bits", "bit", "Sets the output quantization depth.", ForgeParamKind::continuous, ForgeParamCurve::linear},
314 {"feedback_tap", kFeedbackTap, "Feedback Tap", "", "Selects the register bit fed back into the sequence.", ForgeParamKind::continuous, ForgeParamCurve::linear},
315 {"range_v", kRangeV, "Range", "V", "Sets the output voltage span.", ForgeParamKind::continuous, ForgeParamCurve::linear},
316 {"external_data", kExternalData, "External Data", "", "Selects an external steering bit.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"internal", "Internal", 0}, {"external", "External", 1}}},
317 {"data_in", kDataIn, "Data In", "", "Sets the external steering bit.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"low", "Low", 0}, {"high", "High", 1}}}}};
318}
319
320} // namespace rungler
321
322// ══════════════════════════════════════════════════════════════════════════
323// Quantizer — CV to scale, on the 1 V/octave standard
324// ══════════════════════════════════════════════════════════════════════════
325namespace quantize {
326
327inline constexpr const char* kTypeId = "sequencing.quantize_scale";
328
329inline constexpr state::ParamID kMode = 1; // stepped 0 = EDO-N, 1 = scale mask
330inline constexpr state::ParamID kEdoN = 2; // steps per octave
331inline constexpr state::ParamID kScaleMask = 3; // 12-bit pitch-class mask
332inline constexpr state::ParamID kRootPc = 4; // pitch class
333inline constexpr state::ParamID kHystCents = 5; // cents
334inline constexpr state::ParamID kReset = 6; // stepped 0/1 — clears the latch
335
337
342
367
372
374
376 return {"quantize_scale", "Scale Quantizer", "Quantizes a control voltage to equal divisions or a pitch-class scale.",
377 {}, {{"default", kTypeId}},
378 {{"mode", kMode, "Mode", "", "Selects equal divisions or a pitch-class mask.", ForgeParamKind::stepped, ForgeParamCurve::linear,
379 {{"equal_divisions", "Equal Divisions", 0}, {"scale_mask", "Scale Mask", 1}}},
380 {"edo_n", kEdoN, "Divisions", "", "Sets equal divisions per octave.", ForgeParamKind::continuous, ForgeParamCurve::linear},
381 {"scale_mask", kScaleMask, "Scale Mask", "", "Selects enabled pitch classes as a bit mask.", ForgeParamKind::continuous, ForgeParamCurve::linear},
382 {"root_pc", kRootPc, "Root", "", "Sets the root pitch class.", ForgeParamKind::continuous, ForgeParamCurve::linear},
383 {"hysteresis_cents", kHystCents, "Hysteresis", "cent", "Prevents chatter near quantization boundaries.", ForgeParamKind::continuous, ForgeParamCurve::linear},
384 {"reset", kReset, "Reset", "", "Clears the quantizer latch.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"idle", "Idle", 0}, {"reset", "Reset", 1}}}}};
385}
386
387} // namespace quantize
388
389// ══════════════════════════════════════════════════════════════════════════
390// Gate logic — the Boolean combinator
391// ══════════════════════════════════════════════════════════════════════════
392namespace gate_logic {
393
394inline constexpr const char* kTypeId = "sequencing.gate_logic";
395
396inline constexpr state::ParamID kOp = 1; // stepped 0 AND/1 OR/2 XOR/3 NAND/4 NOR/5 XNOR
397
399
403
410
417
419 return {"gate_logic", "Gate Logic", "Combines two gate signals with selectable Boolean logic.",
420 {}, {{"default", kTypeId}},
421 {{"operation", kOp, "Operation", "", "Selects the Boolean gate operation.", ForgeParamKind::stepped, ForgeParamCurve::linear,
422 {{"and", "AND", 0}, {"or", "OR", 1}, {"xor", "XOR", 2}, {"nand", "NAND", 3}, {"nor", "NOR", 4}, {"xnor", "XNOR", 5}}}}};
423}
424
425} // namespace gate_logic
426
427// ══════════════════════════════════════════════════════════════════════════
428// Probability gate — deterministic chance
429// ══════════════════════════════════════════════════════════════════════════
430namespace prob_gate {
431
432inline constexpr const char* kTypeId = "sequencing.prob_gate";
433
434inline constexpr state::ParamID kProbabilityPct = 1; // %
435inline constexpr state::ParamID kReset = 2; // stepped 0/1 — clears the latch
436
438
443
449
455
457 return {"prob_gate", "Probability Gate", "Passes incoming gates according to a deterministic probability decision.",
458 {}, {{"default", kTypeId}},
459 {{"probability_pct", kProbabilityPct, "Probability", "%", "Sets the chance that each gate passes.", ForgeParamKind::continuous, ForgeParamCurve::linear},
460 {"reset", kReset, "Reset", "", "Clears the gate latch and random sequence.", ForgeParamKind::stepped, ForgeParamCurve::linear, {{"idle", "Idle", 0}, {"reset", "Reset", 1}}}}};
461}
462
463} // namespace prob_gate
464
465} // namespace pulp::host::sequencing
static constexpr int kMaxDim
Definition cartesian_walk.hpp:58
Hysteretic continuous-CV edge detector.
Definition trigger.hpp:39
static constexpr std::uint32_t kProbSeed
Definition probability_gate.hpp:46
static constexpr int kDefaultBits
Definition rungler.hpp:74
static constexpr std::uint32_t kSeedPattern
Definition rungler.hpp:84
static constexpr int kMaxStages
Definition stage_sequencer.hpp:70
static constexpr std::uint32_t kRandomSeed
Definition stage_sequencer.hpp:89
Authored sequence in the signal domain: blocks that remember a pattern, walk it under a clock,...
Definition forge_sequencing_catalog.hpp:196
constexpr state::ParamID kXOffset
Definition forge_sequencing_catalog.hpp:206
constexpr state::ParamID kGridW
Definition forge_sequencing_catalog.hpp:204
float cartesian_walk_cv_bound_v(const Grid &grid)
Largest absolute CV, in volts, the node can emit for a given grid.
constexpr state::ParamID kGridH
Definition forge_sequencing_catalog.hpp:205
Grid default_grid()
The default grid: a rising chromatic ramp in volts, so an unconfigured node walks an audible,...
Definition forge_sequencing_catalog.hpp:216
signal::CartesianWalk Walk
Definition forge_sequencing_catalog.hpp:209
constexpr const char * kTypeId
Independent X and Y — the documented René behaviour, and the default.
Definition forge_sequencing_catalog.hpp:199
float cartesian_walk_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
std::array< float, static_cast< std::size_t >(Walk::kMaxDim *Walk::kMaxDim)> Grid
Definition forge_sequencing_catalog.hpp:211
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:244
constexpr state::ParamID kYOffset
Definition forge_sequencing_catalog.hpp:207
constexpr state::ParamID kRun
Definition forge_sequencing_catalog.hpp:203
constexpr const char * kRowMajorTypeId
Row-major — an X wrap carries into Y, and the Y clock port is not read.
Definition forge_sequencing_catalog.hpp:201
CustomNodeType make_cartesian_walk_node(Grid grid=default_grid(), bool row_major=false)
grid is the composed pattern and row_major is the access topology — the latter picks the registered t...
Definition forge_sequencing_catalog.hpp:392
constexpr state::ParamID kOp
Definition forge_sequencing_catalog.hpp:396
signal::GateLogic Logic
Definition forge_sequencing_catalog.hpp:398
constexpr const char * kTypeId
Definition forge_sequencing_catalog.hpp:394
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:418
CustomNodeType make_gate_logic_node()
Two outputs, because these operations come in complementary pairs and the complement is free: with op...
float gate_logic_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
Definition forge_sequencing_catalog.hpp:430
signal::ProbGate Prob
Definition forge_sequencing_catalog.hpp:437
constexpr const char * kTypeId
Definition forge_sequencing_catalog.hpp:432
constexpr state::ParamID kReset
Definition forge_sequencing_catalog.hpp:435
float prob_gate_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
constexpr state::ParamID kProbabilityPct
Definition forge_sequencing_catalog.hpp:434
CustomNodeType make_prob_gate_node(std::uint32_t seed=Prob::kProbSeed)
seed is registration-time (law 2): changing the seed is how you roll again, and that is a composition...
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:456
Definition forge_sequencing_catalog.hpp:325
CustomNodeType make_quantize_scale_node()
constexpr state::ParamID kMode
Definition forge_sequencing_catalog.hpp:329
constexpr state::ParamID kReset
Definition forge_sequencing_catalog.hpp:334
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:375
constexpr state::ParamID kScaleMask
Definition forge_sequencing_catalog.hpp:331
float quantize_scale_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
signal::QuantizeScale Quant
Definition forge_sequencing_catalog.hpp:336
float quantize_scale_mask_offset_bound_v()
The additive ceiling of scale-mask mode, in volts: the rounding boundary plus the widest hysteresis w...
constexpr state::ParamID kRootPc
Definition forge_sequencing_catalog.hpp:332
constexpr state::ParamID kHystCents
Definition forge_sequencing_catalog.hpp:333
constexpr state::ParamID kEdoN
Definition forge_sequencing_catalog.hpp:330
constexpr const char * kTypeId
Definition forge_sequencing_catalog.hpp:327
Definition forge_sequencing_catalog.hpp:262
constexpr state::ParamID kRun
Definition forge_sequencing_catalog.hpp:266
float rungler_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:309
signal::Rungler Rung
Definition forge_sequencing_catalog.hpp:273
float rungler_output_bound_v()
The largest absolute output the node can emit, in volts: the ceiling of the range_v param,...
constexpr state::ParamID kRangeV
Definition forge_sequencing_catalog.hpp:269
constexpr const char * kTypeId
Definition forge_sequencing_catalog.hpp:264
CustomNodeType make_rungler_node(int reg_bits=Rung::kDefaultBits, std::uint32_t seed_pattern=Rung::kSeedPattern)
reg_bits and seed_pattern are registration-time.
constexpr state::ParamID kExternalData
Definition forge_sequencing_catalog.hpp:270
constexpr state::ParamID kFeedbackTap
Definition forge_sequencing_catalog.hpp:268
constexpr state::ParamID kDacBits
Definition forge_sequencing_catalog.hpp:267
constexpr state::ParamID kDataIn
Definition forge_sequencing_catalog.hpp:271
Definition forge_sequencing_catalog.hpp:100
std::array< Stage, static_cast< std::size_t >(Seq::kMaxStages)> Pattern
Definition forge_sequencing_catalog.hpp:123
Pattern default_pattern()
The default composed pattern: a rising major scale, one clock per stage, one re-articulated gate per ...
Definition forge_sequencing_catalog.hpp:139
signal::StageSeq Seq
Definition forge_sequencing_catalog.hpp:112
constexpr state::ParamID kRepeatDutyPct
Definition forge_sequencing_catalog.hpp:110
constexpr state::ParamID kDirection
Definition forge_sequencing_catalog.hpp:108
CustomNodeType make_stage_seq_node(Pattern pattern=default_pattern(), std::uint32_t seed=Seq::kRandomSeed)
pattern and seed are registration-time: the composed notes and which random performance this artifact...
constexpr state::ParamID kRun
Definition forge_sequencing_catalog.hpp:106
constexpr const char * kTypeId
Definition forge_sequencing_catalog.hpp:102
constexpr state::ParamID kNumStages
Definition forge_sequencing_catalog.hpp:107
float stage_seq_worst_case_gain()
Worst-case linear gain for the Forge registry (series law 8).
float stage_seq_pitch_bound_v(const Pattern &pattern)
Largest absolute pitch, in volts, the node can emit for a given pattern.
ForgeNodeDescriptor descriptor()
Definition forge_sequencing_catalog.hpp:180
constexpr state::ParamID kSlideMs
Definition forge_sequencing_catalog.hpp:109
Definition forge_sequencing_catalog.hpp:86
constexpr float kGateHigh
Level a gate/clock output is driven to.
Definition forge_sequencing_catalog.hpp:90
constexpr float kGateLow
Definition forge_sequencing_catalog.hpp:91
bool param_high(float v)
Reads a 0/1 param as a boolean, at the kit's rising threshold so the convention is the same one the p...
Definition forge_sequencing_catalog.hpp:95
@ stepped
Definition forge_param_descriptor.hpp:25
@ continuous
Definition forge_param_descriptor.hpp:25
@ logarithmic
Definition forge_param_descriptor.hpp:29
@ linear
Definition forge_param_descriptor.hpp:29
constexpr double kSemitonesPerOctave
Semitones per octave, and cents per semitone. Fixed by 12-TET notation.
Definition units.hpp:61
constexpr double kTriggerHighThreshold
Definition trigger.hpp:31
RunglerT< float > Rungler
Definition rungler.hpp:212
StageSeqT< float > StageSeq
Definition stage_sequencer.hpp:420
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
@ single
High on the first pulse only.
Definition stage_sequencer.hpp:28
TransportEdgeT< float > TransportEdge
Definition transport_edge.hpp:120
GateLogicT< float > GateLogic
Definition gate_logic.hpp:106
ProbGateT< float > ProbGate
Definition probability_gate.hpp:93
CartesianWalkT< float > CartesianWalk
Definition cartesian_walk.hpp:192
QuantizeScaleT< float > QuantizeScale
Definition scale_quantizer.hpp:204
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55
Definition custom_node_type.hpp:90
Definition forge_param_descriptor.hpp:127
Definition forge_sequencing_catalog.hpp:223
signal::TransportEdge transport
Definition forge_sequencing_catalog.hpp:225
signal::CartesianWalk walk
Definition forge_sequencing_catalog.hpp:224
signal::HystereticTriggerDetectT< float > y_detect
Definition forge_sequencing_catalog.hpp:226
Definition forge_sequencing_catalog.hpp:400
signal::GateLogic logic
Definition forge_sequencing_catalog.hpp:401
Definition forge_sequencing_catalog.hpp:439
signal::HystereticTriggerDetectT< float > reset_detect
Definition forge_sequencing_catalog.hpp:441
signal::ProbGate gate
Definition forge_sequencing_catalog.hpp:440
Definition forge_sequencing_catalog.hpp:338
signal::QuantizeScale quant
Definition forge_sequencing_catalog.hpp:339
signal::HystereticTriggerDetectT< float > reset_detect
Definition forge_sequencing_catalog.hpp:340
Definition forge_sequencing_catalog.hpp:275
signal::Rungler rungler
Definition forge_sequencing_catalog.hpp:276
signal::TransportEdge transport
Definition forge_sequencing_catalog.hpp:277
Definition forge_sequencing_catalog.hpp:154
signal::TransportEdge transport
Definition forge_sequencing_catalog.hpp:156
signal::StageSeq seq
Definition forge_sequencing_catalog.hpp:155
One stage of the composed pattern — the realization payload.
Definition forge_sequencing_catalog.hpp:115
float pitch_v
Definition forge_sequencing_catalog.hpp:116
bool slide
Definition forge_sequencing_catalog.hpp:119
int pulse_count
Definition forge_sequencing_catalog.hpp:117
bool skip
Definition forge_sequencing_catalog.hpp:120
signal::StageGateMode gate_mode
Definition forge_sequencing_catalog.hpp:118