Commit graph

163 commits

Author SHA1 Message Date
Me Here
4ceb80b4f4 Bump version to 0.0.65 2026-05-28 23:38:53 -05:00
Me Here
cc56741483 PM_K-1: on-screen MIDI indicator + auto-mute buzzer when a host is listening
The editor's 'Device audio' now sends a MIDI Active-Sensing heartbeat (0xFE, every 250ms)
to the device while on. The firmware reads usb_midi.ports[0]; while it hears the heartbeat
(<1s) it shows a green 'MIDI' badge top-right and silences the buzzer (the computer plays);
~1s after it stops, it reverts to the buzzer and hides the badge. Manual MUTE_BUZZER still
works. Verified headless: host detected -> MIDI shown + buzzer duty 0; timeout -> reverts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:38:53 -05:00
Me Here
6b508ab86e Bump version to 0.0.64 2026-05-28 23:08:48 -05:00
Me Here
ba8d57e7ab PM_K-1 CircuitPython: fix polymeter (~) timing — true ratio polyrhythm
The firmware ran every lane at a fixed beat/sub, ignoring the ~ flag, so a poly lane
(e.g. cowbell:3~) played quarter-notes instead of fitting its cycle into lane 1's bar —
the duple 'and' coincided with a triplet note. Now match the web engine: a poly lane's
whole cycle spans the master lane's bar (dur = master_bar / steps). Verified: claves:5~
over kick:4 -> both cycles = 2.400s (5-over-4); 3-over-2 lands correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 23:08:48 -05:00
Me Here
8254bb042c Bump version to 0.0.63 2026-05-28 22:57:23 -05:00
Me Here
b5584454b3 PM_K-1 CircuitPython: add boot.py to guarantee the USB-MIDI port appears
If the device isn't seen as a MIDI input (USB endpoint pressure from drive+serial+HID+MIDI),
boot.py disables the unused HID interface and enables usb_midi — copy it on and power-cycle.
Bundled into pm_k1_circuitpy.zip; documented in the README.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:57:23 -05:00
Me Here
186b51ae23 Bump version to 0.0.62 2026-05-28 22:55:57 -05:00
Me Here
aaf5c4d260 editor: MIDI 'Device audio' diagnostics (show device name + pulse on note)
User reported no computer audio + 'no device being controlled'. Add visibility to
diagnose: the button now shows the connected MIDI input's name (or 'no device'), the
toggle alert lists detected inputs, and the button pulses green on each Note-On
received — so it's clear whether the device is seen and whether notes are arriving.
Also call ensureAudio() in the message handler as a guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:55:57 -05:00
Me Here
8433c5bfe2 Bump version to 0.0.61 2026-05-28 22:40:09 -05:00
Me Here
7ccc75e399 Phase 3: USB-MIDI audio — play the device through the computer's speakers
Firmware (pico-cp/code.py): on every click, send a USB-MIDI note-on per firing lane —
GM drum note by voice (SOUND_GM), velocity by level (accent/normal/ghost) — via the
default-enabled usb_midi.ports[1]. Polyphonic, so the computer plays the full groove.
New CONFIG: MIDI_ENABLED (default on), MUTE_BUZZER (silence the buzzer when using
computer audio).

Editor (editor.html): a '🎹 Device audio' toggle uses the Web MIDI API
(requestMIDIAccess) to voice incoming notes through the existing synth — Note-On ->
GM_NUM[note] / velocity-to-gain -> playInstrument(). The device is the clock; the
browser is the sound module, locked in sync. Chrome/Edge.

Verified: firmware emits the right notes (kick+hat on beat 1 of four-on-the-floor,
snare's rest skipped); editor loads clean with the toggle + handlers present. Docs
(info-kit, both READMEs) updated. The on-device buzzer/screen still work standalone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:40:08 -05:00
Me Here
d9a2be7389 Bump version to 0.0.60 2026-05-28 22:20:35 -05:00
Me Here
d558dccbde Phase 2: editor 'Save/Load to device' + bundle the editor on the drive
Add to the editor's set-list ⋯ menu:
  - 📟 Save to device — writes the active set list as programs.json (the same file the
    PM_K-1 firmware reads). Uses the File System Access API to write straight onto the
    CIRCUITPY drive (Chrome/Edge); falls back to a download to drag on. Reuses
    setupToPatch() per item -> {title, programs:[{name, prog}]}.
  - 📥 Load from device — reads a programs.json back into a new set list (patchToSetup
    per item; reuses the existing import path).
Bundle the built editor.html into pm_k1_circuitpy.zip so the drive carries its own
offline programmer. info-kit + pico-cp/README document the workflow.

Verified: editor loads with no console errors; both menu buttons + all four functions
present; zip contains editor.html. (FSA save needs a real user gesture to test on-device.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:20:35 -05:00
Me Here
3664b7a29e Bump version to 0.0.59 2026-05-28 22:16:36 -05:00
Me Here
6edb89e33c PM_K-1 grid: smaller circles + align beats vertically across lanes
Place step circles by proportional position in the bar (beat = column start) instead
of centring in per-lane slots, so same-meter lanes' beats land at the same x (e.g. the
8-step hat's beats sit directly under the 4-step kick/snare). Cap circle radius at 6
(was up to ~18). Verified by printing per-lane beat x-positions + rendering the grid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:16:36 -05:00
Me Here
c34d37d9c6 Bump version to 0.0.58 2026-05-28 22:07:00 -05:00
Me Here
ec43c694a1 PM_K-1 CircuitPython: circle pad grid, small labels, dimmer LED, faster SPI
From on-board feedback (works well; minor tweaks):
  - Pad grid uses circles now: big circle on each beat (division), small on the
    subdivisions (vectorio.Circle — native, no extra cost), coloured/lit as before.
  - Lane labels use a new small font (font_s.bin, ~12px via gen_font.py) so they're
    half-size and show more of the voice name (e.g. 'hatClos').
  - LED was blinding -> LED_BRIGHTNESS scale (default 0.15) applied on every write.
  - Residual tearing -> SPI back to 62.5 MHz (vendor speed; smaller tear window on a
    panel with no tearing-effect pin). Both are CONFIG flags.
Verified by rendering the full scene headless. font_s.bin added to gen_font.py + bundle.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:07:00 -05:00
Me Here
6421e525da Bump version to 0.0.57 2026-05-28 21:56:27 -05:00
Me Here
c499910df4 PM_K-1 CircuitPython: add the lanes/pads view
Replace the single beat-dot row with a full pad grid: each lane is a row of step
pads coloured by dynamics (mute/normal/accent/ghost), with the playhead lit as it
plays (per-lane, so polymeter shows). Header (title/BPM/RUN/item) is compacted above
it; transport stays below. Pads are vectorio rects sharing one 8-colour palette and
recolour in place via color_index (cheap, tear-free); the grid only rebuilds on track
change. Caps at MAXLANES=5 rows (extra lanes still play). Verified by rendering the whole
displayio scene graph headless (layout + playhead lighting correct).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:56:27 -05:00
Me Here
47c19dea8c Bump version to 0.0.56 2026-05-28 21:43:48 -05:00
Me Here
ffededd05b PM_K-1 CircuitPython: self-contained RGB LED + fix screen tearing
From on-board feedback (memory + colours now good):
  - LED: drive the WS2812 via the core neopixel_write module (no neopixel library to
    install) — a tiny RGB class. Self-contained: it works straight from the bundle.
  - Tearing: switch displayio to auto_refresh=False and push a complete frame only when
    the scene changed (dirty flag, capped at the panel's refresh rate) so updates are
    never shown mid-paint. Beat dots now recolour in place (vectorio color_index) instead
    of being rebuilt every beat, shrinking the dirty region.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:43:48 -05:00
Me Here
365d242339 Bump version to 0.0.55 2026-05-28 21:30:03 -05:00
Me Here
111da49b5a PM_K-1 CircuitPython: fix MemoryError + red/blue swap (from on-board test)
On hardware the app rendered, beeped and took input, then died with MemoryError at
the text Bitmap alloc — the two ~37KB base64 font strings stayed pinned in RAM. Move
the fonts to small binary files read at boot (font_m.bin / font_l.bin), drop the
base64 + binascii, and gc.collect() before each text bitmap. code.py 56KB -> 20KB and
RAM use drops ~37KB+. Also: cyan rendered as yellow (R/B swapped) -> MADCTL 0x40 -> 0x48.
Bundle + README updated to include the font blobs. (LED still needs the neopixel lib.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:30:03 -05:00
Me Here
2c40baec58 Bump version to 0.0.54 2026-05-28 21:10:34 -05:00
Me Here
b419ad0daa Phase 1: CircuitPython firmware (USB-drive edition) for the Kit
New pico-cp/ — a CircuitPython port of the PM_K-1 firmware so the Pico mounts as a
CIRCUITPY drive carrying its code + tracks (the MicroPython pico/main.py stays the
simple fallback):
  - pico-cp/code.py: displayio BusDisplay driving ST7796 via a custom init_sequence;
    smooth anti-aliased text via displayio Bitmap+Palette (reuses the baked font blobs);
    vectorio rects for dots/buttons; DIY GT911 touch (16-bit regs, edge-detected);
    pwmio buzzer, analogio joystick, digitalio buttons, optional neopixel RGB; the
    polymeter engine on a time.monotonic_ns scheduler. Reads /programs.json (falls back
    to baked defaults); CircuitPython auto-reloads on file change.
  - pico-cp/programs.json: the 23 default grooves. pico-cp/README.md: flash + calibrate.
  - build.sh/deploy.sh: bundle + serve /pm_k1_circuitpy.zip. info-kit.html: experimental
    'CircuitPython edition — USB drive' section.

Verified in CPython (stubbed displayio): init sequence well-formed, parser handles the
grooves incl. (3,8) euclid + @-4 gain, and code.py's actual make_text renders identical
smooth AA text. Hardware bits (panel/touch/MIDI) await on-board testing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:10:34 -05:00
Me Here
656eab53dd Bump version to 0.0.53 2026-05-28 21:01:40 -05:00
Me Here
5fc962f0c4 Phase 0: refresh README to current state; add 'kit' embed variant
README was stale (pre-dating several shipped changes). Rewrite it to match reality:
  - voices are all synthesized now (KIT_ALIAS -> 808/909); drop the VCSL samples
    narrative, the @BUILD:samples wording, and the sample credits.
  - document the lean-widget + separate info-<device>.html page model (was 'Open=Info').
  - add kit.html + all info-*.html to the Pages table; add the new src/ partials
    (header/footer/chrome/progbox/infoembed), pico/ firmware, and pico-main.py to Files/Build.
  - document the share-grammar additions: GM note numbers, Euclidean (k,n[,rot]), per-lane @<db> gain.
  - add a 'Build it (hardware)' section for the PM_K-1 Kit + MicroPython firmware.

embed.js: add the 'kit' form factor to the variant map (it previously fell back to micro),
so data-varasys-metronome="kit" embeds kit.html as the README now documents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:01:40 -05:00
Me Here
1afa56b078 Bump version to 0.0.52 2026-05-28 17:11:30 -05:00
Me Here
df6e70473c PM_K-1 firmware: smooth AA fonts, full set list, LED-off-on-stop, touch edge-detect
Four firmware improvements (web simulator already had these):
  - Smooth lettering: replace the upscaled 8x8 bitmap font (and the 7-seg BPM) with
    baked anti-aliased proportional fonts (DejaVuSans-Bold 22 + 78), rendered by
    blending fg over bg through a 16-entry alpha LUT. Generator: pico/gen_font.py.
  - All grooves: PROGRAMS now carries the full web set list (23 grooves), not 5.
  - Fix: the RGB LED stayed lit when stopped — the stop path now zeroes the colour
    and the fade only runs while playing (led_off()).
  - Fix: the on-screen play button played one beep then stopped — a finger held past
    the old lockout re-fired the toggle. Touch is now edge-detected like the hardware
    buttons (fires once on finger-down, ignores held).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 17:11:30 -05:00
Me Here
f34f7291de Bump version to 0.0.51 2026-05-28 16:42:18 -05:00
Me Here
111702222b PM_K-1 docs: make the two-step flash explicit (main.py is not drag-and-drop)
A user dropped main.py onto the RPI-RP2 BOOTSEL drive (which only accepts a .uf2)
and it vanished on reboot. Clarify in pico/README.md and info-kit.html that
flashing is two distinct steps: (1) drag-and-drop the MicroPython .uf2, then
(2) copy main.py over USB serial with Thonny/mpremote — the Pico is not a USB
drive once MicroPython is running.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:42:18 -05:00
Me Here
8e5a725aba Bump version to 0.0.50 2026-05-28 16:19:15 -05:00
Me Here
fe56673bea PM_K-1: drop the VARASYS wordmark from the screen UI (it's on the case)
The on-screen header showed VARASYS + the model; since the wordmark is already
silkscreened on the case/PCB, keep only the PM_K-1 KIT label on the display.
Applied to both pico/main.py (draw_static) and the kit.html web simulator.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:19:08 -05:00
Me Here
2c2a3adcd7 Bump version to 0.0.49 2026-05-28 16:10:36 -05:00
Me Here
eecea625d3 Add PM_K-1 "Kit" — buildable Pico touchscreen unit + MicroPython firmware
A new, first-actually-buildable form factor for the 52Pi EP-0172 "Pico Breadboard
Kit Plus" (Raspberry Pi Pico; 3.5" ST7796 320x480 cap-touch via GT911, PSP
joystick on ADC0/1, WS2812 RGB on GP12, buzzer GP13, buttons GP14/15):

  - pico/main.py — one self-contained MicroPython file: ST7796 direct-draw driver,
    GT911 touch (16-bit register addressing), WS2812 RGB (neopixel), PWM buzzer,
    ADC joystick, buttons. It parses the project's own program-string language
    (verified against the web engine's semantics) and runs a non-blocking
    ticks_us scheduler with an on-screen touch UI. CONFIG flags cover panel /
    colour / touch / joystick calibration. pico/README.md has flashing +
    calibration steps.
  - kit.html — lean widget that mirrors the firmware's on-screen UI (portrait
    320x480 canvas) plus a joystick / RGB / buzzer / A-B buttons; plays via the
    shared engine. info-kit.html — the real EP-0172 pinout, a parts list
    (~$45 incl. Pico) and the firmware to flash (downloads /pico-main.py, links
    the README + source).
  - Landing + embed page list the Kit; build.sh/deploy.sh build the two pages and
    serve pico/main.py as /pico-main.py for download.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:10:31 -05:00
Me Here
ee412bad04 Bump version to 0.0.48 2026-05-28 14:18:42 -05:00
Me Here
9e5c79b3b2 Split each form factor into a lean widget page + a separate info page
Previously every device .html bundled its full narrative (purpose, BOM,
dimensioned drawings, embedding docs) inside a #techinfo block that embed
mode (?embed=1) only CSS-hid — so every embedder and every landing-page
iframe downloaded all of it (showcase 77%, teacher 49% of the file) for
content no embedder ever sees.

Now:
  - <device>.html is the lean widget only: header + front view/controls +
    title + summary + program box. ?embed=1 still collapses to the bare
    widget; the heavy narrative is gone from the payload.
  - info-<device>.html (new, one per form factor) carries all the words —
    purpose, dimensions, priced BOM, embedding docs — and embeds the live
    widget at the top via the existing iframe + auto-resize protocol
    (new shared src/infoembed.html + src/infoembed.js).
  - Each device links out to its info page ("…dimensions & BOM →"); the
    landing panes and viewport bar now offer both Open ↗ and Specs & info ⓘ.
  - Dropped the now-dead "Show info" toggle (CSS + progbox.js).

Branding: adopt the official VARASYS "tagline on the bottom" logos from the
brand kit (light-background variant now matches; dark already did). The
tagline is baked into the PNGs, so remove the CSS .brand-tag / .dev-tag
spans and the showcase canvas-drawn tagline. Brand cyan #0AB3F7 / navy
#1C283F already match the official palette.

build.sh / deploy.sh: build + deploy the six new info-*.html pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 14:18:23 -05:00
Me Here
f622e58a49 Bump version to 0.0.47 2026-05-28 12:48:44 -05:00
Me Here
dc936fdc11 Proper VARASYS logo (wordmark + tagline) everywhere; embed defaults to the set lists
Logos: the brand is now a consistent lockup — wordmark image + a crisp CSS
"Simplifying Complexity" tagline — in the shared header, device silkscreens
(teacher/stage/micro), the player (was a CSS text box) and the showcase canvas
(was drawn text; now the real logo image + tagline). Cropped the baked tagline
out of logo-light.b64 so both themes render the tagline once. Renamed device
silk logos to .dev-logo so they no longer shrink the shared header logo.

Embeds: every form factor now loads its default set lists when embedded with no
config — and the Concepts landing embeds them that way (viewport loads
<device>?embed=1 with no forced #p=; the program box reflects what the device
reports and only overrides on explicit Load).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 12:48:44 -05:00
Me Here
18eed37d97 Bump version to 0.0.46 2026-05-28 11:55:12 -05:00
Me Here
1faf9cad41 Embed version dropdown; Display weight static/behind lights; Practice beat flash; move Philosophy up
- Embed page: a form-factor dropdown that rewrites every snippet (drop-in +
  plain iframe), the live demo, and the name for the chosen version; variant
  table completed to all six.
- Display (Showcase): the tempo weight no longer flashes and is drawn BEHIND the
  pendulum lights so it never hides a beat flash.
- Practice (Micro): a beat/sub-beat flash — the whole 14-seg display washes amber
  on each step (subtle on sub-beats, brighter on the beat, full on the "1"),
  latency-compensated like the other devices.
- Landing: Philosophy section moved above "Pick a form factor".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:55:12 -05:00
Me Here
36cff77219 Bump version to 0.0.45 2026-05-28 11:41:21 -05:00
Me Here
2e8b693208 Dimensioned drawings for Stage/Practice/Display; fix "Show info" toggle timing
- Add front + top/side dimensioned schematic views (inch + mm) inside the
  "Show info" section of Stage (front + top-edge I/O), Practice (front bar +
  both end faces), and Display (pyramid front + side profile). Shared .dview /
  .dschem CSS in base.css.
- Fix: progbox.js now defers to DOM-ready, so the "Show info" toggle + #techinfo
  are wired even when they sit after the page script (Stage/Practice/Player were
  silently not toggling / ignoring ?info=1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:41:21 -05:00
Me Here
b6e9fed426 Bump version to 0.0.44 2026-05-28 11:26:49 -05:00
Me Here
5a805a292b Phase D — naming rollout: PM_x-1 purpose codes
Visible names/codes updated across all pages, the landing panes, device silk
labels, the Showcase canvas legend, and the README:
  PM_E-1 Editor · PM_T-1 Teacher · PM_S-1 Stage · PM_P-1 Practice (was Micro) ·
  PM_D-1 Display (was Showcase) · PM_C-1 Concept (was Initial).
Filenames/URLs and embed variant keys are kept as-is for backward compatibility
(existing links and embeds keep working).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:26:49 -05:00
Me Here
295f838258 Bump version to 0.0.43 2026-05-28 11:22:23 -05:00
Me Here
f1146e720a Phase C — per-page plain/info split + per-device program box
Each form-factor page is now plain by default: title + summary + the front view +
a program I/O box (shared src/progbox.* — paste a patch OR a base64 set-list code,
decoded + linted + loaded; copy; reflects the device state and posts it to an
embedding parent). All technical content — description, BOM, dimensions, top/side
views, embedding — hidden behind a "Show technical info" checkbox; ?info=1 opens it
checked. Teacher's top-edge view + dimensions are marked .tech so they hide too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 11:22:23 -05:00
Me Here
271abfe43a Bump version to 0.0.42 2026-05-28 10:58:19 -05:00
Me Here
31111abbcb Phase B — landing rebuild + editor program I/O + per-lane dB knob
Editor: per-lane gain knob (drag/scroll/double-click, dB, applied at schedule
time — no stutter); program box now decodes base64 set-list codes + lints
(clear ✓/✗ message). When embedded it posts its program to the parent.

Landing (Concepts) rebuilt to the spec: description first, the EDITOR open by
default in a live viewport, a summary pane per form factor (click loads it into
the viewport), and a program I/O box that shows the current program decoded (not
base64), accepts plain text OR a base64 set-list code, lints it, loads it into
the viewport, and copies it. Viewport auto-sizes + reflects the device's posted
program. Engine codec inlined for decode/lint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:58:19 -05:00
Me Here
c0bf81c3fc Bump version to 0.0.41 2026-05-28 10:33:56 -05:00
Me Here
4babd1f4ef Phase A — engine v2: drop samples, add conventions + per-lane dB gain
- Remove the VCSL sample kit entirely (editor 351K → 141K). All voices are
  synthesized; the friendly GM names now alias to the punchier 808/909 renders
  (KIT_ALIAS). build.sh drops the @BUILD:samples inlining; assets/samples.json gone.
- Conventions (backward-compatible): GM note-number aliases (36=kick…), '-'/'_'
  rest aliases in step patterns, Euclidean (k,n[,rot]) shorthand.
- Per-lane gain in dB (@<db> in the grammar) applied as a velocity multiplier at
  schedule time — no stutter; threaded through every host's buildMeters + the
  editor's lanes (knob UI comes in Phase B).
- 15/15 engine round-trip tests pass; pages console-clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:33:56 -05:00