Skip to content

Notation you can trust (Epic M); release 0.5.0 - #13

Merged
matteospanio merged 2 commits into
masterfrom
dev
Oct 4, 2026
Merged

matteospanio merged 2 commits into
masterfrom
dev

Conversation

@matteospanio

Copy link
Copy Markdown
Member

Notation you can trust: Epic M, released as 0.5.0. A review found that the notation the note boards didn't measure was broken somewhere. This PR measures it (lyrics, chord symbols, dynamics, clefs, stems and beams, LilyPond's own playback) and fixes what the measurements showed. See docs/changelog.md for the list of changes, docs/devlog.md for the notes and docs/import-export.md for the measured support.

What changes

  • MusicXML: read where <backup> and <forward> place the notes, and written valid (<divisions> always, text escaped, ISO-8859-1 input read).
  • LilyPond reader: no longer drops constructs silently (\afterGrace, grace chords, tremolos, \partial N*M, beat structure, text scripts, placement, marks).
  • Lyrics:
    • read and written the way LilyPond sings them (melismas, __, ~, punctuation, verses, named voices);
    • MusicXML elisions and verse names, MIDI syllables, ABC verses and Humdrum **text;
    • Note.lyric_syllables in Python.
  • Chord symbols: kept as steps, so 7#9, add9 or m(maj7) are no longer read as major. They are written to LilyPond as g4:7.9- at their beat.
  • Stems and beams: readers keep only what the source states, and writers draw the rest by LilyPond's rules. ABC and kern now have beams, and retrograde flips them.
  • Note arrays: velocity per part, dynamics from directions, sounding pitch, grace chords.
  • Writers:
    • church modes keep their tonic;
    • tempo is written once, and marks sit at their beat;
    • mid-bar clefs keep their place in every format;
    • MIDI never puts two instruments on one channel;
    • kern rests a voice that is absent from a bar.
  • Transforms: retrograde carries key, meter and clef changes; transposition prefers fewer accidentals.
  • CLI: every movement is written; LilyPond warnings go to stderr; -I works on every reading command; diff compares timing.

The last commit fixes what failed CI on the release commit:

  • Clippy 1.99's new lints.
  • The LilyPond oracle: LilyPond 2.24 writes a lyric tie as ‿ in its MIDI, and 2.22 writes ~. The oracle now compares them as equal.
  • The fuzz job's crash: the beam rules listed every beat of the bar. A meter of 2³¹ beats used more than 8 GB in every writer and took down the runner. Equal beats are now kept as one.

Measured

Check 0.4.0 0.5.0
Lyrics surviving MusicXML → LilyPond / kern / MIDI (of 38 files) 8 / 0 / 17 33 / 38 / 33
Chord symbols through LilyPond (of 8) 0 7
LilyPond lyric cases where lytk reads what LilyPond sings 11 of 26 31 of 31
Syllables LilyPond sings where lytk wrote them not measured 710 of 710
Stems / beams matching the source engraver not measured 98.0 % / 94.1 %

Checks

  • 1,206 Rust and 325 Python tests pass locally, and Clippy 1.99 is clean on every target.
  • LilyPond oracle with both LilyPond 2.22.1 and 2.24.3: 31/31 lyric cases, 710/710 syllables, 148 fixtures compiled.
  • The LilyPond corpus boards pass.
  • The LilyPond-shaped fuzz (release build, 1,024 cases) passed three runs, peaking at 0.5 GB. Before the fix it hit an 8 GB cap within seconds.

🤖 Generated with Claude Code

matteospanio and others added 2 commits October 2, 2026 14:28
The 2026-10-01 review found that what the note boards didn't measure was
broken somewhere. M0 measures it (notation board: lyrics, chord symbols,
dynamics, clefs at their places; stems/beams against the source
engravers; LilyPond lyric and playback oracles; one Python test per
confirmed bug), and M1-M10 fix it:

- M1/M2 MusicXML read at the <backup>/<forward> cursor; written valid
  (escaped text, <divisions> always, encodings).
- M5 LilyPond constructs no longer dropped (afterGrace, grace chords,
  tremolo, \partial N*M, beat structure, text scripts, placement, marks).
- M6 note arrays: per-part velocity, direction dynamics, sounding pitch,
  grace chords; Music::Transposition.
- M7 chord symbols as steps; LilyPond chordmode at each beat.
- M4 stems and beams drawn by LilyPond's rules where a source left them.
- M8 writers: church modes, tempo once, marks at their beat, mid-bar
  clefs, ABC clefs/hairpins, kern rests and *staff, MIDI channels.
- M3 lyrics sung where LilyPond sings them, through every format.
- M9 retrograde carries keys/clefs; transpose prefers fewer accidentals.
- M10 CLI writes every movement; warnings; -I; diff compares timing.

Version 0.5.0 in Cargo.toml (and Cargo.lock); the changelog's
[Unreleased] becomes [0.5.0] - 2026-10-02; roadmap, devlog,
import-export (measured support) and the CLI docs updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
… meters

- Clippy 1.99 (2026-10-01): function items passed by value, a duplicated
  #[allow], a dead `indent -= 1`.
- LilyPond oracle: LilyPond 2.24 (CI's) writes a lyric tie as `‿` in its
  MIDI, 2.22 as `~`; both sides are compared through `elided`. 31/31 and
  710/710 with either version.
- Fuzz job out of memory: Beaming::of listed every beat of the bar, so a
  meter of 2^31 beats made 2^31 beat ends in every writer. Equal beats
  are kept as one, and end_after repeats a pattern over its span.
  Test: a_meter_of_equal_beats_keeps_one.

Changelog dated 2026-10-04, the release day; roadmap and devlog updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@matteospanio
matteospanio merged commit da00093 into master Oct 4, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant