No description
Find a file
Me Here 3e70eadea7 As-built: add on-page bill of materials; confirm analog click-injection
- Add a costed BOM panel below the loader, grouped by subsystem (brain &
  display, beat bar, controls, audio—analog click injection, connectors &
  power, build) with quantities and ballpark prices (~$61 one-off).
- Reflect the confirmed analog mixing in the audio path / comment: PCM5102A
  click DAC → summing op-amp (NE5532/OPA2134) with a hi-Z instrument buffer →
  balanced line driver (DRV134) to the shared 1/4" TRS out, plus a PAM8302A
  monitor amp + speaker — the instrument is never re-digitised (no latency).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 07:42:38 -05:00
assets Add build step (inline assets at build); drop "mockup" from the main app 2026-05-25 15:21:28 -05:00
src Share engine, seed set lists & base CSS between editor and player 2026-05-25 15:49:35 -05:00
.gitignore Add build step (inline assets at build); drop "mockup" from the main app 2026-05-25 15:21:28 -05:00
build.sh Add "as-built" player variant: mono 128×64 OLED + 16-px WS2812 beat bar 2026-05-26 06:57:57 -05:00
deploy.sh Add "as-built" player variant: mono 128×64 OLED + 16-px WS2812 beat bar 2026-05-26 06:57:57 -05:00
index.html Share engine, seed set lists & base CSS between editor and player 2026-05-25 15:49:35 -05:00
LICENSE Add GNU AGPL v3 license 2026-05-25 08:33:40 -05:00
player-asbuilt.html As-built: add on-page bill of materials; confirm analog click-injection 2026-05-26 07:42:38 -05:00
player.html Add "as-built" player variant: mono 128×64 OLED + 16-px WS2812 beat bar 2026-05-26 06:57:57 -05:00
README.md Share engine, seed set lists & base CSS between editor and player 2026-05-25 15:49:35 -05:00
release.sh Add versioning: VERSION file, dev/formal stamping, release.sh 2026-05-24 16:59:31 -05:00
VERSION Bump version to 0.0.18 2026-05-26 07:34:40 -05:00

Stackable Metronome

A browser polymetric groove trainer / metronome — a full web app, and the reference design for a Raspberry Pi Pico hardware build (whose playonly device is mocked up at player.html). Stack as many "meter lanes" as you like; each is its own little metronome with a grouping, subdivision, drum voice and a perstep pattern with accents. Layering lanes produces polymeter and true ratio polyrhythm.

Live: https://metronome.varasys.io · Source: https://codeberg.org/VARASYS/metronome

The deployed page is a single, selfcontained index.htmlzero dependencies: no framework, no CDN libraries, nothing fetched at runtime. It's assembled by a small build step (build.sh) that inlines the audio samples + brand assets (kept in assets/) into the HTML, so the source stays lean. 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 (incl. swing), a drum/percussion voice, perstep dynamics (accent / normal / ghost / mute), mute, live measure counter.
  • Sounds — a sampled acoustic kit plus synthesized 808 / 909 and electronic voices; click each pad to set its dynamics; pick a swing subdivision for a triplet feel.
  • 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; cue across lists and commit on a bar/beat boundary with no audible gap (see Live performance); each play is logged for crossday comparison.
  • Sharing — copy a link to your current settings or a whole set list.
  • 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>] [; cd<sec>] [; b<bars>] ; <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
cd<sec> time countdown, seconds (auto-advance with Continue) cd60
b<bars> segment length in bars (auto-advance with Continue) b16
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 — the acoustic kit: beep, kick, snare, rim, clap, hatClosed, hatOpen, ride, crash, tomLow, tomMid, tomHigh, tambourine, cowbell, woodblock, claves, jamblock (kick, snare, closedhat, crash, toms, tambourine, cowbell, woodblock and claves play embedded CC0 samples; beep, clap, rim, hatOpen and ride stay synthesized — VCSL has no clean source for those); plus synthesized drum machines — kick808 snare808 clap808 hat808 openHat808 cowbell808 tom808 and kick909 snare909 clap909 hat909 ride909 crash909. Unknown → beep.
  • grouping — beats per bar, optionally grouped for odd meters: 4, 3, 2+2+3. Groups get a visual divider; accents are perstep (see =pattern).
  • /sub — subdivision: 1 quarter (default), 2 eighth, 3 triplet, 4 sixteenth, 6 sextuplet. This also sets how many pads each beat splits into. Append s for swing on even subdivisions — 2s (swung eighths) or 4s (swung sixteenths) delay the offbeats to a triplet (2:1) feel. Omit for quarter.
  • =pattern — perstep dynamics, one char per pad: X accent, x normal, g ghost (soft), . mute (rest). Length = beats per bar × sub. Omit to get the default — the first step of each beat accented, the rest normal (click a pad in the UI to cycle accent → normal → ghost → mute). e.g. 4=.X.X accents the backbeat (2 & 4); 4/2s is swung eighths with the default accents. (Legacy x/. on/off patterns and short beatcount patterns still parse.)
  • ~ — 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 accented snare backbeat (2 & 4)
hatClosed:4/2 eighthnote hihats (downbeat of each beat accented)
ride:4/2s swung eighthnote ride
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. The link encodes everything in the URL — nothing is uploaded.
  • 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
/ / Home / End move the cue cursor (crosses set lists)
PgUp / PgDn cue the previous / next set list
Enter commit the cued item — switches on the next bar (smooth)
Shift+Enter commit now — switches on the next beat (rude)
N / P load next / previous immediately (rude quickstep)
Alt+ / Alt+ reorder the cued item
19 enable / silence lane 19
? shortcuts help
Esc close the help / share dialog · cancel an armed switch

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

Live performance

The set list is performance-ready: you can line up where you're going next without disturbing what's playing, then commit on a musical boundary — no audible gap.

  • Cue, then commit. The arrows / Home / End / PgUp / PgDn move a cue cursor (amber outline) through items — across set lists, without loading anything. Enter commits the cued item with a smooth cutover at the next bar; Shift+Enter is a rude cutover at the next beat ("wrong thing playing, fix it now"). N / P are immediate rude quicksteps. Esc cancels an armed switch.
  • Barlength segments. Give an item a bar count (Timers box, or the b<n> patch token) and a bar countdown (▦) shows bars remaining. With Continue on, it autoadvances to the next item at the bar boundary — so a song is just a set list of segments (each with its own tempo, ramp and bar length) that hand off seamlessly.
  • All transitions — manual or auto, beat or bar — keep the clock continuous; the loaded item can even live in a set list you're not currently viewing (the player names it).

Build

index.html (the editor) and player.html (the hardwareplayer mockup) are both sources that share code through @BUILD:* markers, so the two stay in sync:

  • /*@BUILD:include:src/…@*/ inlines a shared partial — the audio/scheduler engine (src/engine.js), the seed set lists (src/setlists.js, so the player ships the same default set lists as the editor), and base styling (src/base.css: reset + brand palette + type).
  • @BUILD:favicon@, @BUILD:logo-*@, /*@BUILD:samples@*/{} inline the base64 assets from assets/.

./build.sh resolves every marker into a selfcontained dist/index.html + dist/player.html (the editor inlines the CC0 samples; the player passes an empty SAMPLES for pure synth). dist/ is generated, gitignored — don't edit it by hand. deploy.sh runs the build first, so a deploy always serves freshly assembled pages.

Versioning

VERSION holds the formal version. deploy.sh builds, then 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.

Files

File Purpose
index.html the editor app (source, with @BUILD:* markers)
player.html the playonly hardwaredevice mockup (/player.html)
src/ shared partials inlined into both: engine.js, setlists.js, base.css
assets/ base64 blobs inlined at build (samples, logos, favicon)
build.sh resolve markers → selfcontained dist/ pages
deploy.sh build, then 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 public repository is https://codeberg.org/VARASYS/metronome (also linked from the inapp ? help).

Credits

Acoustic drum oneshots are from the Versilian Community Sample Library (VCSL), released under CC0 (public domain) — trimmed and downsampled, embedded inline. The 808/909 voices and the electronic/percussion sounds are synthesized in Web Audio (no samples).