# VARASYS PolyMeter A small **website** built around one **polymetric groove trainer / metronome** engine. The home page is the **PE‑1 PolyMeter Editor** — a full web app where you stack as many "meter lanes" as you like; each is 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) and ships as an **embeddable widget** anyone can drop into their own page. **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 audio samples + brand assets (kept in `assets/`) into each page, so the sources stay lean. State (set lists, the practice log, theme and UI preferences) lives in `localStorage`. ## Pages | URL | What | |-----|------| | [`/`](https://metronome.varasys.io/) `index.html` | **PE‑1 — PolyMeter Editor** (home / main app) | | `/concepts.html` | **PolyMeter Concepts** — the form‑factor gallery (cards → live page + info) | | `/player.html` | **PM‑1 Initial** — idealized concept device (full display + set‑list nav, theme, fullscreen "stage" view) | | `/stage.html` | **PM‑1 Stage** — pedalboard build (colour TFT, arcade buttons, 1/4″ instrument pass‑through with analog click injection) | | `/micro.html` | **PM‑µ Micro** — minimal home‑practice unit (one push scroll‑encoder + 7‑segment LED) | | `/info-editor.html`, `/info-initial.html` | purpose pages (web app / concept — no BOM) | | `/info-stage.html`, `/info-micro.html` | purpose **+ priced BOM** (buildable hardware only) | | `/embed.html` · `/embed.js` | embed docs and the drop‑in loader | Each page carries the same VARASYS header (logo + 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 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** (set‑list **⋯** menu) to back up your work. ## 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** — 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 per‑lane *poly* toggle fits a lane's beats evenly into lane 1's bar (e.g. 5‑over‑4, 3‑over‑2). - **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 cross‑day comparison. - **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, and 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** — the acoustic kit: `beep`, `kick`, `snare`, `rim`, `clap`, `hatClosed`, `hatOpen`, `ride`, `crash`, `tomLow`, `tomMid`, `tomHigh`, `tambourine`, `cowbell`, `woodblock`, `claves`, `jamblock` (kick, snare, closed‑hat, 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 per‑step (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 off‑beats to a triplet (2:1) feel. Omit for quarter. - **`=pattern`** — per‑**step 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 beat‑count 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` | eighth‑note hi‑hats (downbeat of each beat accented) | | `ride:4/2s` | **swung** eighth‑note ride | | `claves:5~` | 5 evenly across lane 1's bar (5‑over‑4 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=` — 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. 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 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 (a legacy `presets` field is included for backward compatibility). ## 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 `