Step Sequencer
Tier: Core | ComponentType: 21 | Params: 4
16-step discrete modulation source with direction control, glide smoothing, and 15 pattern presets.
Overview
StepSequencer is a patterned modulation source that cycles through a 16-step pattern of semitone values at a configurable rate. Each step holds a float value (typically a semitone offset), and the sequencer advances through the pattern at a rate determined by the Step Length parameter. The output is the current step's value, optionally smoothed by a Glide parameter that creates portamento-like transitions between steps.
Four Direction modes control traversal: Forward steps through the pattern sequentially, Reverse walks backward, PingPong bounces at the boundaries, and Random selects steps uniformly via xorshift32 PRNG. The step count can be reduced from the full 16 to create shorter loops.
15 pattern presets cover common musical use cases:
- Pitch presets (semitone values): OctaveUp, OctaveDown, FifthUp, Triad, PowerChord, Chromatic4, Pentatonic, WholeSteps, ThermaeClassic
- Gate presets (0/1 values): Gate4, Gate3, Euclidean5_8
- Contour presets: Accelerando (ramp), RandomEach (per-step random), RandomHold (held random blocks)
Custom patterns are loaded via setPattern(values, count). In chain mode, the sequencer modulates the input signal like ChaosAttractor — it is a modulation source, not an audio effect.
File Locations
| Path | |
|---|---|
| Header | Sources/FolioDSP/include/FolioDSP/Core/StepSequencer.h |
| Implementation | Sources/FolioDSP/src/Core/StepSequencer.cpp |
| Tests | Tests/FolioDSPTests/StepSequencerTests.swift |
| Bridge | Sources/FolioDSPBridge/src/FolioDSPBridge.mm (StepSequencerBridge) |
Parameters
| Index | Name | Description | Min | Max | Default Min | Default Max | Default | Unit |
|---|---|---|---|---|---|---|---|---|
| 0 | Steps | Number of active steps | 1.0 | 16.0 | 1.0 | 16.0 | 8.0 | |
| 1 | Step Length | Duration of each step | 1.0 | 44100.0 | 50.0 | 2000.0 | 200.0 | ms |
| 2 | Glide | Smoothing between steps (0% = instant, 100% = full step length) | 0.0 | 100.0 | 0.0 | 100.0 | 0.0 | % |
| 3 | Direction | Step direction (0=Forward, 1=Reverse, 2=PingPong, 3=Random) | 0.0 | 3.0 | 0.0 | 3.0 | 0.0 |
Processing Algorithm
The process() function executes once per sample. It has no audio input — it generates a modulation signal.
1. Step Duration
The step length in milliseconds is converted to samples:
2. Step Advance
A per-sample counter increments. When it reaches the step duration, the sequencer advances:
3. Direction Logic
The step index advances according to the selected direction mode:
Forward:
Reverse:
PingPong:
Random:
4. Target Value
The target value is read from the current position in the pattern array:
5. Glide Smoothing
When glide is non-zero, a one-pole lowpass filter smooths the transition between step values. The glide time is a percentage of the step length:
When glide is zero, the output snaps instantly to the target value.
6. Output
The smoothed (or unsmoothed) value is returned as the modulation output.
Core Equations
Snapshot Fields
| Field | Type | Range | Unit | Description |
|---|---|---|---|---|
| Current Step | Float | 0–15 | Index of the currently active step | |
| Value | Float | -24–24 | st | Current output value (smoothed) |
| Step Length | Float | 1–44100 | ms | Current step duration |
| Glide | Float | 0–100 | % | Current glide amount |
| Step Progress | Float | 0–1 | Progress through the current step (counter/S) | |
| Direction | Uint8 | 0–3 | Current direction mode | |
| Num Steps | Float | 1–16 | Number of active steps | |
| Pattern | Float[16] | -24–24 | st | Full 16-step pattern values |
Implementation Notes
- Step counter uses floating-point accumulation (
stepCounter_ += 1.0f) and subtractssamplesPerStepon advance, preserving fractional timing for accurate long-term phase. - Pattern values are stored in a plain C array (
float pattern_[16]), not atomic. Patterns should be set from the main thread only — the audio thread reads directly. This is safe because pattern updates are infrequent and atomic consistency per-element is not required. - xorshift32 PRNG for random direction provides fast, deterministic pseudo-random step selection without system calls.
- Preset patterns are constructed in stack-local arrays inside
setPresetPattern()and then copied viasetPattern(). The random presets (RandomEach, RandomHold) use fixed seeds for reproducibility. - Semitone values in pitch presets use standard semitone intervals: 7 = perfect fifth, 12 = octave, 4 = major third. The ThermaeClassic preset references the Chase Bliss Thermae pitch-shifting delay pedal pattern.
- All parameters use
std::atomic<float>(orstd::atomic<int>) for lock-free thread safety. - Snapshot emission is decimated to ~60 fps (every 735 samples at 44.1 kHz).
Equation Summary
y = pattern[step] + glide smooth