Easy-to-manage track markers you can share.
CueDown is a minimal, human-writable cue sheet format for tracklists and DJ sets. A tracklist in the common forum notation — 0:00 Artist - Title — is already almost valid CueDown, and normalizing a file is always safe.
One cue per line. One canonical form. Strict errors, never guesses. Files end in .cd.
{{ outText }}
Timecode and track text are the MVP; everything else is optional. A forum tracklist pasted whole just works — the file-level fallback grammar reads it and rewrites it canonically.
Every accepted line maps to exactly one canonical line, and canonical lines are fixed points: parse → serialize returns them byte-for-byte. Normalization is idempotent — safe to run on every save.
Anything outside the accept grammar is an error — nine of them, E01 through E09, each with the line number of first failure. Parsers stop early and never silently degrade.
A permissive accept grammar tolerates hearts, lowercase tokens, any token order and overflowing timecodes. The strict write grammar is a single canonical subset. The delimiter is - — everything after it is the track string, verbatim.
0:00 ❤️ - Aalson – Reeds 6:56 - Alex Rusin – Ups and Down 15:50 s3 <3 - Nils Andreas – Rainbow Colors 1:04:25.5 - Koelle – Round & Round 133:16 x s2 - Some Track – Goodbye
00:00 <3 - Aalson – Reeds 06:56 - Alex Rusin – Ups and Down 15:50 <3 S3 - Nils Andreas – Rainbow Colors 01:04:25.500 - Koelle – Round & Round 02:13:16 X S2 - Some Track – Goodbye
The fallback is all-or-nothing. A parser first attempts the canonical grammar on the whole file; only if that fails may it read every line as TIMECODE TRACK STRING. The grammars are disjoint by construction, so a canonical file with one typo never silently degrades with its flags swallowed as text.
MM:SS when hours are zero, HH:MM:SS when nonzero, fields zero-padded to 2.
Field overflow normalizes: 133:16 → 02:13:16. Bare integers are rejected.
Fractions use . only, 1–3 digits, written as exactly 3 — and never stripped once present: 4:20.0 → 04:20.000.
<3 — loved. Any heart emoji is accepted on input (❤️ 💜 🩵 …); always written <3.
X — never show me this again. No emoji aliases, deliberately: people go the distance for tracks they love; the never-play list gets the minimal product.
Mutually exclusive — both on one line is E02.
Relative intensity of the set at this cue, S0 lowest. Purely advisory — it exists to show the shape of a set: where's the fast part?
Single digit, never zero-padded (S03 is E06). s3 accepted, written S3.
Default is S0; an explicit S0 is preserved on write.
Every error reports the line number of first failure. When both grammar passes fail, the canonical-pass error is the primary diagnostic.
| Code | Meaning |
|---|---|
| E01 | Duplicate token — timecode, flag, or speed appears twice |
| E02 | <3 and X on the same line |
| E03 | Missing timecode |
| E04 | Empty or whitespace-only track string |
| E05 | Malformed timecode — bare integer, bad field shape, "," fraction separator |
| E06 | Zero-padded speed (S03) or out-of-range speed |
| E07 | Timecodes not strictly ascending / duplicate timecode |
| E08 | Unrecognized token before the delimiter (canonical grammar) |
| E09 | Mixed-grammar file — parses under neither the canonical nor the fallback grammar |
.cd (.cue is taken by CDRWIN cue sheets).TIMECODE [FLAG] [SPEED] - TRACK STRING
- written as space-hyphen-space, and it is the only delimiter. : is not accepted — it collides with timecode syntax and may appear freely in track text.Fallback grammar — forum tracklists. TIMECODE TRACK STRING: everything after the timecode is the track string, verbatim, hyphens included. All-or-nothing at file level: the canonical pass runs first, and only if it fails may the fallback pass run — then every line must parse as fallback. The grammars are disjoint by construction; when both passes fail the result is E09 with the canonical-pass error as the primary diagnostic. On write, a fallback file is rewritten to canonical CueDown.
Timecode (required). Write MM:SS when hours are zero, HH:MM:SS when nonzero, fields zero-padded to 2. Milliseconds only if sub-second data exists, as . + exactly 3 digits; a zero fraction still counts (4:20.0 → 04:20.000). Accept 2 or 3 fields of 1+ digits; field overflow normalizes (133:16 → 02:13:16). Fraction separator . only, a decimal fraction of a second, 1–3 digits. Bare integers rejected — minimum shape is M:SS.
Flag (optional). <3 or X, mutually exclusive. Accept any heart emoji with or without U+FE0F; always written <3. x accepted on input; no emoji aliases for X.
Speed (optional). S0–S9, single digit, never zero-padded. s3 accepted, written S3. Default is S0; an explicit S0 is preserved on write, and a token-free line stays token-free.
Token matching is case-insensitive on input; tokens are written uppercase. Input tokens may be separated by one or more spaces/tabs; on write, exactly one space between tokens and around the delimiter.
Strict — fail the file, stop early. The nine codes E01–E09 are listed in the table above.
The format carries intent; interpretation is application-defined. <3 — loved, the track the listener will go the distance for. X — never show me this again; excluded from future play. S0–S9 — relative intensity of the set at this cue, purely advisory. muwav's intended use: map BPM across the set, visualize intensity, and potentially skip the wind-down track at the end.
normalize(normalize(f)) == normalize(f) byte-for-byte (idempotence).