Plain-text music notation

Write a lead sheet | hear a band

Plainsong is notation you type in any editor, diff in git, and compile to MIDI. This page is the compiler — it runs in your browser, offline, with nothing installed and nothing sent anywhere. Everything below is live: edit it, drag it, break it.

Playground

Type notation, hear it play. It recompiles as you type, and each token lights up while the note it wrote is sounding.

song.song
Arrangement0.0s
Compiling…

Simulation · the bar divides itself

You never write durations in Plainsong. You write how many things happen in a bar, and the bar shares itself out between them. Drag the slider and watch the same bar hold a different number of events — the bar never changes length.

Simulation · a written time is an arrival time

The idea the whole system rests on. A score says “beat one” without saying where that happens. Plainsong reads a written beat as the moment sound should reach a listener, then solves backwards for when each player must physically move. Drag the players. Drag the ear. Watch what changes.

What to try

Drag the ear onto the organ. The spread stops being zero — because the organ now reaches you before the timpani does, and the score was never compensated for your chair.

Turn compensation off

Everyone plays exactly on the written beat, and the sound smears by the width of the stage. That is what a score without a stage actually asks for.

Why orchestras watch

Every player hears a different performance, and each is right about what they hear. The eyes carry the intention; the ears only carry history.

Simulation · rows stack, repeats follow on

Rows of different kinds sound together. Two rows of the same kind run one after the other. Toggle the second melody row between the two readings.

Run it yourself

This page is one file with no dependencies, no build step and no network calls.

  1. Save the page

    Save this HTML anywhere and open it. It works from file:// — offline, on a plane, on a machine with nothing installed.

  2. Or serve it

    python3 -m http.server 8000

    Any static host works: GitHub Pages, Netlify, a Raspberry Pi on your desk. There is no backend to run.

  3. Then take the full version

    pip install plainsong
    plainsong serve

    Adds the stage solver, soundfont rendering, 3,800 chord charts, an agent, and an MCP server so several agents can write one score at once.

What this page leaves out

A faithful subset

The browser engine is checked against the reference compiler by running both over the same notation and comparing the pitch, start and length of every note — triplets, 3/4, 6/8, chord qualities, stacks, sustains, rests and repeated rows (tools/demo_differential.py). That check exists because it found a real one: . and - were read here as rests rather than as holds, so every sustained note was cut to a single subdivision while the note counts stayed right. Where this engine is smaller, it is smaller on purpose — it does not solve stages, only draws them.

Sound

Oscillators with an envelope. The installed version renders through a soundfont, which is the difference between a sketch and something you would play to somebody.

Agentic compiling

Checking for a built-in model…