Skip to content

feat: add notehead filled and smufl to mx::api - #377

Merged
webern merged 2 commits into
webern:mainfrom
rpatters1:notehead-attributes
Jul 31, 2026
Merged

feat: add notehead filled and smufl to mx::api#377
webern merged 2 commits into
webern:mainfrom
rpatters1:notehead-attributes

Conversation

@rpatters1

Copy link
Copy Markdown
Contributor

Human Summary

The title says it all. Add notehead filled and smufl to mx::api. Also cleanup as identified by Claude.

Summary

The <notehead> element's filled and smufl attributes were modeled in mx::core but dropped by mx::api in both directions. NoteData now carries them alongside notehead:

  • noteheadFilled is an api::Bool defaulting to unspecified, so the attribute is only written when set and MusicXML's duration-based default (hollow for a half note and longer) otherwise applies.
  • noteheadSmufl is an optional glyph name, following the precedent in PercussionData and OtherDirectionData. An empty string is treated as absent rather than letting core::SmuflGlyphName repair it into the placeholder "X".

NoteWriter::setNotehead previously skipped the element entirely whenever the notehead value was
normal. It now emits when either attribute is set, so <notehead filled="no">normal</notehead>
survives a round trip. NoteReader::setNoteheadValue becomes setNoteheadItems and reads all
three off core::Notehead; NoteFunctions::parseNote copies them onto the api struct.

Also adds the missing MXAPI_EQUALS_MEMBER(notehead). That field had never been in NoteData's
equality block, so two notes with different noteheads compared equal and the field was invisible
to round-trip checks.

No roundtrip-baseline.txt additions. lysuite/ly22a_Noteheads.xml gets past its notehead
attribute mismatch but still fails further along on three explicit <notehead>normal</notehead>
elements the writer drops, which needs a separate fidelity knob. The synthetic notehead files now
fail on parentheses, font and color, which mx::api does not model.

Testing

  • Six new cases in NoteDataTest: filled alone, filled with a shape, smufl with
    Notehead::other, both together on cluster, absence by default, and a read of
    data/synthetic/notehead.3.1.xml that pins the core to api path
  • All notehead tests pass (notehead*: 38 assertions in 9 test cases)
  • All NoteData tests pass (*_NoteData: 285 assertions in 37 test cases)
  • Full api suite passes (5249 assertions in 469 test cases)
  • make api-roundtrip passes (295 of 295 pinned)

Expose the <notehead> element's filled and smufl attributes, which mx::core
already modeled but mx::api dropped in both directions. NoteWriter now emits
<notehead> when either is set, even for a normal notehead value. Also adds the
missing MXAPI_EQUALS_MEMBER(notehead), which had never been in the equality
block. Six tests in NoteDataTest; no roundtrip-baseline.txt additions.
The test bound a reference to firstNoteheadNote(mxtest::fromXml(xml)).
Lifetime extension does not apply when a reference binds to one returned
by a function, so the temporary ScoreData was destroyed at the end of the
statement and outNote dangled. Hold the score in a local first, as the
neighbouring notehead tests already do.

MSVC's debug CRT caught this by filling the freed block with 0xDD, which
read back as -572662307; libc++ happened not to reuse the block, so the
Linux and macOS jobs passed.

@webern webern left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thank you for all these contributions.

You can merge them in the order you prefer. Only one of them is not approved yet, the one that I mentioned seems to not have the desired diff at the moment.

@rpatters1

Copy link
Copy Markdown
Contributor Author

Just a reminder: I don't have merge privilege (and am not asking for it).

@rpatters1

Copy link
Copy Markdown
Contributor Author

These should be mergeable in any order. (That was the intent.) But the safest order would be from least-to-most recent.

@webern
webern merged commit 7c0c8f9 into webern:main Jul 31, 2026
7 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.

2 participants