diff --git a/importexport/musicxml/importmxmlpass2.cpp b/importexport/musicxml/importmxmlpass2.cpp index 80b258e9feeca..d88df7f993409 100644 --- a/importexport/musicxml/importmxmlpass2.cpp +++ b/importexport/musicxml/importmxmlpass2.cpp @@ -4891,6 +4891,11 @@ FiguredBass* MusicXMLParserPass2::figuredBass() /** Parse the /score-partwise/part/measure/harmony/frame node. Return the result as a FretDiagram. + Notes: + - MusicXML's first-fret is a positive integer equivalent to MuseScore's FretDiagram::_fretOffset + - it is one-based in MusicXML and zero-based in MuseScore + - in MusicXML fret numbers are absolute, in MuseScore they are relative to the fretOffset, + which affects both single strings and barres */ FretDiagram* MusicXMLParserPass2::frame() @@ -4904,7 +4909,15 @@ FretDiagram* MusicXMLParserPass2::frame() std::map bEnds; while (_e.readNextStartElement()) { - if (_e.name() == "frame-frets") { + if (_e.name() == "first-fret") { + bool ok {}; + int val = _e.readElementText().toInt(&ok); + if (ok && val > 0) + fd->setFretOffset(val - 1); + else + _logger->logError(QString("FretDiagram::readMusicXML: illegal first-fret %1").arg(val), &_e); + } + else if (_e.name() == "frame-frets") { int val = _e.readElementText().toInt(); if (val > 0) { fd->setProperty(Pid::FRET_FRETS, val); @@ -4946,7 +4959,7 @@ FretDiagram* MusicXMLParserPass2::frame() else if (fret > 0) { if (fd->marker(actualString).mtype == FretMarkerType::CROSS) fd->setMarker(actualString, FretMarkerType::NONE); - fd->setDot(actualString, fret, true); + fd->setDot(actualString, fret - fd->fretOffset(), true); } } else @@ -4978,7 +4991,7 @@ FretDiagram* MusicXMLParserPass2::frame() continue; int endString = bEnds[fret]; - fd->setBarre(startString, endString, fret); + fd->setBarre(startString, endString, fret - fd->fretOffset()); } return fd; diff --git a/libmscore/fret.cpp b/libmscore/fret.cpp index 745a91acc0e3f..0ec51a2b2198e 100644 --- a/libmscore/fret.cpp +++ b/libmscore/fret.cpp @@ -1266,6 +1266,9 @@ void FretDiagram::writeMusicXML(XmlWriter& xml) const xml.stag("frame"); xml.tag("frame-strings", _strings); xml.tag("frame-frets", frets()); + if (fretOffset() > 0) + xml.tag("first-fret", fretOffset() + 1); + for (int i = 0; i < _strings; ++i) { int mxmlString = _strings - i; @@ -1298,7 +1301,7 @@ void FretDiagram::writeMusicXML(XmlWriter& xml) const continue; xml.stag("frame-note"); xml.tag("string", mxmlString); - xml.tag("fret", d.fret); + xml.tag("fret", d.fret + fretOffset()); // TODO: write fingerings // Also write barre if it starts at this dot diff --git a/mtest/musicxml/io/testChordDiagrams1.xml b/mtest/musicxml/io/testChordDiagrams1.xml index 42950ba83c654..6245321d7716c 100644 --- a/mtest/musicxml/io/testChordDiagrams1.xml +++ b/mtest/musicxml/io/testChordDiagrams1.xml @@ -157,6 +157,201 @@ Chord plus frame + + + + + + G + + major + + 6 + 4 + + 6 + 3 + + + 5 + 2 + + + 4 + 0 + + + 3 + 0 + + + 2 + 0 + + + 1 + 3 + + + + + + G + 4 + + 4 + 1 + whole + + single + Frame + + + + + + + G + + major + + 6 + 4 + 2 + + 6 + 3 + + + 5 + 2 + + + 4 + 0 + + + 3 + 0 + + + 2 + 0 + + + 1 + 3 + + + + + + G + 4 + + 4 + 1 + whole + + single + Frame with first-fret 2 + + + + + + + A + + major + + 6 + 4 + + 5 + 0 + + + 4 + 2 + + + 3 + 2 + + + 2 + 2 + + + 1 + 0 + + + + + + A + 4 + + 4 + 1 + whole + + single + Frame + + + + + + + A + + major + + 6 + 4 + 12 + + 5 + 12 + + + + 4 + 14 + + + + 3 + 14 + + + 2 + 14 + + + + 1 + 12 + + + + + + + A + 4 + + 4 + 1 + whole + + single + Frame with first-fret 12 and barres + + light-heavy