Repository navigation
Conversation
webern
force-pushed
the
m/mxdev-niente
branch
from
November 7, 2026 08:43
71bdd21 to
a401d1b
Compare
webern
commented
Nov 7, 2026
| // WedgeStop that ends it; without one the circle is left out and a diagnostic says so. A | ||
| // hairpin whose wedgeType is unspecified is written as a crescendo, with the circle on its | ||
| // start. | ||
| Bool niente; |
Owner
Author
There was a problem hiding this comment.
I think this could imply an n instead of a circle, even if the spec calls it niente, so lets disambiguate here.
Suggested change
| Bool niente; | |
| Bool nienteCircle; |
Owner
Author
There was a problem hiding this comment.
🛑 I'm concerned about this PR. It's a lot of code churn in many files for something that doesn't seem to appear in the wild corpus at all. Holding on this one for further consideration.
webern
force-pushed
the
m/mxdev-niente
branch
from
November 7, 2026 11:35
a401d1b to
dae99d0
Compare
<wedge niente="yes"> draws a small circle at the point of a hairpin: a crescendo out of nothing or a diminuendo to nothing. It was dropped on read and never written. WedgeStart gains Bool niente, set on the start for either direction. MusicXML states it on the start of a crescendo but on the stop of a diminuendo, so the writer routes it: a crescendo (or a wedge of unspecified type, which is written as a crescendo) carries it on its start, and SpannerResolver hands a diminuendo's value to the stop that closes it, as it already does for an octave-shift's size. A diminuendo with niente and no stop is reported as dropped data. The reader pairs the part's wedges in one pass before reading its measures, so a diminuendo start takes the niente of its stop even when the stop is in a later measure. niente on the wide end of a hairpin (a diminuendo start or a crescendo stop) or on a continue segment means nothing in MusicXML and is reported as dropped data. The pairing rule (within a part, by number, a stop closes the most recently opened start) now lives in one place, SpannerPairing.h, shared by the reader, the octave-shift sizes and the wedge niente. Pins synthetic/wedge.3.0.xml and synthetic/wedge.3.1.xml.
…error The reader reads a <wedge type="continue"> as a WedgeStart of unspecified type, which the writer writes and pairs as a crescendo start. The niente pre-pass skipped continues instead, so after a diminuendo, a continue and a stop it gave the stop's niente to the diminuendo, which the writer then could not write: the stop now ends the continue. The pre-pass opens on every wedge that is not a stop, so the reader and the writer pair a stop with the same start. A niente that is not read or not written is reported as dropped data with error severity, as every other dropped value is. The WedgeStart::niente comment now says how yes, no and unspecified are drawn, that a diminuendo's circle needs the WedgeStop that ends it, and that a hairpin of unspecified type carries the circle on its start. Tests cover the continue case, a reused number, both values on a diminuendo with no stop, the location of each diagnostic, and two unnumbered diminuendos open at once on different staves, built through the api and read from a file whose order differs from the order mx writes.
An unnumbered ottava nested in another, and an unnumbered ottava beside one numbered 1 on another staff, each take their stop size from their own start.
webern
force-pushed
the
m/mxdev-niente
branch
from
November 7, 2026 11:37
dae99d0 to
80dd597
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI Summary
A niente hairpin has a small circle at its point: a crescendo that grows out of nothing, or a diminuendo that fades away to nothing. MusicXML spells it
<wedge niente="yes">, on the start of a crescendo but on the stop of a diminuendo, because that is where the point is. A read and write through mx::api dropped the attribute, so the circle was lost.WedgeStart gains one field, niente (Bool, unspecified by default, part of WedgeStart equality). It is set on the start for either direction: yes draws the circle, no or unspecified leave a plain point. WedgeStop is unchanged, so a caller cannot put a circle on the wide end of a hairpin.
On write, a crescendo's niente goes on its start, and a diminuendo's goes on the stop that ends it, found with the same pairing the writer already uses to give an octave-shift stop the size of its start: within a part, by number, a stop ends the most recently opened start, across measures and staves. A start of unspecified type is written as a crescendo, as before, so its niente goes on the start. A diminuendo with niente and no stop has nowhere to put it; the value is left out and reported as dropped data (error severity), for no as well as yes.
On read, one pass over each part's wedges in document order pairs every stop with its start before the measures are read, so a diminuendo takes the niente of its stop even when the stop is in a later measure. Reader and writer pair the same way: the writer pairs in the order it writes, and a continue segment, which mx::api reads as a start of unspecified type and writes as a crescendo start, is paired as a start on both sides. niente on the wide end (a diminuendo's start, a crescendo's stop), on a continue segment, or on a stop that ends a continue is not read, and each is reported once as dropped data with the measure where it appears.
The pairing rule now lives in one small header shared by the reader, the octave-shift sizes and the wedge niente. The octave-shift code that moved onto it behaves exactly as before.
What existing callers see: scores that do not set niente write exactly what they wrote before. Reading a file now fills niente where the file states it, and a file with niente where MusicXML ignores it now produces a dropped-data diagnostic where it was silently dropped before. No file in the corpus outside the two pinned here uses niente. No public signature changes.
Out of scope: a continue segment is still read as a start of unspecified type and written back as a crescendo start, which this change does not fix. An absent number and number 1 still pair separately, as they already do for every spanner in mx, although MusicXML says an absent number means 1.
Pins two files in the api round-trip baseline:
Testing
References