Skip to content

feat: round-trip a redundant staves element in mx::api - #421

Open
webern wants to merge 5 commits into
mainfrom
claude/mx-api-roundtrip-corpus-9pkrg6-04-staff-count
Open

feat: round-trip a redundant staves element in mx::api#421
webern wants to merge 5 commits into
mainfrom
claude/mx-api-roundtrip-corpus-9pkrg6-04-staff-count

Conversation

@webern

@webern webern commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Human Summary

TODO: human writes here

Summary

MusicXML states a part's staff count in <attributes>/<staves>, and a part that omits the element has one staff. mx wrote the element only when the part had more than one staff, so a source that spelled out the redundant <staves>1</staves> lost it.

PartData gains bool writeStaffCount, defaulting to false. It only affects a single-staff part: a part with more than one staff writes its count either way, since without it every note would land on staff one. The reader sets it when the source spelled the element out and the count is one, so the common case stays at the default.

PartReader::calculateNumStaves now also reports whether a <staves> element was seen. The count alone cannot tell you, since one is both "the source said one" and "the source said nothing".

Non-breaking: one new field defaulting to the behavior mx had before.

Round-trip corpus

Adds 3 files to roundtrip-baseline.txt (402 -> 405). drop:staves was the fourth entry on the classifier worklist.

Testing

  • New StaffCountApiTest covers the single-staff default, the single-staff override, and a two-staff part that writes its count regardless (*StaffCount*: 8 assertions in 3 test cases)
  • make api-test (6314 assertions in 582 test cases)
  • make api-roundtrip (405 passed, 0 failed of 405 pinned)
  • make api-roundtrip-discover reports exactly the 3 new passes and no regressions
  • make fmt

References


Generated by Claude Code

webern added 4 commits August 23, 2026 16:09
MusicXML lets a <note> carry its own playback velocity in the dynamics and
end-dynamics attributes, the MIDI Note On and Note Off velocities expressed as
percentages of the default forte level. The api had no home for either, so the
reader dropped them and an author could not state them.

NoteData gains velocityStart and velocityStop. Both are optional doubles that
default to empty, so a note that says nothing about playback still writes no
attribute. The names avoid "dynamics", which in the api already means the
printed marking (a MarkData in noteAttachmentData) rather than how hard the
note is played.

Pins the thirteen foundsuite Inventions in the api round-trip baseline. Each
one carried a per-note velocity that was the only thing it lost on write.
MusicXML's <identification>/<source> names the edition, manuscript, or other
publication a score was made from. The api had nowhere to keep it, so the
reader discarded it and every write dropped the element.

ScoreData gains an optional source string. Optional rather than a plain string
because <source></source> is legal and means something different from saying
nothing at all.

Pins five more files in the api round-trip baseline whose only divergence was
the dropped element.
<direction directive="yes"> aligns a direction with the measure's time
signature instead of with the note it is anchored to, which is how a tempo or
style marking at the head of a movement is usually placed. The api had no field
for it, so the attribute was dropped on write.

DirectionData gains a tri-state directive following the api's Bool convention:
unspecified does not write an attribute, yes and no are written verbatim.
<harmony> does not carry the attribute, so only <direction> reads and writes it.

Pins three more files in the api round-trip baseline.
MusicXML states a part's staff count in <staves>, and a part that omits the
element has one staff. mx wrote the element only when the part had more than
one staff, so a source that spelled out the redundant <staves>1</staves> lost
it.

PartData gains writeStaffCount, defaulting to false. It only affects a
single-staff part; a part with more than one staff writes its count either way,
since without it every note would land on staff one. The reader sets it when
the source spelled the element out.

Pins three more files in the api round-trip baseline.
@webern webern added feature new feature request non-breaking fixes or implementation that do not require breaking changes api Affects the mx::api layer impl Affects the mx::impl layer ai Issues opened by, or through, a coding agent. labels Aug 23, 2026 — with Claude
Base automatically changed from claude/mx-api-roundtrip-corpus-9pkrg6-03-direction-directive to main August 23, 2026 18:58
…ff-count

Signed-off-by: Matthew James Briggs <matthew.james.briggs@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai Issues opened by, or through, a coding agent. api Affects the mx::api layer feature new feature request impl Affects the mx::impl layer non-breaking fixes or implementation that do not require breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant