Skip to content

step_seq: the shared step-sequencer engine, its notebook, and the rhythm-section book chapters#16

Merged
tap merged 7 commits into
mainfrom
claude/sequencer-303-808-design-pxqfxs
Jul 18, 2026
Merged

step_seq: the shared step-sequencer engine, its notebook, and the rhythm-section book chapters#16
tap merged 7 commits into
mainfrom
claude/sequencer-303-808-design-pxqfxs

Conversation

@tap

@tap tap commented Jul 18, 2026

Copy link
Copy Markdown
Owner

The kernel half of the coordinated phase 3 both plans/tap.808.md §6 and plans/tap.303.md §6 deferred to (design of record: plans/tap.seq.md in TapTools-Max, author-approved 2026-07-18), plus the verification notebook and six book chapters.

The engine — include/taptools/step_seq.h

One phase-clocked step engine (taptools::seq) with two thin emitters speaking the shipped voice contracts verbatim:

  • Clocking: the caller feeds a phasor~-style ramp, 0..1 per pattern cycle; the engine derives the step as floor(phase × length) with swing warping the odd-step starts, sample-accurate entries, stateless against phase (jump/scrub/reverse all follow). Rows off one ramp are drift-free by construction; different lengths are polymeter.
  • trigger_row (tap.808.seq~): amplitude-as-accent impulses on the 4–14 V bus mapping — plain 0.01 = the un-accented 4 V base, accented 0.5 = accent knob (VR3) at noon; pulse_ms widening for envelope consumers.
  • note_row (tap.303.seq~): the pitch + gate pair at 1.0/2.0 accent amplitudes, gate duty 0.5 (Open303 AcidPattern::stepLength), and slide as gate-hold across the boundary — chained slides and the across-the-wrap slide included. Slide flag on the target step per the package note convention; the hardware's source-note storage is a documented divergence.
  • 16 pattern slots with store/recall quantized to cycle|step|now; the armed swap re-derives the step against the new grid on the boundary sample.

19 new Catch2 scenarios (suite 129/129 green), including a pairing test that drives the real tb303_voice.h through the wrapper loop and asserts slid steps glide without retriggering.

The notebook — notebooks/step_seq.ipynb

Executed and asserted, house pattern: the shipping kernel driven through the C ABI (extended with taptools_seqtrig/taptools_seqnote and a minimal taptools_kick; TriggerRow/NoteRow/Kick added to taptools_py.py). Six sections: the analytic grid (≤ 1 sample), the swing warp (odd delay = swing/2), the trigger-bus levels, the 303 line signals — including the full-step hold on a slide source step, a case the isolated-step Catch2 scenario didn't exhibit — four bars of acid + kick rendered from the real voices off one ramp (embedded audio), and cycle-quantized recall swapping exactly on the wrap sample.

The book — Part V + Part VI additions

  • Part V — The rhythm section: two field-guide chapters, The acid machine and The drum machine, every number sourced from the executed notebooks or the kernel suite.
  • Part VI — machine chapters: Seventeen, not four (diode_ladder.h), The couplings are the instrument (tb303_voice.h), One network, eight voices (the tr808_* headers), and Time as a function of phase (step_seq.h).

CI / merge order

build and Tap House Style are green on the branch head. Merge this before tap/TapTools-Max#52 — the package PR pins this branch's head as the submodules/taptools submodule.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

claude added 7 commits July 18, 2026 17:46
…p.303.seq~

The plans/tap.seq.md kernel (author-approved 2026-07-18): a phase-clocked
step engine — floor(phase * length) with swing warping the odd-step
boundaries, sample-accurate entries, stateless against phase (jump, scrub,
reverse all follow) — plus the two emitters speaking the shipped voice
contracts verbatim: trigger_row (amplitude-as-accent impulses on the
4-14 V bus mapping; plain 0.01 = the un-accented 4 V base, accented 0.5 =
VR3 at noon) and note_row (pitch + gate at 1.0/2.0 with gate-hold slide;
gate duty 0.5 per Open303's AcidPattern stepLength, the same reference the
voice's calibrated constants came from; slide flag on the target step per
the package note-message convention, divergence from the hardware's
source-note storage documented in the header).

16 pattern slots with store/recall quantized to cycle|step|now (the
armed swap re-derives the step against the new grid on the boundary
sample). No bench entry: the engine is a handful of arithmetic ops per
sample, below the bench harness's noise floor.

19 test scenarios: the analytic grid, polymeter off one ramp, swing
offsets (and swing-0 bit-identity), velocity amplitudes with re-arming
gaps, pulse widening, reverse phase, live length changes, gate duty,
accent levels, gate-hold slide (chained, and across the pattern wrap),
slide-after-rest, quantized recall at the wrap sample, determinism, and
the tb303 voice pairing (slid steps glide with no retrigger). Suite
129/129 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
notebooks/step_seq.ipynb — executed, asserted, house pattern: the shipping
step_seq.h driven through the C ABI. Six sections: the analytic grid
(<=1 sample, + polymeter), the swing warp (odd delay = swing/2), the
trigger-bus levels (0.01/0.5/1.0 on the 4-14 V mapping, pulse_ms), the
303 line signals (duty 0.5, accent 2.0, gate-hold slide — including the
full-step hold on a slide SOURCE step, which the Catch2 suite's isolated
step didn't exhibit), four bars of acid + kick rendered from the real
tb303_voice.h / tr808_kick.h off one phasor ramp (embedded audio), and
cycle-quantized recall swapping exactly at the wrap.

C ABI: taptools_seqtrig / taptools_seqnote (rows) and a minimal
taptools_kick (with the wrapper's signal-edge trigger logic) added to
tools/capi; TriggerRow / NoteRow / Kick ctypes classes in taptools_py.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
Two field-guide chapters for the Roland recreations, in the house voice
and with every number sourced from the executed notebooks or the kernel
suite: acid.md (tap.diode~ / tap.303~ / tap.303.seq~ — the Stinchcombe
0.028 dB match, the never-self-oscillates trait, the measured envmod law
and knob travels, the x1.94 wow, the warm VCA's 5.4%/11.5% envelope-
tracking distortion, slide as gate-hold, the 13-note-ons measurement) and
drums.md (the eight tap.808.* channels — the kick's two distinct attack/
sigh mechanisms and 2.4% calibration, the metal bank's ~20% unit spread
as seed/tolerance, the hardware choke, the per-knob-cell calibration pass
and its honest lesson, and the tap.808.seq~ row with the pinned bus
levels). The machine deep-dives move to Part VI; introduction updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
Four deep dives in the appendix register: diode_ladder.h (the diffusion
chain vs the buffered cascade, the Stinchcombe coefficients as
4*2^(3/4)/10*sqrt(2)/8*2^(1/4), the k=17 Routh-Hurwitz threshold and the
derived never-self-oscillates trait, the bottom-up closed-form ZDF solve
with secant gains, and the WDF no-go); tb303_voice.h (the per-sample
couplings: slide as one coefficient, the C13 wow as three lines, the
measured envmod law with its gimmick, the shaped square, the slope-
normalized warm VCA, and the documented Open303-vs-Devil-Fish
divergence); the tr808 headers (the bridged-T solved on its states so
the kick's per-sample leg modulation costs nothing, the metal bank's
measured 20% spread, the voices as compositions, and the calibration
lesson: schematics get frequencies, recordings get envelopes);
step_seq.h (time as a pure function of phase — the O(1) derivation,
entry-as-inequality, gate-hold look-ahead, and the armed-recall
re-derivation). SUMMARY updated; two fact fixes against the code (four
saturating edges, 3 ms VCA attack).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
@tap
tap merged commit fbcf326 into main Jul 18, 2026
12 checks passed
tap pushed a commit to tap/TapTools-Max that referenced this pull request Jul 18, 2026
The kernel PR (tap/TapTools#16) was rebase-merged, so the branch commits
took new SHAs on main; the pin now points at main's head instead of the
about-to-be-deleted branch history.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN
tap added a commit to tap/TapTools-Max that referenced this pull request Jul 18, 2026
…slices) (#52)

* plans: the coordinated phase-3 sequencer design (tap.seq.md)

The shared step-sequencer plan both family plans deferred to: one kernel
engine (step_seq.h, phase-clocked from phasor~) with two thin per-family
emitters — tap.808.seq~ (trigger row, amplitude-as-accent impulses) and
tap.303.seq~ (pitch + gate line with gate-hold slide). Cross-references
added to plans/tap.808.md §6 and plans/tap.303.md §6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* plans: tap.seq.md — §6 blocking decisions approved by the author

Shape (one engine, two family wrappers), phase-driven clocking with no
clock object in v1, and pattern slots with quantized recall — all three
approved 2026-07-18; the non-blocking recommendations accepted in
principle, to be confirmed at their slices.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.seq: the sequencers — tap.808.seq~ + tap.303.seq~ (slices 0-3)

The coordinated phase 3 of both Roland families, per plans/tap.seq.md
(author-approved 2026-07-18): thin Min wrappers over the kernel's shared
step engine (step_seq.h, pinned at the submodule bump in this commit).

- tap.808.seq~ — one drum row: phasor~ phase in, amplitude-as-accent
  impulses out (plain 0.01 = the 4 V base bus, accented 0.5 = accent
  knob at noon), hits/accents/velocities surfaces, @Pulse widening,
  swing, polymeter via @Length, 16 slots with quantized recall,
  todict/fromdict, and a 1-based step-index UI outlet (coalescing
  audio->scheduler handoff, the tap.sift~ idiom).
- tap.303.seq~ — the acid line: emits the tap.303~ pitch + gate pair
  (1.0/2.0 accent amplitudes, gate duty 0.5 per Open303), slide as
  gate-hold across the boundary, per-step pitch/gate/accent/slide,
  live @transpose, the same slots/dict/step-outlet surface.

Vertical slices: min-api unittests for both (compiled and run against
the mock kernel — also caught two min-api dict API gaps, worked around
via dictionary_appendatoms), maxrefs, help patchers, maxtest starters.
help/tap.808.maxhelp rebuilt on real rows (one phasor~, nine rows — the
metro/counter/sel pattern retired); help/tap.303.seq~.maxhelp supersedes
the tap.303~-pattern.maxpat dry run, which stays as the event-domain
alternative. RELATED cross-links added to tap.303~ and tap.808.kick~.
REVIVAL.md §7 entry + family-section updates; plan statuses closed out.

Runtime validation in Max still pending, as everywhere.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.seq: house-style pass (clang-format + mandatory braces) + kernel pin bump

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.303.seq~: snake_case the todict locals (clang-tidy naming gate)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.seq: kernel pin bump for the step_seq verification notebook + doc notes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.303/tap.808: kernel pin bump for the book chapters + REVIVAL note

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* book: kernel pin bump for the Part VI rhythm-section machine chapters

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

* tap.seq: repin submodules/taptools to the kernel's merged main

The kernel PR (tap/TapTools#16) was rebase-merged, so the branch commits
took new SHAs on main; the pin now points at main's head instead of the
about-to-be-deleted branch history.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZivyxyBdHYd8sVf8AdUbN

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants