# VARASYS PolyMeter A small **website** built around one **polymetric groove trainer / metronome** engine. A landing page is the front door; the main app is the **PM_E‑1 PolyMeter Editor** — a full web app where you stack as many "meter lanes" as you like, each its own little metronome with a grouping, subdivision, drum voice and a per‑step pattern with accents. Layering lanes produces polymeter and true ratio polyrhythm. The same engine drives an ever‑expanding library of **form‑factor concepts** (idealized and buildable hardware mockups), ships as an **embeddable widget** anyone can drop into their own page, and even runs as **firmware** on a real Raspberry Pi Pico build (the **PM_K‑1 Kit**). **Live:** https://metronome.varasys.io · **Source:** https://codeberg.org/VARASYS/metronome Every **deployed page is a single, self‑contained `.html` file** — **zero dependencies**: no framework, no CDN libraries, nothing fetched at runtime. They're assembled by a small build step (`build.sh`) that inlines a shared engine, the seed set lists, base styling and the brand assets (kept in `assets/`) into each page, so the sources stay lean. Every voice is **synthesized** in Web Audio — there are no audio samples to load. State (set lists, the practice log, theme and UI preferences) lives in `localStorage`. ## Pages The site is **one editor + a gallery of form factors**, and each form factor is split into a **lean widget page** and a **separate info page**: - **`.html`** — just the live widget (front view, controls, program box). This is what `?embed=1` serves and what the landing embeds; it never ships the BOM/narrative. - **`info-.html`** — the spec page: it embeds the live widget at the top, then the description, dimensioned drawings and a priced **Bill of Materials** (for the buildable hardware). | URL | What | |-----|------| | [`/`](https://metronome.varasys.io/) `index.html` | **Concepts** — the landing / form‑factor gallery; each box embeds the live widget (Open ↗ / Specs & info ⓘ) | | `/editor.html` · `/info-editor.html` | **PM_E‑1 — PolyMeter Editor** (the main app) + its overview | | `/pm_e-2.html` · `/info-pm_e-2.html` | **PM_E‑2 — PolyMeter Editor (Notation)** — second-gen, engraved drum notation (Bravura/SMuFL): Staff / TUBS / Konnakol views, edit-on-staff | | `/kit.html` · `/info-kit.html` | **PM_K‑1 Kit** — buildable Raspberry Pi Pico touchscreen unit (52Pi EP‑0172); info page has the wiring, parts and firmware | | `/player.html` · `/info-player.html` | **PM_C‑1 Concept** — idealized concept device (full display + set‑list nav, theme, fullscreen "stage" view) | | `/teacher.html` · `/info-teacher.html` | **PM_T‑1 Teacher** — studio / lesson console (colour TFT, arcade buttons, 1/4″ instrument pass‑through with analog click injection) | | `/stage.html` · `/info-stage.html` | **PM_S‑1 Stage** — foot‑pedal stompbox (two footswitches, expression‑pedal in, RGB beat light, instrument pass‑through) | | `/micro.html` · `/info-micro.html` | **PM_P‑1 Practice** — inline practice bar (instrument in / out pass‑through, clickable thumb‑roller, 14‑segment display) | | `/showcase.html` · `/info-showcase.html` | **PM_D‑1 Display** — pyramid display piece; the pendulum is an RGB light bar combining every lane's subdivisions/accents | | `/embed.html` · `/embed.js` | embed docs and the drop‑in loader | | `/pico-main.py` | the PM_K‑1 MicroPython firmware (download) | The buildable units (Teacher, Stage, Practice, Display, Kit) carry a priced BOM on their info page; the Editor (web app) and Concept have none. Every page shares the same VARASYS header (official logo with baked‑in tagline, nav, theme toggle). The editor also shows a subtle live **program string** of what's loaded — editable, with copy/paste — under the app (press `Enter` or paste to apply; see [the share language](#the-share-language)). Because nothing loads from the network, you can save a 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** (set‑list **⋯** menu) to back up. ## Features - **Meter lanes** — grouping (odd meters), subdivision (incl. swing), a drum/percussion voice, per‑**step dynamics** (accent / normal / ghost / mute), mute, live measure counter. - **Sounds** — every voice is **synthesized** in Web Audio: a friendly drum kit (`kick`, `snare`, `hatClosed`, …) rendered with the **808 / 909** voices, the 808/909 voices by name, and electronic/percussion tones. No samples are loaded. - **Per‑lane gain** — a dB trim knob per lane (`@` in the share language), applied at schedule time so changing it never stutters playback. - **Polyrhythm** — a per‑lane *poly* toggle fits a lane's beats evenly into lane 1's bar (e.g. 5‑over‑4, 3‑over‑2). - **Euclidean rhythms** — spread *k* hits evenly across *n* steps with `(k,n[,rot])`. - **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. - **Sharing** — copy a link to your current settings or a whole set list. - **Theming** — System / Light / Dark. ## The share language A compact, human‑readable text encodes a full configuration (a *patch*). It's what goes in a share link, the editor's program box, and a device's program list. You can hand‑write or edit it. ### Patch grammar ``` v1 ; t [; vol] [; cd] [; b] ; … [; tr/] [; rmp//] ``` | Token | Meaning | Example | |-------|---------|---------| | `v1` | format version (always first) | `v1` | | `t` | tempo | `t120` | | `vol` | master volume 0–100 | `vol70` | | `cd` | time countdown, seconds (auto-advance with Continue) | `cd60` | | `b` | segment length in bars (auto-advance with Continue) | `b16` | | `tr/` | gap trainer: play N bars, mute M | `tr2/2` | | `rmp//` | tempo ramp: start BPM, ±step, every N bars | `rmp80/5/4` | | `` | a meter lane (see below) | `kick:4` | Tokens are joined with `;`. `tr` and `rmp` are omitted when off. ### Lane grammar ``` : [ / ] [ (,[,]) ] [ = ] [ @ ] [ ~ ] [ ! ] ``` - **sound** — a synthesized voice. Friendly kit names (rendered with 808/909): `beep`, `kick`, `snare`, `rim`, `clap`, `hatClosed`, `hatOpen`, `ride`, `crash`, `tomLow`, `tomMid`, `tomHigh`, `tambourine`, `cowbell`, `woodblock`, `claves`; the drum‑machine voices by name — `kick808 snare808 clap808 hat808 openHat808 cowbell808 tom808` and `kick909 snare909 clap909 hat909 ride909 crash909`; or a **General‑MIDI note number** (`36`→kick, `38`→snare, `42`→closed hat, …). Unknown → `beep`. - **grouping** — beats per bar, optionally grouped for odd meters: `4`, `3`, `2+2+3`. Groups get a visual divider; accents are per‑step (see `=pattern`). - **`/sub`** — subdivision: `1` quarter (default), `2` eighth, `3` triplet, `4` sixteenth, `6` sextuplet — also sets how many **pads** each beat splits into. Append **`s`** for **swing** on even subdivisions (`2s`, `4s`) to delay the off‑beats to a 2:1 triplet feel. - **`(k,n[,rot])`** — **Euclidean** fill: place `k` hits as evenly as possible across `n` steps, optionally rotated by `rot`. e.g. `kick:4(3,8)`. - **`=pattern`** — per‑**step dynamics**, one char per pad: **`X`** accent, **`x`** normal, **`g`** ghost (soft), **`.`** `-` `_` mute (rest). Length = beats × `sub`. Omit to get the default — first step of each beat accented, the rest normal. e.g. `4=.X.X` accents 2 & 4. - **`@`** — per‑lane gain trim in decibels, e.g. `@-3` or `@+2`. - **`~`** — 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` | eighth‑note hi‑hats (downbeat of each beat accented) | | `ride:4/2s` | **swung** eighth‑note ride | | `kick:4(3,8)` | a 3‑over‑8 Euclidean kick | | `claves:5~` | 5 evenly across lane 1's bar (5‑over‑4 if lane 1 is `4`) | | `hat909:4/2@-4` | eighth 909 hats, trimmed −4 dB | | `kick:2+2+3=x..x..x` | 7/8, kick on each group start | | **Full:** `v1;t120;kick:4;snare:4=.x.x;hatClosed:4/2;tr2/2` | backbeat groove with gap trainer | ### In URLs - **Settings:** `…/#p=` — readable, e.g. `…/#p=v1;t120;kick:4;claves:5~` - **Set list:** `…/#sl=` — a JSON `{title, description, items[]}` where each item's config is a patch string. Opening such a link applies the settings (or imports the set list) on load, then clears the hash so a refresh won't re‑import. ## Sharing In the set‑list panel's **⋯** menu: - **Share settings link** / **Share set‑list 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. ## Embedding Any form factor can be embedded in another page as a self‑sizing widget. Drop in a container and the loader script — it builds an `