Skip to content

Improvement: one Octatrack base update: update and sync screens, CPU FULL guard, stall frames, engine price in the package, Windows USB, a larger RAM boot stage - #1502

Merged
repeat98 merged 38 commits into
mainfrom
base/update-and-sync-screens
Nov 13, 2026
Merged

repeat98 merged 38 commits into
mainfrom
base/update-and-sync-screens

Conversation

@repeat98

@repeat98 repeat98 commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

One Octatrack base update instead of six pull requests that each needed a base of their own (owner, 13 November 2026). New base: 4e9a87ea. Each part is merged with its commits and authors; the closed pull requests keep their own descriptions and test notes.

  • What was wrong or hard:
  • What this changes:
  • How I checked it:
    • Host: test_status.c (the screens' texts and bars, the lock, a release only after its press, the give-up times, and the unit's sequence where the progress outlives the outcome for a moment), test_flash.c (outcome, progress down with it), the base's other host tests. Site: the dialog, sync, link and guide tests, tsc -b, eslint.
    • npm run pr:ready on this PC: every step passes except two SDK tests, test_dsp_packages_rebuild_from_source (KeyError 'modulation') and test_real_units_relocate_alike… (1004 != 1009), which the session behind Improvement: a busy Octatrack refuses a further module machine or effect with CPU FULL #1499 saw fail on untouched main on this PC as well. In CI both pass (module-suites sdk), and octatrack-source rebuilt the committed packages byte for byte.
    • On the owner's MKII, 13 November 2026, over USB with scripts/device.mjs (boot, then flash), the unit on two slots: five full updates between bases of this branch (be13282e, fb8ccf72, 71e143d2, 4e9a87ea), each saved and verified in 28 to 36 s; two starts from flash afterwards, each confirmed after 15 s with USB back on Windows. The owner watched the last full runs and said they worked well; I have no screen capture.
    • Found on the unit and fixed here: after BASE SAVED the screen could fall back to WAITING with the panel held for 20 s (the progress came down a moment after the outcome). Now covered by the host test.
    • Not checked on a unit: the site's dialog driving a real update (the runs used the command line), a module sync's box, a one-copy unit's conversion with these screens, a key held across the start of the lock, the guard on this exact base. The Improvement: a busy Octatrack refuses a further module machine or effect with CPU FULL #1499 notes on the guard, as its session wrote them:
      • On a unit (owner's MKII, 13 November 2026, development twins, 15 modules, playing at 126 BPM): on twin 0dbd0ee2, at 86 % CPU, picking FM Synth on T2 in SRC SETUP showed "CPU FULL / T2 SRC / FM SYNTH / CPU 86% / UNIT IS BUSY" and T2 kept its machine. On twin 865bcc10 (with Fix: an installed Sidechain keeps its key bus memory free from the start, so picks are not refused NO ROOM after a restart #1492 in): at 85 % picking Euclid on T2 FX1 showed "CPU FULL / T2 FX1 / EUCLID / CPU 85% / UNIT IS BUSY" and the slot stayed NONE; at 88 % FILTER and NONE on the same slot went through; stopped, at 63 %, Euclid went through.
      • Not tried on the unit: a pick just under the line, the box over other pages, a waiting (queued) pick. A Part change or paste that brings module effects in is not refused, by design.
      • Where the 85 % line comes from: 32 units' uploaded load windows, 30 October to 13 November 2026 (2,053 five-minute windows). At 85 % mean CPU or more the longest UI tick gap passed 100 ms in more than half the windows; under 65 % in about one in twenty.
      • Measured and dropped (same unit, same day): a lower guard share does not help the panel (with FM Synth 0.1.2 installed, a share of 50 % skipped over 20,000 renders a second and the load stayed at 77 %); two small cuts in the guard's wrapper measured 76.4 % against 76.6 %, inside the noise, taken out again.
  • Open findings from the unit, not fixed here:
    • Once, after a RAM boot from the USB-Audio-off variant to the standard layout, Windows said the device was not recognised until a power cycle; two repeats of the same step and two starts from flash worked. Cause open.
    • While the base saves itself and runs on, the load window showed one frame gap of 33 ms and a UI tick gap of about 3,600 frames (1.3 s).
    • WAITING FOR MODWERK does not say that it gives up by itself after 25 s.
    • The missing-modules page can open right after an update, since the update itself empties the modules.
    • A save sent one second after the restart was refused once ("hello was not confirmed") and went through eight seconds later; the site retries, the command line did not.
  • What the guides lacked or got wrong, and where I fixed it: docs/OCTATRACK_TWO_SLOT_BASE.md described the old saving box and nothing about a lock or a sync box: rewritten there, with the unit checks still owed. The elekloader README said a RAM boot takes 1.25 MiB without saying that this is also the ceiling of every USB update: corrected there and in boot.h. The other guide edits come with Improvement: the Octatrack base keeps the frames before a stall #1494, Improvement: a busy Octatrack refuses a further module machine or effect with CPU FULL #1499 and Improvement: a machine engine's DSP price lives in its own package #1487 and are described in those.

🤖 Generated with Claude Code

repeat98 and others added 30 commits November 12, 2026 16:06
…d each track's FM test once a frame, and stock renders a track the engine would not change

Installed on no track, FM Synth cost points of every frame on every sample
track: its test for an FM track read battery RAM two or three times a track,
and GLIDE once. The reads are now taken at a frame's first use, and a track
that is not FM, holds no synth voice, has GLIDE off and starts no voice goes
straight to stock's renderer. No function changes.

Not yet a release: no version, release notes or TESTING entry; not heard on
an FM track. The machine port's pin and recipe follow the changed source.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…vice

Windows applies the Microsoft OS 2.0 registry property (DeviceInterfaceGUIDs)
only when it installs an interface. A Windows computer whose interface 1 was
set up without it keeps no device path, so WebUSB's claimInterface fails and
the site shows its 'another tab' line. A new revision (0x0101) should make
Windows set the interfaces up again. Draft: not yet tested on a unit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…names the computer on Windows

The base reports bcdDevice 0x0101: regenerated with --beta --write (browser .bin =
build_core.py .bin 25e1bbf7). The descriptor test now requires the new revision and
stock's bytes elsewhere. On Windows the busy line adds: install the latest base from
the card once (a computer that set up the vendor interface without its GUID can't
claim it, with the same NetworkError as a busy unit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
octatrack:module-packages restamped four; Sidechain 0.2.1 is held, so its
requiredBase is set by hand (the base build printed its sha fd275bf2, the committed bytes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An ABI 10 engine package carries its price per voice in its header's cycles
and kind (bytes 44-46), as an effect's per-instance figure: worst case per
sample, charged once per track that plays it. It lies outside the controller
digest, so a new price ships in the package and never changes the base's
trust row (repeat98, #1480).

- loader.c: an engine needs cycles > 0 and kind executed or hardware; init
  and the other descriptor bytes stay 0. Older bases already refuse any
  price on an engine, so they fail safe.
- abi9.engine (the builder) refuses the same; module-set.ts checks it as
  the loader does.
- machine_registry.c: a voice is charged at its module engine's price; a
  record priced beside it, a per-core cost of another kind or no price at
  all is refused, never admitted free.
- Analog BD: 414 per voice in its engine header (411 + 3 folded, so the
  same DSP room as today); its machine record keeps 0/0 and its kind.
- Beta base rebuilt; only Analog BD's trust row and package change.
  Sidechain 0.2.1 (held) stays trusted and now names the new base.
- Machine recipes recaptured: identical images, copies and fills; only the
  hashes of machine-ports.json and machine_ports.py move.
- New sdk/tests/test_base_bound_trust.py: every published base-bound
  package is trusted by, and names, the committed base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream's #1483 rebuilt the base; this regenerates it with the engine price
change on top: Analog BD's recipe recaptured (identical copies and fills),
base and base-bound packages rebuilt, Sidechain 0.2.1's held entry pointed at
the new base (test_base_bound_trust caught it).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…der's header checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The frame interrupt keeps the last 128 frames (the gap to the frame before and how
long the frame interrupt ran); the tick that finds a new stall record copies them
to battery RAM, and LOG pages them after the stall record. The site, the Worker,
device stall and diagnostics:pull read them. Base rebuilt, packages relinked.

Co-Authored-By: Claude <noreply@anthropic.com>
diagnostics:pull may read only shared sources; device-log.ts is not one.

Co-Authored-By: Claude <noreply@anthropic.com>
…e says how

The relink holds a lagging base-bound package back, row and all; test_base_bound
rebuilds it against the new base and its published bytes match.

Co-Authored-By: Claude <noreply@anthropic.com>
The CPU budget prices machine renders only. A pick is now also refused while
the CPU meter stands at 85 % or more over its last four seconds, with the
same box showing the measured load. Host tests cover the registry and the
box; seen on an MKII on a development twin. The base is not regenerated.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
The loader's selection guard asks status.c before stock writes an FX pick:
a module's effect on a unit at 85 % CPU or more is refused with the CPU
FULL box on its slot. Stock effects and NONE always pass. selection.c links
after the write-lease entries, which do not move.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…r to keep their hands off the Octatrack

The update dialog showed the browser's own 4 px progress element, only while a
send ran, so most of the update had no visible progress, and nothing said that
the Octatrack looks ready after its restart while the base is not saved yet.

- One blue bar for the whole update (ProgressBar), with its percentage and a
  moving sheen while a step reports no figure; the sync dialog uses it too.
- A "Hands off your Octatrack" alert for as long as the update runs, and the
  same words before it starts.
- The link reports 'saving' once the container is on the unit, so the page can
  tell sending it from the write.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…SYNC box with a progress bar

Not ready: the base is not regenerated (the sources pin and the binding still
name the current base) and nothing here has run on a unit.

- status.c: the transfer screens replace the small saving box. A base update
  takes the whole screen and holds every key and knob from the first packet of
  a base until the write is over; a module sync shows a box with a bar.
- flash.c: reports each own write's outcome and whether this start is an
  update's trial (two slots); a failed write takes its screen down.
- ep0.c, boot.c: what the host is sending, and an armed RAM boot.
- Host tests for the screens, the lock and the outcome.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
… texts

The view before an update was a wall of text: three cards with a sentence
each, a warning paragraph, a note above them. Now one intro line, the three
steps as one row, and what to do before the start as a line each.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…nto base/update-and-sync-screens

# Conflicts:
#	scripts/device.mjs
#	scripts/diagnostics-pull.mjs
#	sdk/machines/octatrack/base-binding.json
#	src/engine/assets/octatrack-base-sources.json
#	src/engine/assets/octatrack-base-variants.json
#	src/engine/assets/octatrack-base.elemod
#	src/engine/assets/octatrack-module-packages.json
# Conflicts:
#	sdk/machines/octatrack/base-binding.json
#	sdk/machines/octatrack/module-adapters/machine-recipes.json
#	src/engine/assets/octatrack-base-variants.json
#	src/engine/assets/octatrack-base.elemod
#	src/engine/assets/octatrack-module-packages.json
… measurements, USB package

No function changes. The package is the build of ed6188e's source and is
byte-identical after merging main. Listening checks on the unit are still
open and listed in TESTING.md. The package manifest row and the machine
recipes are left to the combined base branch, which recaptures them once.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…e/update-and-sync-screens

# Conflicts:
#	sdk/machines/octatrack/base-binding.json
#	src/engine/assets/octatrack-base-variants.json
#	src/engine/assets/octatrack-base.elemod
#	src/engine/assets/octatrack-module-packages.json
Counted on the owner's MKII on 13 November 2026 (300 ticks in 5 s); a frame is 363 µs.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
repeat98 and others added 8 commits November 13, 2026 10:33
…re the five machine recipes

The base-bound packages are not relinked yet.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…BASE SAVED

flash.c reported the outcome a moment before its progress came down, from
another task, and the screen logic could fall back to waiting with the panel
held for 20 s. The progress now comes down with the outcome, and nothing
locks the panel again until another base starts to arrive.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…-bound packages relinked

Sidechain Compressor, Output Matrix, CC Map, Recorder Loop Fix and Analog BD
now name the new base.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…older bases take

The combined base came within 668 bytes of the 1.25 MiB every base on a unit
stages for a RAM boot, which is also a USB update's trial, and its development
build passed it. This base stages and starts up to 1.5 MiB, so updates after
it have room. build_core.py still refuses a released base over 1.25 MiB, since
units on older bases could not take it over USB, and prints the room left.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…st afterwards

A module release does not ride in a base pull request, and 0.1.3 still needs
its owner-approved update record, its UI captures and the listening test. The
module, its catalogue and changelog rows, its package row and the poly.s pin
are back at 0.1.2; origin/module/fm-synth-0.1.3 keeps the release.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
…t FM Synth 0.1.3; recipes and packages follow

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
@repeat98 repeat98 changed the title Improvement: one Octatrack base update: update and sync screens, CPU FULL guard, stall frames, engine price in the package, Windows USB, FM Synth 0.1.3 Improvement: one Octatrack base update: update and sync screens, CPU FULL guard, stall frames, engine price in the package, Windows USB, a larger RAM boot stage Nov 13, 2026
@repeat98
repeat98 marked this pull request as ready for review November 13, 2026 10:42
@repeat98
repeat98 enabled auto-merge November 13, 2026 10:43
@repeat98
repeat98 merged commit c717bcd into main Nov 13, 2026
36 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants