No description
Find a file
Me Here 1f957b7630 Update README: fix stale claims found in code review
- Drop the false "vendored QR library" line; state it's a single
  self-contained, zero-dependency file and document offline use.
- Fix keyboard shortcuts to match the in-app help: remove the
  non-existent R toggle, add Alt+↑/↓ (reorder), 1–9 toggles a lane.
- "GM drum voice" → synthesized; set-list items load on click (no ▶
  auto-start); QR is an external service; clarify release.sh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:05:34 -05:00
deploy.sh Per-lane enable (replacing mute), feature boxes, set-list continue mode, external QR 2026-05-24 18:47:16 -05:00
index.html Add VARASYS logo to header 2026-05-25 08:43:21 -05:00
LICENSE Add GNU AGPL v3 license 2026-05-25 08:33:40 -05:00
README.md Update README: fix stale claims found in code review 2026-05-25 09:05:34 -05:00
release.sh Add versioning: VERSION file, dev/formal stamping, release.sh 2026-05-24 16:59:31 -05:00
VERSION Add versioning: VERSION file, dev/formal stamping, release.sh 2026-05-24 16:59:31 -05:00

Stackable Metronome

A browser polymetric groove trainer / metronome — and the design mockup for a Raspberry Pi Pico hardware build. Stack as many "meter lanes" as you like; each is its own little metronome with a grouping, subdivision, drum voice and per-beat pattern. Layering lanes produces polymeter and true ratio polyrhythm.

Live: https://metronome.varasys.io

It's a single, selfcontained index.htmlzero dependencies: no framework, no build step, no bundled or CDN libraries, and nothing fetched at runtime. State (set lists, the practice log, theme and UI preferences) lives in localStorage.

Because nothing loads from the network, you can save the page (Ctrl/+S) and open it straight from disk to run fully offline. One catch from a local file://: the browser may not persist localStorage between sessions, so use Export all (setlist menu) to back up your work.

Features

  • Meter lanes — grouping (odd meters), subdivision, a synthesized drum/percussion voice, perbeat on/off pattern (rests), mute, live measure counter.
  • Polyrhythm — a perlane poly toggle fits a lane's beats evenly into lane 1's bar (e.g. 5over4, 3over2).
  • Practice — gap/mute trainer (play N / mute M bars) and a tempo ramp with a start BPM and signed step.
  • Set lists — named, ordered lists of saved setups; click an item to load it (it switches live if you're already playing), N loads the next; each play is logged for crossday comparison.
  • Sharing — copy a link to your current settings or a whole set list (with an optional QR generated by an external service).
  • Theming — System / Light / Dark.

The share language

A compact, humanreadable text encodes a full configuration (a patch). It's what goes in a share link, and you can handwrite or edit it.

Patch grammar

v1 ; t<bpm> [; vol<pct>] ; <lane> ; <lane> … [; tr<play>/<mute>] [; rmp<start>/<step>/<every>]
Token Meaning Example
v1 format version (always first) v1
t<bpm> tempo t120
vol<pct> master volume 0100 vol70
tr<play>/<mute> gap trainer: play N bars, mute M tr2/2
rmp<start>/<step>/<every> tempo ramp: start BPM, ±step, every N bars rmp80/5/4
<lane> a meter lane (see below) kick:4

Tokens are joined with ;. tr and rmp are omitted when off.

Lane grammar

<sound> : <grouping> [ / <sub> ] [ = <pattern> ] [ ~ ] [ ! ]
  • sound — one of: beep, kick, snare, rim, clap, hatClosed, hatOpen, ride, crash, tomLow, tomMid, tomHigh, tambourine, cowbell, woodblock, claves, jamblock (unknown → beep).
  • grouping — beats per bar, optionally grouped for odd meters: 4, 3, 2+2+3. The first beat of each group is accented.
  • /sub — subdivision: 1 quarter (default), 2 eighth, 3 triplet, 4 sixteenth, 6 sextuplet. This also sets how many pads each beat splits into (a beat becomes sub individuallytoggleable steps). Omit for quarter.
  • =pattern — perstep on/off as x/., length = beats per bar × sub (one char per pad). Omit = all on. e.g. 4=.x.x is a backbeat on 2 & 4; 4/4=x..x..x.x...x... is a sixteenthgrid pattern. A short pattern whose length equals just the beat count is still accepted and expanded across each beat's subdivisions (backcompat).
  • ~ — polyrhythm: fit this lane's beats evenly into lane 1's bar.
  • ! — mute the lane.

Examples

Patch / lane What it is
kick:4 kick on 4 quarter beats
snare:4=.x.x snare backbeat (2 & 4)
hatClosed:4/2 eighthnote hihats
claves:5~ 5 evenly across lane 1's bar (5over4 if lane 1 is 4)
kick:2+2+3=x..x..x 7/8, kick on each group start
cowbell:3+2/2 5/4 grouped 3+2, eighth subdivision
Full: v1;t120;kick:4;snare:4=.x.x;hatClosed:4/2;tr2/2 backbeat groove with gap trainer

In URLs

  • Settings: …/#p=<patch> — readable, e.g. …/#p=v1;t120;kick:4;claves:5~
  • Set list: …/#sl=<base64url> — a JSON {title, description, items[]} where each item's config is a patch string. Used because titles/notes are free text.

Opening such a link applies the settings (or imports the set list) on load, then clears the hash so a refresh won't reimport.

Sharing

In the setlist panel's menu:

  • Share settings link / Share setlist link open a dialog with the link to Copy or Open.
  • QR ↗ opens a thirdparty QR service (api.qrserver.com) with the link in its URL so you can scan it on a phone. A banner warns you it's external — confirm the QR decodes to the shown link before trusting it. (No QR is generated locally.)
  • Export all / Import file back up your set lists and practice log as a JSON file (a legacy presets field is included for backward compatibility).

Keyboard shortcuts

Key Action
Space play / stop (works everywhere except while typing in a text field)
T tap tempo
/ tempo ±1 (Shift = ±10)
A add meter lane
N load next setlist item
Alt+ / Alt+ reorder the selected setlist item
19 enable / silence lane 19
? shortcuts help
Esc close the help / share dialog

(Arrow keys are left alone while a slider or dropdown is focused, so they still adjust it.)

Versioning

VERSION holds the formal version. deploy.sh stamps the served page:

  • Formal — a clean commit tagged v<VERSION>X.Y.Z.
  • Dev — anything else → X.Y.Z-dev.<utc-timestamp>.<short-sha>[.dirty].

Cut a release with ./release.sh [X.Y.Z] — the optional arg bumps & commits VERSION; it then tags the current commit v<VERSION> (requires a clean tree). Push the tag, then deploy.

Deploy

./deploy.sh copies index.html (versionstamped) into the Caddy web root and smoketests the live URL. No restart needed (file_server picks up changes immediately).

Files

File Purpose
index.html the whole app
deploy.sh publish to the Caddy web root
release.sh tag a formal version
VERSION formal version string
LICENSE GNU AGPL v3 license text

License

Copyright (C) 2026 Varasys.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE for the full text.

Because the app is served over a network, the AGPL's §13 applies: anyone interacting with a hosted instance must be able to get its source. The repo link in the inapp ? help satisfies this.