Skip to content

Commit 5f46ab2

Browse files
iveshenry18Jojo-Schmitz
authored andcommitted
ENG-35: Fix small chords on MusicXML import.
Since MusicXML only stores note-level information about smallness (<type size='cue'> and <cue>), chords that should be small were being read as normal-sized chords of small notes. This caused issues with the sizes of flags, ledger lines, and articulations. This commit adds handleSmallness to ensure that a chord with all small notes is imported as a small chord with all non-small notes, as well as a test for this particular case. Port of musescore#8181
1 parent 64be802 commit 5f46ab2

File tree

4 files changed

+797
-3
lines changed

4 files changed

+797
-3
lines changed

importexport/musicxml/importmxmlpass2.cpp

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4012,7 +4012,7 @@ static TDuration determineDuration(const bool rest, const QString& type, const i
40124012
static Chord* findOrCreateChord(Score* score, Measure* m,
40134013
const Fraction& tick, const int track, const int move,
40144014
const TDuration duration, const Fraction dura,
4015-
Beam::Mode bm)
4015+
Beam::Mode bm, bool small)
40164016
{
40174017
//qDebug("findOrCreateChord tick %d track %d dur ticks %d ticks %s bm %hhd",
40184018
// tick, track, duration.ticks(), qPrintable(dura.print()), bm);
@@ -4026,6 +4026,9 @@ static Chord* findOrCreateChord(Score* score, Measure* m,
40264026
else
40274027
c->setBeamMode(bm);
40284028
c->setTrack(track);
4029+
// Chord is initialized with the smallness of its first note.
4030+
// If a non-small note is added later, this is handled in handleSmallness.
4031+
c->setSmall(small);
40294032

40304033
setChordRestDuration(c, duration, dura);
40314034
Segment* s = m->getSegment(SegmentType::ChordRest, tick);
@@ -4100,6 +4103,38 @@ static void handleDisplayStep(ChordRest* cr, int step, int octave, const Fractio
41004103
}
41014104
}
41024105

4106+
//---------------------------------------------------------
4107+
// handleSmallness
4108+
//---------------------------------------------------------
4109+
4110+
/**
4111+
* Handle the distinction between small notes and a small
4112+
* chord, to ensure a chord with all small notes is small.
4113+
* This also handles the fact that a small note being added
4114+
* to a small chord should not itself be small.
4115+
* I.e. a chord is "small until proven otherwise".
4116+
*/
4117+
4118+
static void handleSmallness(bool cueOrSmall, Note* note, Chord* c)
4119+
{
4120+
if (cueOrSmall) {
4121+
note->setSmall(!c->small()); // Avoid redundant smallness
4122+
}
4123+
else {
4124+
note->setSmall(false);
4125+
if (c->small()) {
4126+
// What was a small chord becomes small notes in a non-small chord
4127+
c->setSmall(false);
4128+
for (Note* otherNote : c->notes()) {
4129+
if (note != otherNote)
4130+
otherNote->setSmall(true);
4131+
}
4132+
}
4133+
}
4134+
}
4135+
4136+
4137+
41034138
//---------------------------------------------------------
41044139
// setNoteHead
41054140
//---------------------------------------------------------
@@ -4513,7 +4548,7 @@ Note* MusicXMLParserPass2::note(const QString& partId,
45134548
c = findOrCreateChord(_score, measure,
45144549
noteStartTime,
45154550
msTrack + msVoice, msMove,
4516-
duration, dura, bm);
4551+
duration, dura, bm, small || cue);
45174552
}
45184553
else {
45194554
// grace note
@@ -4585,7 +4620,7 @@ Note* MusicXMLParserPass2::note(const QString& partId,
45854620
addGraceChordsBefore(c, gcl);
45864621
}
45874622

4588-
note->setSmall(cue || small); // cue notes are always small, normal notes only if size=cue
4623+
handleSmallness(cue || small, note, c);
45894624
note->setPlay(!cue); // cue notes don't play
45904625
note->setHeadGroup(headGroup);
45914626
if (noteColor != QColor::Invalid)

0 commit comments

Comments
 (0)