Skip to content

Commit

Permalink
Fix #270988: [MusicXML] first-fret tag not supported for fretboard di…
Browse files Browse the repository at this point in the history
…agrams

Support first-fret tag on both import and export.
  • Loading branch information
lvinken authored and vpereverzev committed May 21, 2021
1 parent 2aefafd commit 7c7e0e6
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 23 deletions.
20 changes: 16 additions & 4 deletions importexport/musicxml/importmxmlpass2.cpp
Expand Up @@ -4893,6 +4893,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()
Expand All @@ -4906,7 +4911,15 @@ FretDiagram* MusicXMLParserPass2::frame()
std::map<int, int> 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->setFrets(val);
Expand Down Expand Up @@ -4946,9 +4959,8 @@ 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
_logger->logError(QString("FretDiagram::readMusicXML: illegal frame-note string %1").arg(string), &_e);
}
Expand Down Expand Up @@ -4978,7 +4990,7 @@ FretDiagram* MusicXMLParserPass2::frame()
continue;

int endString = bEnds[fret];
fd->setBarre(startString, endString, fret);
fd->setBarre(startString, endString, fret - fd->fretOffset());
}

return fd;
Expand Down
42 changes: 23 additions & 19 deletions libmscore/fret.cpp
Expand Up @@ -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;
Expand All @@ -1290,25 +1293,26 @@ void FretDiagram::writeMusicXML(XmlWriter& xml) const
xml.tag("fret", "0");
xml.etag();
}

// Markers may exists alongside with dots
// Write dots
for (auto const& d : dot(i)) {
if (!d.exists())
continue;
xml.stag("frame-note");
xml.tag("string", mxmlString);
xml.tag("fret", d.fret);
// TODO: write fingerings

// Also write barre if it starts at this dot
if (std::find(bStarts.begin(), bStarts.end(), d.fret) != bStarts.end()) {
xml.tagE("barre type=\"start\"");
bStarts.erase(std::remove(bStarts.begin(), bStarts.end(), d.fret), bStarts.end());
}
if (std::find(bEnds.begin(), bEnds.end(), d.fret) != bEnds.end()) {
xml.tagE("barre type=\"stop\"");
bEnds.erase(std::remove(bEnds.begin(), bEnds.end(), d.fret), bEnds.end());
else {
// Write dots
for (auto const& d : dot(i)) {
if (!d.exists())
continue;
xml.stag("frame-note");
xml.tag("string", mxmlString);
xml.tag("fret", d.fret + fretOffset());
// TODO: write fingerings

// Also write barre if it starts at this dot
if (std::find(bStarts.begin(), bStarts.end(), d.fret) != bStarts.end()) {
xml.tagE("barre type=\"start\"");
bStarts.erase(std::remove(bStarts.begin(), bStarts.end(), d.fret), bStarts.end());
}
if (std::find(bEnds.begin(), bEnds.end(), d.fret) != bEnds.end()) {
xml.tagE("barre type=\"stop\"");
bEnds.erase(std::remove(bEnds.begin(), bEnds.end(), d.fret), bEnds.end());
}
xml.etag();
}
xml.etag();
}
Expand Down
195 changes: 195 additions & 0 deletions mtest/musicxml/io/testChordDiagrams1.xml
Expand Up @@ -157,6 +157,201 @@
<text>Chord plus frame</text>
</lyric>
</note>
</measure>
<measure number="4">
<print new-system="yes"/>
<harmony print-frame="no">
<root>
<root-step>G</root-step>
</root>
<kind>major</kind>
<frame>
<frame-strings>6</frame-strings>
<frame-frets>4</frame-frets>
<frame-note>
<string>6</string>
<fret>3</fret>
</frame-note>
<frame-note>
<string>5</string>
<fret>2</fret>
</frame-note>
<frame-note>
<string>4</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>3</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>2</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>1</string>
<fret>3</fret>
</frame-note>
</frame>
</harmony>
<note>
<pitch>
<step>G</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<lyric number="1">
<syllabic>single</syllabic>
<text>Frame</text>
</lyric>
</note>
</measure>
<measure number="5">
<harmony print-frame="no">
<root>
<root-step>G</root-step>
</root>
<kind>major</kind>
<frame>
<frame-strings>6</frame-strings>
<frame-frets>4</frame-frets>
<first-fret>2</first-fret>
<frame-note>
<string>6</string>
<fret>3</fret>
</frame-note>
<frame-note>
<string>5</string>
<fret>2</fret>
</frame-note>
<frame-note>
<string>4</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>3</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>2</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>1</string>
<fret>3</fret>
</frame-note>
</frame>
</harmony>
<note>
<pitch>
<step>G</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<lyric number="1">
<syllabic>single</syllabic>
<text>Frame with first-fret 2</text>
</lyric>
</note>
</measure>
<measure number="6">
<harmony print-frame="no">
<root>
<root-step>A</root-step>
</root>
<kind>major</kind>
<frame>
<frame-strings>6</frame-strings>
<frame-frets>4</frame-frets>
<frame-note>
<string>5</string>
<fret>0</fret>
</frame-note>
<frame-note>
<string>4</string>
<fret>2</fret>
</frame-note>
<frame-note>
<string>3</string>
<fret>2</fret>
</frame-note>
<frame-note>
<string>2</string>
<fret>2</fret>
</frame-note>
<frame-note>
<string>1</string>
<fret>0</fret>
</frame-note>
</frame>
</harmony>
<note>
<pitch>
<step>A</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<lyric number="1">
<syllabic>single</syllabic>
<text>Frame</text>
</lyric>
</note>
</measure>
<measure number="7">
<harmony print-frame="no">
<root>
<root-step>A</root-step>
</root>
<kind>major</kind>
<frame>
<frame-strings>6</frame-strings>
<frame-frets>4</frame-frets>
<first-fret>12</first-fret>
<frame-note>
<string>5</string>
<fret>12</fret>
<barre type="start"/>
</frame-note>
<frame-note>
<string>4</string>
<fret>14</fret>
<barre type="start"/>
</frame-note>
<frame-note>
<string>3</string>
<fret>14</fret>
</frame-note>
<frame-note>
<string>2</string>
<fret>14</fret>
<barre type="stop"/>
</frame-note>
<frame-note>
<string>1</string>
<fret>12</fret>
<barre type="stop"/>
</frame-note>
</frame>
</harmony>
<note>
<pitch>
<step>A</step>
<octave>4</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<lyric number="1">
<syllabic>single</syllabic>
<text>Frame with first-fret 12 and barres</text>
</lyric>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
Expand Down

0 comments on commit 7c7e0e6

Please sign in to comment.