Skip to content

Dev: v3.11.0 - #473

Merged
engmung merged 15 commits into
mainfrom
dev
Oct 4, 2026
Merged

engmung merged 15 commits into
mainfrom
dev

Conversation

@engmung

@engmung engmung commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Release v3.11.0 (core) with Audio v0.7.0. Tagged v3.11.0 at 3a0b7fd on dev.

Merging this deploys the site from main: the new shelf images, the flasher manifest, the Audio guide and the rebuilt Basics pack.

After the merge

  • The GitHub release is created from the tag with the notes below, and the Audio image attached. Publishing it triggers the workflow that attaches the core images.
  • The community host (Pi) must be redeployed, so the Basics pack card and the pattern builds there become the new ones.

Checked for this release

  • CI on dev: green.
  • build.sh all and the footprint pins: pass.
  • The staged images were scanned: no credentials, the right version strings, Core carries no audio markers, and Audio carries its own.
  • check_versions.py: agrees.
  • A final review by five reviewers over main..dev found no blocker; its findings are fixed in web: the guide has a fourth part, Audio #477.
  • On panels: the update from a 3.10.5-equivalent image kept patterns, Wi-Fi and the playing pattern; parked patterns resume in about 0.13 ms; three rebuilt Basics patterns measured at about twice the frame rate; the Audio image reports 19.5 dBm; the real extension held the knobs through silence.
  • Not run on a panel: the published credential-free images themselves (the bench boards take their Wi-Fi from the build), and the microphone at the new transmit power.

Release notes

Installed patterns run faster and come back at once. The console is light and one thing. The audio path is rebuilt from the extension to the microphone.

Patterns

  • Installed patterns run faster, and nobody has to edit one. Patterns are now compiled at -O2 with the maths they call most computed inline, and the results are bit-exact. The Basics pack is rebuilt this way for the first time since August: every one of its 33 patterns is faster, 1.11 to 2.36 times the frames a second, 1.52 at the median. On a second panel three of them went from 24.2, 18.5 and 33.0 ms a frame to 11.5, 11.0 and 12.8.
  • To get it: update the firmware first, then install the Basics pack again from the site. A pattern already on a panel keeps the build it was installed with. Community patterns are rebuilt the first time someone sends one again.
  • The rebuilt pack needs firmware 3.5.1 or later (3.2.0 to 3.4.0 refuse all 33 of its patterns), and 3.10.5 or later for the largest ones on the Audio edition. Update first; reinstalling replaces files that load with files an old firmware will not.
  • Going back to a pattern no longer loads it again. A pattern that has run stays parked in PSRAM, and picking it again resumes it in about 0.2 ms where the heavy ones took seconds (Branched Flow 3.3 s, Two Stream 4.1 s). Up to 16 stay parked; they give their memory back when a new load needs it.
  • SELECT shows parked patterns live as the knob reaches them.
  • What this takes away: a pattern that wants a fresh start every time it is picked does not get one. setup() runs once per load. Restarting the panel, or any install, delete or reorder on the Patterns page, starts it again.

The console

  • Light by default, with dark as a remembered toggle, and one look across its pages.
  • The home page is the panel's control surface: now playing with its arrows, on/sleep, brightness and the four knobs, with the device's facts under them. The edition has a card of its own, with the pages it carries and the update notice.
  • Knobs: set all four at once with the All row.
  • The Status page shows the crash record when there is one.

Audio edition v0.7.0

  • The Audio page is a console page. It says who has the knobs (the microphone listening, off or not fitted; the extension or the phone app), names the bands K1 to K4, and shows what each knob actually gets.
  • It saves only what you changed. It reads the panel's mapping before it can write, so a failed read followed by one edit can no longer overwrite four bands, and two tabs no longer undo each other. The page is 17.2 KB where it was 19.9.
  • A microphone that is not delivering no longer moves the knobs.
  • The browser extension (0.2.0) holds the knobs through silence. A paused or quiet tab keeps each knob at its rest value instead of letting go after half a second.
  • A knob set from the console's sliders, by MIDI CC 20-23 or by /api/params stays where it was put until its encoder is turned; sound does not move it, and the Audio page does not show that yet.
  • Live means the panel is being driven. Audio-React switched off on the panel, a silent tab, a closed tab, a wrong address and a panel without the Audio edition each say so, where every failure used to read "WebSocket error".
  • To update the extension, pull the repository and press Reload on chrome://extensions; your mapping is kept.

Updating

  • Standard firmware: the notice on the console's home page, or patternflow.work/update.
  • Audio: patternflow.work/editions, the Audio card, Install to my panel; or drop patternflow-audio.ino.bin from this release on the panel's Update page. The link on an older panel's Update page goes to /update, which installs the standard firmware and would replace the edition. Your settings stay, and the Audio card puts it back.
  • Reflashing keeps your patterns, your Wi-Fi and your settings.

Editions

Audio v0.7.0 is cut on this core. Performance v0.4.0 is still the image on the shelf and is on core 3.10.4 until its maintainer re-cuts it: no parked patterns, no light console, and a pattern's code still lives in internal RAM there, so the rebuilt Basics pack installs but a large community pattern can be refused. The clock and MIDI try-out images are unchanged.

On the site

  • An Audio guide joins Build, Play and Make at patternflow.work/guide: the edition, sound from a browser tab with the real editor to try, the on-board microphone, and the board as a MIDI port with Ableton.

How this was checked.

  • Pattern speed: measured on two panels by its author, and three patterns measured again on a third.
  • Parked patterns: measured on two panels with 12-13 modules parked.
  • The console and the Audio page: on panels, light and dark, phone and desktop widths.
  • The extension: run against a panel with the microphone. A tone moved K1, four seconds of silence left the knobs held, and Stop handed them back.
  • Updates over Wi-Fi: done repeatedly on three panels between Core and Audio images.
  • Not checked: the Audio page on a real phone or in the phone app, and the extension in a Chrome that asks for local-network permission. The Performance and MIDI images build and pass their checks but were not run on a panel for this release.

The full list is in CHANGELOG.md.

🤖 Generated with Claude Code

An installed module was unloaded whenever another pattern took the panel,
so every return paid a whole load: FAT read, relocation, constructors and
setup() - 25-100 ms for most of the catalogue, 3.3 s for Branched Flow,
4.1 s for Two Stream, 0.6 s for Burgers and Wave Cascade.

A module that holds no internal RAM is now parked in PSRAM when it is left
(src/core_module_resident.h: 16 slots, LRU) and resumed on the loop task
when it is picked again - no read, no relocation, no setup(), carrying on
from its own state the way compiled-in presets always have. SELECT switches
to a preset or a parked module on the detent and shows it live.

So that modules are parkable, data sections go to PSRAM first, as code
already did (PF_MODULE_DATA_PSRAM_FIRST; follows PF_MODULE_RESIDENT_MAX).
A-B-B-A on two boards, 16 module runs: 13 within noise (-1.1..+0.8 %),
Burgers +2.6 %, Wave Cascade +2.2 %, Breakout +0.85 %; internal heap with a
module running +4..10 KB.

Parked modules give way: before a fresh load until PSRAM free >= the 4 MB
per-module runtime limit + 512 KB, on every module allocation while anything
is parked until 512 KB stays free, on a refused allocation, before the
loader's retries, and on any install/replace/delete (a storage generation
bumped by every module-file writer, including ones that do not capture).

Hardware (Audio edition, .217 and .246): every revisit resumed in
85-210 us; internal heap flat with 12-13 modules parked; an upload emptied
the table and PSRAM came back by exactly the parked 683 KB; five 1.5 MB
probes held the floor (PSRAM never under ~3.1 MB, 0 refusals); random soaks
of 300 and 200 switches, 0 resets. Checked by hand in SELECT.

Static DRAM +112..120 B per edition (re-pinned), IRAM unchanged.

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

vercel Bot commented Oct 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
pattern-flow_origin Building Building Preview Oct 3, 2026 2:51am UTC

engmung and others added 14 commits October 3, 2026 11:53
…thing

Light by default with dark kept as the remembered toggle; one base block of
shared parts across Console, Patterns, Status, Wi-Fi, Knobs and Update; home
leads with the panel's controls; the header wraps instead of scrolling on a
phone; the monospace stack gains Windows fonts. No page grew past its gzip
size. Feature pages are untouched and take the light palette from the
chrome. The guide's console demo is regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…knobs move together

The edition the panel runs is a card of its own (name, versions, the
feature pages it carries, the update notice, a button to the other
editions) instead of one more row among the facts. The knobs show their
values and gain Together (one drag moves all four) and Shuffle with Undo,
each one request; the arrow keys step through patterns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts all four at once

Home: the device facts are back in the control card under the knobs, as
before; the right column is the edition card and the pages. The knob
extras (Together, Shuffle, Undo, the value readout) are gone - "all four
at once" meant the Knobs page: it now has an All row that sets direction
and edges per click for the four, reading Mixed while they differ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
firmware: the console is light, and its six core pages look like one thing
…e, partial saves, an extension that holds and says what is happening

Audio edition and the audio extension only; the firmware core, the console
chrome and the other editions are untouched.

/audio-in
- The page is a console page: light by default, the console's parts, a
  Sources list that says who has the knobs (microphone listening, off, not
  fitted; extension or phone app), knobs named K1..K4, dB and Hz on the axes.
- It reads the panel's mapping before it can write, and an edit posts only
  the field that changed, one request in flight. A failed read can no longer
  be followed by an edit that overwrites four bands.
- The cursor, level line and readout show what the knob gets.
- Levels ride the console's PF.poll lane instead of a private loop.
- The builder only assembles (the adapter, CSS and bar are real files),
  strips comments, and --check gates the stamped page at 17.5 KB gzip:
  17.2 KB now, 19.9 before.

features/audio_in, features/audio
- POST /api/audio-in applies a band's field when any of that band's fields
  is present; reset takes band=N; reset-all includes attack.
- A microphone that is not available cannot drive the knobs; nan arguments
  are refused. The d= message and every documented field stay.

tools/patternflow-audio-extension (0.2.0)
- One mapping model (mapping.js) shared by popup, offscreen and editor.
- The steady value is resent, so a silent or paused tab holds the knobs at
  rest instead of releasing the lanes after 500 ms.
- Live means the panel is being driven: Audio-React off, a silent tab, a
  closed tab, a wrong address and a panel without the Audio edition each
  say so. New installs start in Auto range with the Smooth curve.
- The editor works down to a half-screen window and a phone, Preview no
  longer covers what it demonstrates.

console_serve.py answers the audio endpoints with switchable states
(/mock?audio=music|silence|off|fresh|nomic|stalled|phone|ext|noread) and
assembles /audio-in live.

Checked: build.sh all, the footprint pins, the console and source checks;
on a panel with the microphone (mapping kept across the update, one-field
save, unchanged frame time) and with the real extension against it (hold
through silence, Aud off, Stop).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
firmware, tools: the audio path reworked — /audio-in as a console page, partial saves, an extension that holds
…s is rebuilt

No pattern source is edited. What changes is how a .h becomes a .pfm:

- build_module.py builds at -O2 (was -Os). On today's Basics presets,
  same board, same boot: 3..34 % more frames a second.
- abi/pf_libm.h (new, included first by pf_module.h) gives floorf, ceilf,
  truncf, roundf, fminf, fmaxf and fmodf inline bodies that return what
  libm returns, bit for bit, and call the real symbol outside the range
  each proof covers. check_libm.py: 20,083,619,797 comparisons, 0
  mismatches, MSVC and g++ with sanitizers. check_module_libm.py reads a
  module the real compiler built. _math_probe on a board: "math ok 9/9".
- web/public/packs/basics.zip is rebuilt for the first time since
  2026-08-15 (GCC 8.4, descriptor 2). All 33 against their August builds
  on one board: 1.11x..2.36x the frames, 1.52x at the median.
- Old-style headers left untouched (floorf/fmodf per pixel), today's
  recipe -> this one: 0510 14.8 -> 10.3 ms, 0515-4 25.3 -> 17.5,
  0520 26.9 -> 20.3, 0601 26.0 -> 20.2.
- All 147 distinct public community headers build this way (the old
  recipe's compiler crashed on two) and each was loaded and run on a
  board: no reset, no refused load.

What it costs, as accepted by the owner:
- The pattern's own arithmetic can differ in the last bit (-O2 and inline
  code move where GCC fuses a*b+c). The seven functions are exact.
- Code is larger (median 1.36x over 145 community patterns). Firmware
  before 3.10.5 places code in internal RAM and will refuse some that
  loaded; Basics now needs 3.5.1 (descriptor 2). CHANGELOG says which.

Also: SHIPPED_CODE_CEILING becomes the 16 KB instruction cache plus an
allow-list over the old 6144 B internal line; abi.sums re-pinned (no layout
change; --update keeps its notes); the "module is 20 % slower" claim is
replaced by a measurement (Origin: 9.56 ms compiled in, 9.81 as a module).
Shared headers changed in comments only; the firmware image is unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
firmware: modules are built at -O2 with exact inline maths, and Basics is rebuilt
… the microphone, MIDI and your DAW

/guide/audio (and /ko): getting the Audio edition onto the board first,
then three sections with names and no order between them.

- A browser tab: the extension, its popup's states, and the extension's
  real editor running in the page in its demo mode, driving the 3D
  board's knobs; a hand on a knob wins for five seconds, as on the board.
- The microphone: what to buy, five leads on four places (GND takes two),
  the switch, and the /audio-in page. AUDIO_GUIDE.md and the editions card
  said four leads and now agree.
- MIDI and your DAW: connecting with rtpMIDI, Ableton's Remote and
  mapping, channel 1 and the numbers each way, the console's MIDI page.
- OSC, the phone app and the Director's .mid export are links at the end.

The hub has four cards. The simulated board learns the Audio edition
(OSC and AUD rows on NETWORK, toggled by K2/K3) and lanes as an overlay
that never writes into the stored knob values. editor_demo.py generates
web/public/guide/audio-editor from the extension's editor. The console's
MIDI page no longer says MIDI has a row on the NETWORK screen.

Checked: typecheck, lint, 390 tests, next build, build.sh all and the
footprint pins; walked in headless Chrome at 1440 and 390 wide, English
and Korean. Not checked on a real phone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Text and guards, no behaviour change beyond one link.

- /update on the site says it installs the standard firmware and sends an
  edition's owner to its card; the panel's own Update page now links an
  edition to patternflow.work/editions#<variant> instead of /update, which
  would have replaced it with the core.
- The Audio card no longer claims a raised Wi-Fi transmit power (the core
  has been at full power since 3.10.5).
- The Basics pack card says it needs firmware 3.5.1 or later.
- AUDIO_GUIDE and the changelog say that a knob pinned from the console,
  MIDI CC 20-23 or /api/params outranks sound until its encoder is turned;
  the changelog's /audio-in size and its "same or smaller" line are
  corrected, and a restart is named as what gives a pattern a fresh start.
- shelf.sh puts back a credentials file left aside by a killed run and
  refuses to build with composition files left in features/; the aside
  name is gitignored.
- RELEASING.md gains two steps: regenerate the guide's console demo after
  the cut, and redeploy the community host after main deploys.

build.sh all and the footprint pins pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bundles/audio/overrides.h pinned 17 dBm. That was a raise while the core
shipped 13 dBm; since 3.10.5 the core is at 19.5 and the pin made Audio
the one build with less. The override is gone, so v0.7.0 follows the
core. Checked on a panel: /api/status txDbm reads 19.5 on the Audio image.
Not checked: the microphone's noise floor at the higher power (the board
with the microphone was not on the bench).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web: the guide has a fourth part, Audio
Core v3.11.0, Audio v0.7.0 staged by shelf.sh from a sketch copy without patternflow_secrets.h; the previous folders retired to their tags. The guide's console demo is regenerated for the new version, and README's Moving fast note names the release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@engmung engmung changed the title firmware: a pattern that has run stays loaded and comes back at once Dev: v3.11.0 Oct 4, 2026
@engmung
engmung merged commit eaa294b into main Oct 4, 2026
9 checks passed
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.

1 participant