Skip to content

firmware, tools: the audio path reworked — /audio-in as a console page, partial saves, an extension that holds - #475

Merged
engmung merged 1 commit into
devfrom
audio-polish
Oct 4, 2026
Merged

engmung merged 1 commit into
devfrom
audio-polish

Conversation

@engmung

@engmung engmung commented Oct 4, 2026

Copy link
Copy Markdown
Owner

The whole audio path: the browser extension, the /audio-in console page, and the two audio features. Only the Audio edition and the extension change. The firmware core, the console chrome and the other editions are untouched.

It started from an audit (five reviewers, about 80 findings) that came down to three causes:

  1. The editor was live on defaults before the panel's mapping arrived, and every edit rewrote the whole mapping. One failed read plus one edit overwrote four bands; two tabs reverted each other.
  2. The editor drew the mapping in its own units, so the cursor and readout were not what the knob got.
  3. /audio-in could not be developed like a console page (no mock endpoints; CSS and JS inside Python strings), which is how it missed the light redesign.

/audio-in

  • A console page: light by default, the console's parts, and a Sources list that says who has the knobs. Knobs are named K1..K4, with dB and Hz on the axes.
  • It reads before it writes. An edit posts only the changed field, one request in flight.
  • Levels go through PF.poll instead of a private loop.
  • The builder only assembles and strips comments. --check gates the page at 17.5 KB gzip: 17.2 KB now, 19.9 before.

Firmware (features/audio_in, features/audio)

  • POST /api/audio-in applies a band's field when any of that band's fields is posted.
  • reset takes band=N.
  • An unavailable microphone cannot drive the knobs.
  • nan arguments are refused.
  • Nothing documented was removed: the d= message and every status field stay.

Extension 0.2.0

  • One mapping model, mapping.js.
  • A silent or paused tab holds the knobs at rest. The steady value is resent; the firmware releases a lane after 500 ms.
  • Live means the panel is being driven. Audio-React off, a silent tab, a closed tab, a wrong address and a non-Audio panel each say so.
  • New installs start in Auto range with the Smooth curve.
  • The editor holds at half-screen and phone widths.

Dev server

  • 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 (five compositions), check_footprint.py, console_pages.py check (with the size gate), check_sources.py, check_boundaries.py.
  • On the panel with the microphone:
    • The stored mapping survived the update.
    • No POST before the first read.
    • One slider step posted attack=0.645 alone and held across a reload.
    • Frame time (10.4 ms) and microphone drops were unchanged with the page open.
  • The real extension against that panel:
    • A tone swung K1 between 0.30 and 0.85.
    • Four seconds of silence left the lanes held at rest.
    • Audio-React off on the panel turned the popup to Aud off.
    • Stop handed the knobs back to the microphone.

Not checked

  • A real phone on /audio-in (touch was emulated).
  • The Android app's WebView.
  • A current Chrome with its local-network permission prompt (the panel requests ran in Playwright's Chromium).
  • Page speed A/B on the panel: the Wi-Fi link swung between 24 and 366 ms ping during the run, so old-vs-new load times were not comparable.

Left as is, on purpose

  • Dragging a box edge in Auto range still takes all four knobs to manual. Changing that needs a design decision.
  • The Android app has the same change-only skip the extension had. It is noted in docs/audio-ws-spec.md and not fixed here.

🤖 Generated with Claude Code

…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>
@vercel

vercel Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
pattern-flow-open Ready Ready Preview Oct 4, 2026 5:08am UTC
1 Skipped Deployment
Project Deployment Actions Updated
pattern-flow_origin Ignored Ignored Oct 4, 2026 5:08am UTC

@engmung
engmung merged commit 64697df into dev Oct 4, 2026
10 checks passed
@engmung
engmung deleted the audio-polish branch October 8, 2026 13:22

This branch was successfully deployed

1 active deployment
Preview – pattern-flow-open — 4f8d8501 Deployed Oct 4, 2026 by vercel[bot]
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