From 4d143f6aa86583c473fddbb60d1a4ebb2bf4b279 Mon Sep 17 00:00:00 2001 From: iveshenry18 Date: Thu, 1 Jul 2021 16:08:16 -0600 Subject: [PATCH] ENG-59: Fix missing secondary beam breaks Previously, only the first beam was taken into account when importing Beam::Mode. This commit adds a mechanism to collect the beam type for all beams and make a more correct choice about Beam::Mode (including BEGIN32 and BEGIN64). Additionally, it adds handling of these modes to the export code. Now the round trip from .mscx -> .xml -> .mscx is correct and complete *when beam modes are specified explicitly in the .mscx*; however, more thorough handling of Beam::Mode::AUTO (where it results in the equivalent of BEGIN32 or BEGIN64) on export needs to be done. Duplicate of #8492, plus fixing 4 compiler warnings, see #8554 --- importexport/musicxml/exportxml.cpp | 21 +- importexport/musicxml/importmxmlpass2.cpp | 68 ++- importexport/musicxml/importmxmlpass2.h | 2 +- mtest/musicxml/io/testBeamModes.pdf | Bin 0 -> 27872 bytes mtest/musicxml/io/testBeamModes.xml | 650 ++++++++++++++++++++++ mtest/musicxml/io/testBeamModes_ref.mscx | 513 +++++++++++++++++ mtest/musicxml/io/tst_mxml_io.cpp | 1 + 7 files changed, 1225 insertions(+), 30 deletions(-) create mode 100644 mtest/musicxml/io/testBeamModes.pdf create mode 100644 mtest/musicxml/io/testBeamModes.xml create mode 100644 mtest/musicxml/io/testBeamModes_ref.mscx diff --git a/importexport/musicxml/exportxml.cpp b/importexport/musicxml/exportxml.cpp index 66f99d96fb6cd..f07be34c3b795 100644 --- a/importexport/musicxml/exportxml.cpp +++ b/importexport/musicxml/exportxml.cpp @@ -2928,6 +2928,8 @@ static void writeBeam(XmlWriter& xml, ChordRest* const cr, Beam* const b) int blp = -1; // beam level previous chord int blc = -1; // beam level current chord int bln = -1; // beam level next chord + Beam::Mode bmc = Beam::Mode::AUTO; // beam mode current chord + Beam::Mode bmn = Beam::Mode::AUTO; // beam mode next chord // find beam level previous chord for (int i = idx - 1; blp == -1 && i >= 0; --i) { const auto crst = elements[i]; @@ -2935,23 +2937,34 @@ static void writeBeam(XmlWriter& xml, ChordRest* const cr, Beam* const b) blp = toChord(crst)->beams(); } // find beam level current chord - if (cr->isChord()) + if (cr->isChord()) { blc = toChord(cr)->beams(); + bmc = toChord(cr)->beamMode(); + } // find beam level next chord for (int i = idx + 1; bln == -1 && i < elements.size(); ++i) { const auto crst = elements[i]; - if (crst->isChord()) + if (crst->isChord()) { bln = toChord(crst)->beams(); + bmn = toChord(crst)->beamMode(); + } } // find beam type and write for (int i = 1; i <= blc; ++i) { QString text; - if (blp < i && bln >= i) text = "begin"; + // TODO: correctly handle Beam::Mode::AUTO + // when equivalent to BEGIN32 or BEGIN64 + if ((blp < i && bln >= i) + || (bmc == Beam::Mode::BEGIN32 && i > 1) + || (bmc == Beam::Mode::BEGIN64 && i > 2)) + text = "begin"; else if (blp < i && bln < i) { if (bln > 0) text = "forward hook"; else if (blp > 0) text = "backward hook"; } - else if (blp >= i && bln < i) + else if ((blp >= i && bln < i) + || (bmn == Beam::Mode::BEGIN32 && i > 1) + || (bmn == Beam::Mode::BEGIN64 && i > 2)) text = "end"; else if (blp >= i && bln >= i) text = "continue"; diff --git a/importexport/musicxml/importmxmlpass2.cpp b/importexport/musicxml/importmxmlpass2.cpp index 2d4df7787e7c6..b4e32a6eba2f7 100644 --- a/importexport/musicxml/importmxmlpass2.cpp +++ b/importexport/musicxml/importmxmlpass2.cpp @@ -1836,7 +1836,7 @@ static void handleBeamAndStemDir(ChordRest* cr, const Beam::Mode bm, const Direc // reset beam mode for all elements and remove the beam removeBeam(beam); } - else if (!(bm == Beam::Mode::BEGIN || bm == Beam::Mode::MID || bm == Beam::Mode::END)) { + else if (!(bm == Beam::Mode::BEGIN || bm == Beam::Mode::MID || bm == Beam::Mode::END || bm == Beam::Mode::BEGIN32 || bm == Beam::Mode::BEGIN64)) { qDebug("handleBeamAndStemDir() in beam, bm %d -> abort beam", static_cast(bm)); // reset beam mode for all elements and remove the beam removeBeam(beam); @@ -4501,6 +4501,36 @@ static void setNoteHead(Note* note, const QColor noteheadColor, const bool noteh note->setHeadType(NoteHead::Type::HEAD_QUARTER); } +//--------------------------------------------------------- +// computeBeamMode +//--------------------------------------------------------- + +/** + Calculate the beam mode based on the collected beamTypes. + */ + +static Beam::Mode computeBeamMode(const QMap& beamTypes) + { + // Start with uniquely-handled beam modes + if (beamTypes.value(1) == "continue" + && beamTypes.value(2) == "begin") + return Beam::Mode::BEGIN32; + else if (beamTypes.value(1) == "continue" + && beamTypes.value(2) == "continue" + && beamTypes.value(3) == "begin") + return Beam::Mode::BEGIN64; + // Generic beam modes are naive to all except the first beam + else if (beamTypes.value(1) == "begin") + return Beam::Mode::BEGIN; + else if (beamTypes.value(1) == "continue") + return Beam::Mode::MID; + else if (beamTypes.value(1) == "end") + return Beam::Mode::END; + else + // backward-hook, forward-hook, and other unknown combinations + return Beam::Mode::AUTO; + } + //--------------------------------------------------------- // addFiguredBassElemens //--------------------------------------------------------- @@ -4711,7 +4741,8 @@ Note* MusicXMLParserPass2::note(const QString& partId, int velocity = round(_e.attributes().value("dynamics").toDouble() * 0.9); bool graceSlash = false; bool printObject = _e.attributes().value("print-object") != "no"; - Beam::Mode bm = Beam::Mode::AUTO; + Beam::Mode bm; + QMap beamTypes; QString instrumentId; MusicXMLParserLyric lyric { _pass1.getMusicXmlPart(partId).lyricNumberHandler(), _e, _score, _logger }; MusicXMLParserNotations notations { _e, _score, _logger }; @@ -4727,7 +4758,7 @@ Note* MusicXMLParserPass2::note(const QString& partId, // element handled } else if (_e.name() == "beam") - beam(bm); + beam(beamTypes); else if (_e.name() == "chord") { chord = true; _e.readNext(); @@ -4809,6 +4840,8 @@ Note* MusicXMLParserPass2::note(const QString& partId, currBeams.insert(currentVoice, (Beam *)nullptr); Beam* &currBeam = currBeams[currentVoice]; + bm = computeBeamMode(beamTypes); + // check for timing error(s) and set dura // keep in this order as checkTiming() might change dura auto errorStr = mnd.checkTiming(type, rest, grace); @@ -5634,32 +5667,17 @@ void MusicXMLParserPass2::harmony(const QString& partId, Measure* measure, const /** Parse the /score-partwise/part/measure/note/beam node. - Sets beamMode in case of begin, continue or end beam number 1. + Collects beamTypes, used in computeBeamMode. */ -void MusicXMLParserPass2::beam(Beam::Mode& beamMode) - { +void MusicXMLParserPass2::beam(QMap& beamTypes) { Q_ASSERT(_e.isStartElement() && _e.name() == "beam"); - int beamNo = _e.attributes().value("number").toInt(); - - if (beamNo == 1) { - QString s = _e.readElementText(); - if (s == "begin") - beamMode = Beam::Mode::BEGIN; - else if (s == "end") - beamMode = Beam::Mode::END; - else if (s == "continue") - beamMode = Beam::Mode::MID; - else if (s == "backward hook") - ; - else if (s == "forward hook") - ; - else - _logger->logError(QString("unknown beam keyword '%1'").arg(s), &_e); - } - else - _e.skipCurrentElement(); + bool hasBeamNo; + int beamNo = _e.attributes().value("number").toInt(&hasBeamNo); + QString s = _e.readElementText(); + + beamTypes.insert(hasBeamNo ? beamNo : 1, s); } //--------------------------------------------------------- diff --git a/importexport/musicxml/importmxmlpass2.h b/importexport/musicxml/importmxmlpass2.h index 5936ff4fbe0b6..ad0c6c968cade 100644 --- a/importexport/musicxml/importmxmlpass2.h +++ b/importexport/musicxml/importmxmlpass2.h @@ -288,7 +288,7 @@ class MusicXMLParserPass2 { FretDiagram* frame(qreal& defaultY, qreal& relativeY, bool& hasTotalY); void harmony(const QString& partId, Measure* measure, const Fraction sTime, DelayedDirectionsList& delayedDirections); Accidental* accidental(); - void beam(Beam::Mode& beamMode); + void beam(QMap& beamTypes); void duration(Fraction& dura); void forward(Fraction& dura); void backup(Fraction& dura); diff --git a/mtest/musicxml/io/testBeamModes.pdf b/mtest/musicxml/io/testBeamModes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..389500616792eb8bcba8fcbefa1d247d5b45290c GIT binary patch literal 27872 zcmeFZb#NU^@-8S_vPBl7g-2vDGh58ej7QAOvSeAzjF!dB%*Iy+RE-&ai{D=17&Ps0R5(v{hj1w#*@16b>u!EkZG&?=fb zSO5WJ&o5y7U_dZEFiS81m=u^bm?5ZSPYy#XUJcVF$Vb zfGLBHcA#2QP>mHB2dIV-j0TJa^v3{_mbJ4sbTk0|Aub2z0J_Z#x<&uT@vrVpt*r$0 z96(wKaxl;_(9^Nf(bF?CGcdDI)3K1!(UFqF@bJI@tqfmvX832_U2T8>S^+%=Jqv4N z&|rGTKzjfqsDb=H2{8SefRKxWh=K!XKp0vDK7fOrDVm!v1#~J$rKit+cfj@Na#X|Lk4^G`xcY(9Q}#D+qKlH2}(s@N500G|Ru~ z@T%*p#&$p}hd))O6|lB)02S>4^mM;%pp^&OTRYkrfQ+JlHCrBrme0z{`nACyM$$?F z4Ndjw8m;mTsT^nS9 zu&D*;SpaB-EkKW15NKd+2z>3$-T~yzmM|`<)0z?yICV&^V`aPcU~mZKI%;tLBcyD*>yq`}a_R@J}tXDm6 z$1a~PPMq=K*=@a^8GBY)^SaKD~a~g+g@(gkD@}mSn(08+lmwhCj0R7h`zJ->EQF?CN3i@nKARc&^_T*|HRLY z;KltsLW_8eNW&<|A!y>iYa2QoY3KJLu|z=BSd=?_fH51Fz{%X{B+{DK|A$pD)XSE9 z(49(9z7}efu~Y*K7WAzF=?{28FMHHv+Mw7*LqSNRRY%c}-M4w03gFw;W8WvL=ywt$ zGPn7HR?|itpJQq16?ph>-+#Nbpt}dIv=uWri3#-+9O+~+WDapqx)v~U$jf?)DU6el zvJ3@=`yX49&yQb5%zRc$5U1?A6v;_SmGWLJ^+uA5OYV*}^d0LeMB*S8bU+;maQ5al zk)PDx=6b^T(I(0D#PoD@;+pKm){fxU5QLRIb*AX?ohM93cCin49a` z2YPm5(!Z~+ zj-FE_GDBACO&NW&S4HLLJ#rBc4_dW9yphO1L>_^{rX<{8?QPS zL8_1BI|1DS;sfirSD7x`*4Dwscuopj7v(7%NdYBDGSZ2UcNsh`w~{4qh

IYnaF~ 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 literal 0 HcmV?d00001 diff --git a/mtest/musicxml/io/testBeamModes.xml b/mtest/musicxml/io/testBeamModes.xml new file mode 100644 index 0000000000000..c72d04e3ea4e3 --- /dev/null +++ b/mtest/musicxml/io/testBeamModes.xml @@ -0,0 +1,650 @@ + + + + + Beam Modes + + + Henry Ives + + MuseScore 0.7.0 + 2007-09-10 + + + + + + + + + + 7 + 40 + + + 1697.14 + 1200 + + 85.7143 + 85.7143 + 85.7143 + 85.7143 + + + 85.7143 + 85.7143 + 85.7143 + 85.7143 + + + + + + + title + Beam Modes + + + subtitle + MuseScore Testcase + + + composer + Henry Ives + + + + brace + + + Piano + Pno. + + Piano + + + + 1 + 1 + 78.7402 + 0 + + + + + + + + + 50.00 + 0.00 + + 170.00 + + + + 48 + + 0 + + + + G + 2 + + + + + C + 1 + 4 + + 6 + 1 + 32nd + sharp + up + begin + begin + begin + + + + C + 1 + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + C + 1 + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + D + 4 + + 6 + 1 + 32nd + up + continue + end + end + + + + D + 4 + + 6 + 1 + 32nd + up + continue + begin + begin + + + + C + 1 + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + C + 1 + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + D + 4 + + 6 + 1 + 32nd + up + end + end + end + + + + F + 4 + + 6 + 1 + 32nd + up + begin + begin + begin + + + + D + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + E + 4 + + 6 + 1 + 32nd + up + continue + continue + continue + + + + E + 4 + + 6 + 1 + 32nd + up + continue + end + end + + + + E + 4 + + 8 + 1 + 16th + + 3 + 2 + + up + continue + begin + + + + + + + F + 4 + + 8 + 1 + 16th + + 3 + 2 + + up + continue + continue + + + + G + 4 + + 8 + 1 + 16th + + 3 + 2 + + up + end + end + + + + + + + F + 1 + 4 + + 12 + 1 + 16th + sharp + up + begin + begin + + + + G + 4 + + 12 + 1 + 16th + up + continue + end + + + + B + 4 + + 8 + 1 + 16th + + 3 + 2 + + up + continue + begin + + + + + + + B + 4 + + 8 + 1 + 16th + + 3 + 2 + + up + continue + continue + + + + C + 5 + + 8 + 1 + 16th + + 3 + 2 + + up + end + end + + + + + + + E + 4 + + 3 + 1 + 64th + up + begin + begin + begin + begin + + + + F + 4 + + 3 + 1 + 64th + natural + up + continue + continue + continue + continue + + + + C + 4 + + 3 + 1 + 64th + natural + up + continue + continue + continue + continue + + + + F + 4 + + 3 + 1 + 64th + up + continue + continue + end + end + + + + E + 4 + + 3 + 1 + 64th + up + continue + continue + begin + begin + + + + F + 4 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + G + 4 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + F + 4 + + 3 + 1 + 64th + up + continue + end + end + end + + + + E + 4 + + 3 + 1 + 64th + up + continue + begin + begin + begin + + + + F + 4 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + G + 4 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + A + 4 + + 3 + 1 + 64th + up + continue + continue + end + end + + + + F + 4 + + 3 + 1 + 64th + up + continue + continue + begin + begin + + + + A + 4 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + C + 5 + + 3 + 1 + 64th + up + continue + continue + continue + continue + + + + E + 5 + + 3 + 1 + 64th + up + end + end + end + end + + + + + + G + 5 + + 48 + 1 + quarter + down + + + + 48 + 1 + quarter + + + + 96 + 1 + half + + + light-heavy + + + + diff --git a/mtest/musicxml/io/testBeamModes_ref.mscx b/mtest/musicxml/io/testBeamModes_ref.mscx new file mode 100644 index 0000000000000..43aebe1592285 --- /dev/null +++ b/mtest/musicxml/io/testBeamModes_ref.mscx @@ -0,0 +1,513 @@ + + + + + 0 + 480 + + 1 + 1 + 1 + 0 + + Henry Ives + + + + + + + + + Beam Modes + + + + stdNormal + + 3 + + Piano + + Piano + Pno. + Piano + 21 + 108 + 21 + 108 + keyboard.piano + F + + 100 + 95 + + + 100 + 33 + + + 100 + 50 + + + 100 + 67 + + + 100 + 100 + + + 120 + 67 + + + 150 + 100 + + + 150 + 50 + + + 120 + 50 + + + 120 + 100 + + + + + + + + + + 12.5 + + + + Beam Modes + + + + + MuseScore Testcase + + + + right,top + + Henry Ives + + + + + + G + G + + + 4 + 4 + + + up + 5 + 1 + + + begin + 32nd + + + accidentalSharp + + 61 + 21 + + + + mid + 32nd + + 61 + 21 + + + + mid + 32nd + + 61 + 21 + + + + mid + 32nd + + 62 + 16 + + + + begin32 + 32nd + + 62 + 16 + + + + mid + 32nd + + 61 + 21 + + + + mid + 32nd + + 61 + 21 + + + + mid + 32nd + + 62 + 16 + + + + up + -3 + -7 + + + begin + 32nd + + 65 + 13 + + + + mid + 32nd + + 62 + 16 + + + + mid + 32nd + + 64 + 18 + + + + mid + 32nd + + 64 + 18 + + + + 2 + 3 + 16th + + + 3 + + + + begin32 + 16th + + 64 + 18 + + + + mid + 16th + + 65 + 13 + + + + mid + 16th + + 67 + 15 + + + + + up + -3 + -8 + + + begin + 16th + + + accidentalSharp + + 66 + 20 + + + + mid + 16th + + 67 + 15 + + + + 2 + 3 + 16th + + + 3 + + + + begin32 + 16th + + 71 + 19 + + + + mid + 16th + + 71 + 19 + + + + mid + 16th + + 72 + 14 + + + + + up + -11 + -15 + + + begin + 64th + + 64 + 18 + + + + mid + 64th + + + accidentalNatural + + 65 + 13 + + + + mid + 64th + + + accidentalNatural + + 60 + 14 + + + + mid + 64th + + 65 + 13 + + + + begin64 + 64th + + 64 + 18 + + + + mid + 64th + + 65 + 13 + + + + mid + 64th + + 67 + 15 + + + + mid + 64th + + 65 + 13 + + + + begin32 + 64th + + 64 + 18 + + + + mid + 64th + + 65 + 13 + + + + mid + 64th + + 67 + 15 + + + + mid + 64th + + 69 + 17 + + + + begin64 + 64th + + 65 + 13 + + + + mid + 64th + + 69 + 17 + + + + mid + 64th + + 72 + 14 + + + + mid + 64th + + 76 + 18 + + + + + + + + quarter + down + + 79 + 15 + + + + quarter + + + half + + + end + + + + + + diff --git a/mtest/musicxml/io/tst_mxml_io.cpp b/mtest/musicxml/io/tst_mxml_io.cpp index c7f169ac05eb2..1a5d620dbcc82 100644 --- a/mtest/musicxml/io/tst_mxml_io.cpp +++ b/mtest/musicxml/io/tst_mxml_io.cpp @@ -68,6 +68,7 @@ private slots: void barStyles3() { mxmlIoTest("testBarStyles3"); } void bracketTypes() { mxmlImportTestRef("testBracketTypes"); } void beamEnd() { mxmlIoTest("testBeamEnd"); } + void beamModes() { mxmlImportTestRef("testBeamModes"); } void beams1() { mxmlIoTest("testBeams1"); } void beams2() { mxmlIoTest("testBeams2"); } void beams3() { mxmlIoTestRef("testBeams3"); }