#24

tools: musicxml-to-notes, a score part to a render-notes melody

Openyungalgowants to merge intofrom

Adds tools/musicxml-to-notes.ts: one part of a MusicXML score (.mxl or .musicxml) becomes the {bpm, lyrics, notes} file that chimera render notes sings. With it, a multi-voice show for the duet page (?show=<id>) can be built from a published arrangement, not from hand-typed JSON.

bun tools/musicxml-to-notes.ts score.mxl                 # list the parts
bun tools/musicxml-to-notes.ts score.mxl P1 --out p1.json [--bpm N] [--spell ba=bah,...]

No new dependencies: .mxl is unzipped with the system unzip; it needs the wasm build (bun run wasm) for the dictionary.

Traps it handles

  • Scores split words their own way (to-ge-ther), and the dictionary can't say a lone ge. Each word is joined again and syllabified by the engine's own dictionary, as render notes will.
  • More syllables than notes (ba is "B.A." in CMUdict) or none (a hum written dm) stop the tool with the words and measures listed; --spell word=respelling fixes them. Fewer syllables than notes hold the last vowel, with a warning.
  • Curly apostrophes are normalized before the count.
  • Repeats and 1st/2nd endings are written out; each pass through a repeat sings its own lyric line (verse 2 the second time).
  • Tied notes become one note; a note with no lyric holds the previous vowel (-).
  • D.C. / D.S. / To Coda / Fine, and two voices on one staff, stop the tool with an error, not a wrong melody.

Not handled

  • Tempo changes: render notes takes one bpm; the tool warns and uses the first (or --bpm).
  • Chords: the first note is sung.
  • The XML is read with regular expressions; tested on MuseScore output only.

Ran

  • A 5-part a cappella MuseScore arrangement (71 measures, 198–314 notes per part): converted, rendered with render notes --tele, and replayed on the duet page with 5 heads in sync.

  • A hand-written score with a repeat, two endings and two verses: expands to the right order and lyrics.

  • A second (7-part) MuseScore arrangement: errors and warnings as designed.

  • bun run typecheck and bun run test pass.

  • tests/musicxml-to-notes.test.ts (4 tests): play order with repeats, endings and verses; joined words and ties; too-long words refused once whatever their case; D.S. refused.

Activity

4
vercel[bot]13h ago

@yungalgo is attempting to deploy a commit to the Jameson Hodge's projects Team on Vercel.

A member of the Team first needs to authorize it.

ProbablePrime9h ago

I don't really know how to handle this PR wise, especially because it's vibe coded, but I asked Claude to improve your script a bit and: https://github.com/ProbablePrime/chimera-vocal-synth/tree/feat/musicxml-ify.ts

became the result.

My changes there convert a whole score into json and can output it directly in the shows folder too. It makes my workflow really easy, Here's how I do it:

  1. I downloaded: https://musescore.com/user/286001/scores/2962801 as MusicXML
  2. I ran: bun tools/musicxml-ify.ts all-i-want-for-christmas-is-you-mariah-carey-ttbb-a-cappella-choir.mxl --output public/shows/christmas
  3. I loaded: http://127.0.0.1:5317/?show=christmas
  4. I got: https://www.youtube.com/watch?v=QKg3-m-5C2A
  5. This immediately got copyright claimed, but I kind of see that as a win, Chimera is re-creating a song well enough for that to happen 🤣