Skip to content

New module: Bar LED 0.1.0-experimental: tempo LED green on the pattern's 1 (Octatrack) - #1173

Open
nathangroth wants to merge 32 commits into
repeat98:mainfrom
nathangroth:module/bar-led
Open

nathangroth wants to merge 32 commits into
repeat98:mainfrom
nathangroth:module/bar-led

Conversation

@nathangroth

@nathangroth nathangroth commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Bar LED 0.1.0-experimental (Octatrack)

The tempo LED flashes green on the pattern's 1 while the sequencer plays; every other beat stays stock red, and stopped it is stock. A visual downbeat for players who route the cue outputs through external effects and can't use the click.

  • Hook: one call. Stock's beat flash, jsr set_led at 0x40056f24 (set_led(38, 3), the tempo LED's red half), goes through bl_flash, which passes LED 39 (green) on the first flash after the master step (0x800065b4) wraps. No clock or count of its own.
  • Cost: at most 11 ColdFire instructions once per beat; 64 bytes of code and state; USB package 196 bytes. Under a 62 s MIDI flood in ot_emu the longest frame interrupt and idle time are identical to the same build without it (evidence/performance.json, perf:audit passes).
  • Compatibility: no other module or the base patches the site; uiClaims empty; no conflicts.
  • Attribution: original work by @nathangroth, MIT.

The owner's review

  • Pause and continue — fixed. As the review read it: any flash while the transport word wasn't 1 rearmed the last step, and the word is 2 while paused (STEM_REC.md), so continuing flashed green wherever the pattern was. unit.s now rearms only on 0 (stopped and rewound); a pause keeps the step it paused on. verify.py gained a run that pauses and continues twice: the old source fails it (green at steps 7 and 14 after continuing), this one passes.
  • Pattern change while playing: not yet run; it needs the unit. The tester will run pause/continue and a pattern change on the committed package de7f9cae… next; the result goes into TESTING.md and the qualification record before this leaves draft. Until then the hardware record is the earlier run on bce3b4d6…, which predates the fix and says so.
  • Screenshots: access.noUiReason ("It draws nothing: the tempo LED turns green on the pattern's 1."), both screenshot lists empty, the qualification tutorial now the README's three steps.

Publication

  • Moved to sdk/octabam/modules/bar-led/; catalogue entry; qualification record; changelog in src/community/module-changelogs/bar-led.json.
  • Packages built in modwerk-source-tools and imported; every USB package checks identical. The committed USB package de7f9cae… differs from a local test build only in the name bytes.
  • Tape Echo and Euclid standalone recipes re-pinned; Analog BD proofs re-exported natively (all 212 identical, only the tree hash moves).
  • module:verify: 80 native module-owned images match, 90 matching refusals, 0 mismatches, of 170 selections; pairs recorded.

Checks

npm run pr:ready: every module, catalogue, pair, board, typecheck, build and SDK check passes. Locally test fails only on discord.js (not installed) and on 5 s timeouts on an external disk; those tests pass with a longer timeout. lint trips over leftover .claude/worktrees/ checkouts.

What the guides lacked or got wrong

For a Docs: pull request (a module PR stays free of guide edits), beside the four listed on #1224:

  1. OCTATRACK_HARDWARE_TRAPS: through a USB 2.0 hub every package upload was refused at EP0 after all retries, while small requests worked; straight into the Mac it worked.
  2. OCTATRACK_DRIVING: on a flashed beta base state, stats, mem and key steps answer "build it with --dev"; status, do inventory, missing, try/remove and do selftest work.
  3. The sequencing guide could name the transport word's three states (0 rewound, 1 playing, 2 paused); a hook that treats "not 1" as stopped gets pause wrong, as this one did.
  • I read the guide for its category (system, sequencing), and TESTING.md lists what I did not test.
  • Source and media are mine, MIT. Nothing comes from Elektron firmware.
  • Hardware results are what a named person saw on the named build; emulator results are labelled as such. No screenshots: access.noUiReason.

Hardware results, 5 November 2026

The committed package (de7f9cae) kept beside Slow LFO on @nathangroth's MKI (flashed beta base 9680e9ac): SELF TEST passed, 2/2 intact, longest frame 371 us. The tester reports green on the pattern's 1 on external MIDI clock, through tempo changes while playing (internal and external clock), at pattern scales 3/4, 3/2 and 2X, on the master length in per-track mode, after STOP/PLAY, and after continuing from a pause. Still not tested: a pattern change while playing, MKII (now a Known issue: line in the release notes), the site's install dialog. Details in TESTING.md.

module:verify passes again (78 match, 96 refusals, 0 mismatches). It also asks to commit a chooser-metadata.json row, but the beta base is built from that file, so a row makes the committed base stale (octatrack-base.test.ts). Recent ColdFire-only modules carry no row, so this PR doesn't either; the row belongs with the next base rebuild. That instruction in module-verify.mjs could say so: a small follow-up, not part of this release.

pr:ready: everything passes except push-runtime and change-scope, which time out on this external disk and pass alone with longer timeouts.

Known limit: a pattern no longer than one beat (documentation only)

The README's Compatibility and limitations now says a pattern of 1, 2 or 4 steps at 1x (or 8 at 2x) is green only on the first flash after PLAY, then red: every beat flash sees step 0, so the step never drops. 4 steps at 1x was seen under the port in review of octabam's copy (sambanks/octabam#1053); 8 at 2x is inferred. No code change. Locally module:doctor is green; npm run check passed except ESLint, which failed only on extra worktrees under .claude/worktrees/ (more than one tsconfig root), which CI doesn't have.

🤖 Generated with Claude Code

nathangroth and others added 5 commits November 2, 2026 15:44
…e 1 of every bar

While the sequencer plays, the beat-flash call (set_led(38, 3) at
0x40056f24) lights LED 39, the tempo LED's green half, on every fourth
beat counted from PLAY. Other beats and the stopped state stay stock.
ot_emu on stock 1.40C: 39 on beats 1, 5, 9 and 38 on the rest
(verify.py). Not yet run on a unit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The beat flash now turns green on the first flash after the master step
(0x800065b4) wraps, and on the first flash after PLAY, instead of every
fourth beat counted from PLAY. It follows the pattern length and scale
and drops the bar counter. ot_emu: green on step 0 at 12, 16 and 20
steps (verify.py); 14 steps greens the first flash after the wrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@repeat98

repeat98 commented Nov 3, 2026

Copy link
Copy Markdown
Owner

Thanks, this is neat: one stock call, no clock of its own, and nothing in the base covers the tempo LED, so its own declared site is the right place for it. The guide gaps you found are in #1174.

The step left is the USB run. Your unit needs a Modwerk base for that: the USB card on the site's Octatrack page walks you through installing it. Then install the package through the site, do Keep, a power cycle and Undo, then remove it, and record the results in TESTING.md. With that, move it from sdk/drafts/bar-led/ to sdk/octabam/modules/bar-led/ in this pull request, mark it ready, and run npm run pr:ready until it says Ready.


Generated by Claude Code

nathangroth and others added 4 commits November 4, 2026 05:29
Trial and Undo, Keep, power cycle, removal and SELF TEST on the flashed
beta base 9680e9ac, package bce3b4d6, with the tester's LED reports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nathangroth

Copy link
Copy Markdown
Contributor Author

@repeat98 The USB run is done on my MKI, on the flashed beta base 9680e9ac… with package bce3b4d6…: a timed trial that undid itself, Keep, a power cycle (still installed, green on the 1), removal, and SELF TEST passed with it kept. It's all in TESTING.md and the description.

One question before I move it out of drafts. Publication needs tests.qualification.documentation.screenshots, but Bar LED draws nothing on the LCD. MODULE_UI_CAPTURES says to keep screenshots empty "until the owner sets a rule". How would you like it handled: a photo of the LED, a noUiReason-style exception, or something else? Once that's settled, the move, catalogue entry, packages, native comparison and qualification record follow in this PR.


Generated by Claude Code

@repeat98

repeat98 commented Nov 5, 2026

Copy link
Copy Markdown
Owner

Thanks, the USB run is everything I asked for.

On screenshots: you're right that a picture of an LCD page wouldn't show anything Bar LED does, and a photo of a green LED can't pass the black-and-white check. Butter Fingers has the same problem. So I've widened access.noUiReason in #1228: a module that changes stock behaviour and draws nothing of its own (no controls, no effectId, no screen: claim in uiClaims) may give it in place of screenshots, whatever its location. Bar LED already fits. The access steps and the README tutorial of at least three steps stay required; the screenshots don't. I'll tag you when it's on main. Then merge main, add access.noUiReason (one sentence naming what it changes instead, say "It draws nothing: the tempo LED turns green on the pattern's 1."), keep access.screenshots and tests.qualification.documentation.screenshots empty, and replace the template's tutorial steps in the qualification record with three real ones that match the README's tutorial.

Until then you can do the move to sdk/octabam/modules/bar-led/, the catalogue entry, packages, native comparison and qualification record. pr:ready will only say Ready once that rule is in.

One thing to check on the unit while you're there. As I read unit.s, any flash while the transport word isn't 1 resets bl_last to -1. So after a pause, the first flash on continue would be green wherever the pattern is. Could you try pause and continue, and a pattern change while playing (the sequencing guide asks for the pattern change)? Then either handle it or add a line to the limitations.


Generated by Claude Code

…pauses and continues

The owner's review: any flash while the transport word was not 1 rearmed the
last step, and the word is 2 while paused, so continuing flashed green
wherever the pattern was. Only 0 (stopped and rewound) rearms now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@repeat98

repeat98 commented Nov 5, 2026

Copy link
Copy Markdown
Owner

The rule is on main now (#1228), so you can go ahead with access.noUiReason as described above.


Generated by Claude Code

nathangroth and others added 7 commits November 5, 2026 04:47
…ason in place of screenshots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…age, Tape Echo and Euclid recipes re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d pair checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…identical), tree hash re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tock-effects image)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nathangroth nathangroth changed the title New module: Bar LED 0.1.0-experimental (draft): tempo LED green on the pattern's 1 (Octatrack) New module: Bar LED 0.1.0-experimental: tempo LED green on the pattern's 1 (Octatrack) Nov 5, 2026
nathangroth and others added 5 commits November 5, 2026 05:21
…e/bar-led

# Conflicts:
#	scripts/build-module-packages.py
#	scripts/module-release-scope.test.mjs
#	scripts/module-source.test.mjs
#	sdk/catalog.json
#	sdk/machines/octatrack/module-adapters/standalone-recipes.json
#	src/catalog/module-documents.json
#	src/engine/assets/analog-bd-composition-proofs.json
#	src/engine/assets/bootstrap-package.json
#	src/engine/assets/coldfire-packages.json
#	src/engine/assets/descriptor-recipes.json
#	src/engine/assets/dsp-packages.json
#	src/engine/assets/menu-recipes.json
#	src/engine/assets/module-build.json
#	src/engine/assets/platform-writes.json
#	src/engine/assets/requested-packages.json
#	src/engine/assets/resident-dsp.json
#	src/engine/assets/rom-packages.json
#	src/engine/assets/usb-audio-packages.json
#	src/engine/assets/utility-packages.json
…er 0.1.0); Tape Echo and Euclid recipes re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refusals, 0 mismatches)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dentical), tree hash re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e/bar-led

# Conflicts:
#	sdk/machines/octatrack/module-adapters/standalone-recipes.json
#	src/engine/assets/analog-bd-composition-proofs.json
#	src/engine/assets/bootstrap-package.json
#	src/engine/assets/coldfire-packages.json
#	src/engine/assets/descriptor-recipes.json
#	src/engine/assets/dsp-packages.json
#	src/engine/assets/menu-recipes.json
#	src/engine/assets/module-build.json
#	src/engine/assets/platform-writes.json
#	src/engine/assets/requested-packages.json
#	src/engine/assets/resident-dsp.json
#	src/engine/assets/rom-packages.json
#	src/engine/assets/usb-audio-packages.json
#	src/engine/assets/utility-packages.json
nathangroth and others added 3 commits November 5, 2026 05:57
…le Quantizer 0.1.4); Tape Echo and Euclid recipes re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dentical), tree hash re-pinned

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@repeat98

repeat98 commented Nov 5, 2026

Copy link
Copy Markdown
Owner

Thanks, the pause fix is the right one, and the gate that pauses and continues twice is just what I wanted next to it. Everything else from my last comment is in: the move, access.noUiReason, both screenshot lists empty, the README's tutorial in the qualification record, the packages, the native comparison and the performance record.

Three things are left before I can merge:

  1. The unit run on the package this PR ships, de7f9cae…. The hardware record is still the run on bce3b4d6… from before the fix, but qualification.sourceSha256 already names the new source, so the record pairs today's source with the old image. You already plan this. Pause and continue, and a pattern change while playing, are still open from my last comment, so please run those too. Then point tests.qualification.imageSha256, hardware.sourceRevision, hardware.imageSha256, testedOn, evidenceRevision and the summaries at that run, and drop the "predates the pause fix" lines.
  2. Only claim what's been seen. The README overview, the presentation overview and highlights, and the changelog's third line say it follows pattern changes, scale and external MIDI clock, but none of those has been run yet. Either try them in the same session (a pattern scale other than 1x and external clock take a minute each) or cut those lines back to what you've seen.
  3. A stale line. TESTING.md's Performance section still says there is no evidence/performance.json yet. There is one now.

Then mark it ready. Slow LFO (#1224) and this PR touch the same generated and package files, so whichever merges second needs one more merge of main and a package rebuild. I'll merge whichever is finished first and let you know.


Generated by Claude Code

nathangroth and others added 6 commits November 5, 2026 07:30
The README, presentation and changelog no longer say it follows pattern
scale, pattern changes, tempo changes or external MIDI clock: none has
been run. Those go on the not-yet-tested list. TESTING.md's Performance
section now points at evidence/performance.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	sdk/machines/octatrack/module-adapters/standalone-recipes.json
#	src/engine/assets/analog-bd-composition-proofs.json
#	src/engine/assets/bootstrap-package.json
#	src/engine/assets/coldfire-packages.json
#	src/engine/assets/descriptor-recipes.json
#	src/engine/assets/dsp-packages.json
#	src/engine/assets/menu-recipes.json
#	src/engine/assets/module-build.json
#	src/engine/assets/platform-writes.json
#	src/engine/assets/requested-packages.json
#	src/engine/assets/resident-dsp.json
#	src/engine/assets/rom-packages.json
#	src/engine/assets/usb-audio-packages.json
#	src/engine/assets/utility-packages.json
… hash re-pinned

Toolchain-image build imported; Bar LED's USB package is unchanged
(de7f9cae). Tape Echo and Euclid recipes re-pinned for the four rebuilt
asset files; Play Modes stays on its reviewed sources. Native comparison:
78 match, 96 refused, 0 mismatches. Analog BD: all 212 proofs identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The committed package kept beside Slow LFO on the tester's MKI (SELF TEST
2/2 intact). Reported: external MIDI clock, tempo changes, pattern scales
3/4, 3/2 and 2X, per-track mode on the master length, STOP/PLAY and
pause/continue. module:verify writes the chooser-metadata row; the
release notes gain the MKII known issue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The base is built from that file, so a row here makes the committed beta
base stale; recent ColdFire-only modules carry no row either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nathangroth
nathangroth marked this pull request as ready for review November 5, 2026 22:28
…n only)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

repeat98 commented Nov 6, 2026

Copy link
Copy Markdown
Owner

One more thing I noticed while reading the 5 November results, separate from what's still open from my last comment.

At 2X the README says the green comes once every two passes, but the presentation overview says it flashes green on the first beat of each pass. By unit.s's own reasoning, a 16-step pattern at 2X should go green on every pass, so it looks like the master step doesn't follow the scale the way the code expects. Is the once-every-two-passes what you want? If so, please say it in the overview and add a Known issue: line to the release notes. If not, make it follow the scale.


Generated by Claude Code

This branch has not been deployed

No deployments
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