Skip to content

Commit

Permalink
fix #85786 - Export then import of Music XML file gives score with no…
Browse files Browse the repository at this point in the history
… notes
  • Loading branch information
lvinken committed Feb 7, 2016
1 parent 5b20a4a commit 09c3dcf
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 36 deletions.
49 changes: 32 additions & 17 deletions mscore/importmxmlpass1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,23 @@ Score::FileError MusicXMLParserPass1::parse()
return Score::FileError::FILE_NO_ERROR;
}

//---------------------------------------------------------
// allStaffGroupsIdentical
//---------------------------------------------------------

/**
Return true if all staves in Part \a p have the same staff group
*/

static bool allStaffGroupsIdentical(Part const* const p)
{
for (int i = 1; i < p->nstaves(); ++i) {
if (p->staff(0)->staffGroup() != p->staff(i)->staffGroup())
return false;
}
return true;
}

//---------------------------------------------------------
// scorePartwise
//---------------------------------------------------------
Expand Down Expand Up @@ -999,7 +1016,10 @@ void MusicXMLParserPass1::scorePartwise()
foreach(Part const* const p, il) {
if (p->nstaves() > 1 && !partSet.contains(p)) {
p->staff(0)->addBracket(BracketItem(BracketType::BRACE, p->nstaves()));
p->staff(0)->setBarLineSpan(p->nstaves());
if (allStaffGroupsIdentical(p)) {
// span only if the same types
p->staff(0)->setBarLineSpan(p->nstaves());
}
}
}
}
Expand Down Expand Up @@ -2264,22 +2284,22 @@ void MusicXMLParserPass1::staffDetails(const QString& partId)
Q_ASSERT(_e.isStartElement() && _e.name() == "staff-details");
logDebugTrace("MusicXMLParserPass1::staffDetails");

Part* part = getPart(partId);
Q_ASSERT(part);
int staves = part->nstaves();

QString number = _e.attributes().value("number").toString();
int n = -1; // invalid
int n = 1; // default
if (number != "") {
n = number.toInt();
if (n <= 0) {
logError(QString("invalid number %1").arg(number));
n = -1;
if (n <= 0 || n > staves) {
logError(QString("invalid staff-details number %1").arg(number));
n = 1;
}
else
n--; // make zero-based
}
n--; // make zero-based

Part* part = getPart(partId);
Q_ASSERT(part);
int staves = part->nstaves();
int staffIdx = _score->staffIdx(part);
int staffIdx = _score->staffIdx(part) + n;

StringData* t = 0;
if (_score->staff(staffIdx)->isTabStaff()) {
Expand Down Expand Up @@ -2307,12 +2327,7 @@ void MusicXMLParserPass1::staffDetails(const QString& partId)
}

if (staffLines > 0) {
if (n == -1) {
for (int i = 0; i < staves; ++i)
setStaffLines(_score, staffIdx+i, staffLines);
}
else
setStaffLines(_score, staffIdx, staffLines);
setStaffLines(_score, staffIdx, staffLines);
}

if (t) {
Expand Down
34 changes: 17 additions & 17 deletions mscore/importmxmlpass2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3427,15 +3427,21 @@ void MusicXMLParserPass2::clef(const QString& partId, Measure* measure, const in
{
Q_ASSERT(_e.isStartElement() && _e.name() == "clef");

Part* part = _pass1.getPart(partId);
Q_ASSERT(part);
int staves = part->nstaves();

// TODO: check error handling for
// - single staff
// - multi-staff with same clef
QString strClefno = _e.attributes().value("number").toString();
int clefno = 1; // reasonable default
int clefno = 1; // default
if (strClefno != "")
clefno = strClefno.toInt();
if (clefno <= 0) {
// conversion error (0) or other issue (<0), assume staff 1
if (clefno <= 0 || clefno > part->nstaves()) {
// conversion error (0) or other issue, assume staff 1
// Also for Cubase 6.5.5 which generates clef number="2" in a single staff part
// Same fix is required in pass 1 and pass 2
logError(QString("invalid clef number '%1'").arg(strClefno));
clefno = 1;
}
Expand Down Expand Up @@ -3521,27 +3527,21 @@ void MusicXMLParserPass2::clef(const QString& partId, Measure* measure, const in
else
qDebug("clef: unknown clef <sign=%s line=%d oct ch=%d>", qPrintable(c), line, i); // TODO

Part* part = _pass1.getPart(partId);
Q_ASSERT(part);
int staves = part->nstaves();

if (clefno < staves) {
Clef* clefs = new Clef(_score);
clefs->setClefType(clef);
int track = _pass1.trackForPart(partId) + clefno * VOICES;
clefs->setTrack(track);
Segment* s = measure->getSegment(clefs, tick);
s->add(clefs);
}
Clef* clefs = new Clef(_score);
clefs->setClefType(clef);
int track = _pass1.trackForPart(partId) + clefno * VOICES;
clefs->setTrack(track);
Segment* s = measure->getSegment(clefs, tick);
s->add(clefs);

// set the correct staff type
// note that this overwrites the staff lines value set in pass 1
// also note that clef handling should probably done in pass1
int staffIdx = _score->staffIdx(part);
int staffIdx = _score->staffIdx(part) + clefno;
int lines = _score->staff(staffIdx)->lines();
if (st == StaffTypes::TAB_DEFAULT || (_hasDrumset && st == StaffTypes::PERC_DEFAULT)) {
_score->staff(staffIdx)->setStaffType(StaffType::preset(st));
_score->staff(staffIdx)->setLines(lines);
_score->staff(staffIdx)->setLines(lines); // preserve previously set staff lines
_score->staff(staffIdx)->setBarLineTo((lines - 1) * 2);
}
}
Expand Down
4 changes: 2 additions & 2 deletions mtest/musicxml/io/testIncorrectStaffNumber_ref.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
<sign>F</sign>
<line>4</line>
</clef>
</attributes>
<note>
Expand Down
Binary file added mtest/musicxml/io/testTablature4.pdf
Binary file not shown.
217 changes: 217 additions & 0 deletions mtest/musicxml/io/testTablature4.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise>
<work>
<work-number>MuseScore testfile</work-number>
<work-title>Tablature 4</work-title>
</work>
<identification>
<creator type="composer">Leon Vinken</creator>
<encoding>
<software>MuseScore 0.7.0</software>
<encoding-date>2007-09-10</encoding-date>
<supports element="accidental" type="yes"/>
<supports element="beam" type="yes"/>
<supports element="print" attribute="new-page" type="no"/>
<supports element="print" attribute="new-system" type="no"/>
<supports element="stem" type="yes"/>
</encoding>
</identification>
<part-list>
<score-part id="P1">
<part-name>Guitar</part-name>
<part-abbreviation>Guit.</part-abbreviation>
<score-instrument id="P1-I1">
<instrument-name>Classical Guitar</instrument-name>
</score-instrument>
<midi-device id="P1-I1" port="1"></midi-device>
<midi-instrument id="P1-I1">
<midi-channel>1</midi-channel>
<midi-program>25</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<score-part id="P2">
<part-name>Guitar</part-name>
<part-abbreviation>Guit.</part-abbreviation>
<score-instrument id="P2-I1">
<instrument-name>Classical Guitar [Tablature]</instrument-name>
</score-instrument>
<midi-device id="P2-I1" port="1"></midi-device>
<midi-instrument id="P2-I1">
<midi-channel>2</midi-channel>
<midi-program>25</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
</part-list>
<part id="P1">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>G</sign>
<line>2</line>
<clef-octave-change>-1</clef-octave-change>
</clef>
<clef number="2">
<sign>TAB</sign>
<line>5</line>
</clef>
<staff-details number="2">
<staff-lines>6</staff-lines>
<staff-tuning line="1">
<tuning-step>E</tuning-step>
<tuning-octave>2</tuning-octave>
</staff-tuning>
<staff-tuning line="2">
<tuning-step>A</tuning-step>
<tuning-octave>2</tuning-octave>
</staff-tuning>
<staff-tuning line="3">
<tuning-step>D</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="4">
<tuning-step>G</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="5">
<tuning-step>B</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="6">
<tuning-step>E</tuning-step>
<tuning-octave>4</tuning-octave>
</staff-tuning>
</staff-details>
</attributes>
<note>
<pitch>
<step>G</step>
<octave>3</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<pitch>
<step>G</step>
<octave>3</octave>
</pitch>
<duration>4</duration>
<voice>5</voice>
<type>whole</type>
<stem>none</stem>
<staff>2</staff>
<notations>
<technical>
<string>3</string>
<fret>0</fret>
</technical>
</notations>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
<part id="P2">
<measure number="1">
<attributes>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>TAB</sign>
<line>5</line>
</clef>
<clef number="2">
<sign>G</sign>
<line>2</line>
<clef-octave-change>-1</clef-octave-change>
</clef>
<staff-details number="1">
<staff-lines>6</staff-lines>
<staff-tuning line="1">
<tuning-step>E</tuning-step>
<tuning-octave>2</tuning-octave>
</staff-tuning>
<staff-tuning line="2">
<tuning-step>A</tuning-step>
<tuning-octave>2</tuning-octave>
</staff-tuning>
<staff-tuning line="3">
<tuning-step>D</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="4">
<tuning-step>G</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="5">
<tuning-step>B</tuning-step>
<tuning-octave>3</tuning-octave>
</staff-tuning>
<staff-tuning line="6">
<tuning-step>E</tuning-step>
<tuning-octave>4</tuning-octave>
</staff-tuning>
</staff-details>
</attributes>
<note>
<pitch>
<step>G</step>
<octave>3</octave>
</pitch>
<duration>4</duration>
<voice>1</voice>
<type>whole</type>
<staff>1</staff>
<notations>
<technical>
<string>3</string>
<fret>0</fret>
</technical>
</notations>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<pitch>
<step>G</step>
<octave>3</octave>
</pitch>
<duration>4</duration>
<voice>5</voice>
<type>whole</type>
<staff>2</staff>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
</score-partwise>
1 change: 1 addition & 0 deletions mtest/musicxml/io/tst_mxml_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ private slots:
void tablature1() { mxmlIoTest("testTablature1"); }
void tablature2() { mxmlIoTest("testTablature2"); }
void tablature3() { mxmlIoTest("testTablature3"); }
void tablature4() { mxmlIoTest("testTablature4"); }
void tempo1() { mxmlIoTest("testTempo1"); }
void tempo2() { mxmlIoTestRef("testTempo2"); }
void timesig1() { mxmlIoTest("testTimesig1"); }
Expand Down

0 comments on commit 09c3dcf

Please sign in to comment.