JimNYC wrote: ↑08-08-21 10:37 amIf [...] it's hard to parse for playing, then it might be a shortcut to leave the playing part as is with MIDI and just parse MusicXML for notation.
I was mostly bellyaching. The documentation is surprisingly good/usable and the amount that
doesn't overlap between parsing for playing vs. parsing for sheet music is small.
There are a lot of corner cases, but I knew there would be going in. The most recent example: Most MusicXML files appear to use the "partwise" layout, which means there is a "part-list" that has some metadata (name, instrument, midi-channel, overall volume multiplier, etc.) for each part. Then the rest of the file is a series of "part" elements with an ID that corresponds to an entry from that first list. Each "part" contains a list of "measure", which in turn contains the rest.
Because a "part" seemed to be distinguished by instrument and MIDI channel, it falls very naturally into the same slot as a "track" in a MIDI file. And I have been happily treating it like a MIDI track this entire time, until I got to the "parse multiple parts" test on my list. In MuseScore, I told it to give me like seven piano staffs, plunked some random notes down, exported as MusicXML, and tried to read it in Synthesia.
The file only contains one part.
Instead, (inside score-partwise > part > measure)
each "note" has a new child element included like "<staff>4</staff>".
So now Synthesia has to contend with two ways to get something like a MIDI track: multiple parts or a single part that refers to multiple (arbitrarily numbered) staffs. I wouldn't be surprised to find a third eventually. There are subtleties beyond that, too: how do you treat a grand staff? Is that just one "track"? (Given piano music's propensity to use a separate staff for each hand, it should probably still be considered two for Synthesia's sake... but that doesn't mean I haven't had to spend time thinking about it!)
And "partwise" isn't the only layout. There is a "timewise" layout that re-organizes everything so the list of "measure" elements are at the top level, where each contains a complete list of what each part does during that measure. (I still haven't seen one of those in the wild yet.) So that's another variation the code will need to handle.
All of the above impacts both playing and rendering sheet music, so there wouldn't be any savings in this case to try to only do one or the other, unfortunately. This is just one of those things I have to slog my way through.
