Skip to content

Commit

Permalink
Merge pull request #1345 from lvinken/musicxml-fixes
Browse files Browse the repository at this point in the history
Musicxml fixes
  • Loading branch information
lasconic committed Oct 2, 2014
2 parents f6b641f + b653802 commit 9133473
Show file tree
Hide file tree
Showing 12 changed files with 506 additions and 316 deletions.
33 changes: 29 additions & 4 deletions mscore/importxml.cpp
Expand Up @@ -725,8 +725,9 @@ void MusicXml::import(Score* s)
tupletAssert();
score = s;

// TODO only if multi-measure rests used ???
// score->style()->set(StyleIdx::createMultiMeasureRests, true);
// assume no multi-measure rests, will be set to true when encountering a multi-measure rest
// required as multi-measure rest is a meaure attribute in MusicXML instead of a style setting
score->style()->set(StyleIdx::createMultiMeasureRests, false);

for (QDomElement e = doc->documentElement(); !e.isNull(); e = e.nextSiblingElement()) {
if (e.tagName() == "score-partwise")
Expand Down Expand Up @@ -1523,8 +1524,20 @@ void MusicXml::xmlScorePart(QDomElement e, QString id, int& parts)
domNotImplemented(e);
else if (ee.tagName() == "midi-channel")
part->setMidiChannel(ee.text().toInt() - 1);
else if (ee.tagName() == "midi-program")
part->setMidiProgram(ee.text().toInt() - 1);
else if (ee.tagName() == "midi-program") {
int program = ee.text().toInt();
// Bug fix for Cubase 6.5.5 which generates <midi-program>2</midi-program>
// Check program number range
if (program < 1) {
qDebug("MusicXml::xmlScorePart: incorrect midi-program: %d", program);
program = 1;
}
else if (program > 128) {
qDebug("MusicXml::xmlScorePart: incorrect midi-program: %d", program);
program = 128;
}
part->setMidiProgram(program - 1);
}
else if (ee.tagName() == "midi-unpitched") {
qDebug("MusicXml::xmlScorePart: instrument id %s midi-unpitched %s",
qPrintable(instrId), qPrintable(ee.text()));
Expand Down Expand Up @@ -2362,11 +2375,14 @@ Measure* MusicXml::xmlMeasure(Part* part, QDomElement e, int number, Fraction me
}

// multi-measure rest handling:
// if any multi-measure rest is found, the "create multi-measure rest" style setting
// is enabled
// the first measure in a multi-measure rest gets setBreakMultiMeasureRest(true)
// and count down the remaining number of measures
// the first measure after a multi-measure rest gets setBreakMultiMeasureRest(true)
// for all other measures breakMultiMeasureRest is unchanged (stays default (false))
if (startMultiMeasureRest) {
score->style()->set(StyleIdx::createMultiMeasureRests, true);
measure->setBreakMultiMeasureRest(true);
startMultiMeasureRest = false;
}
Expand Down Expand Up @@ -4825,6 +4841,15 @@ Note* MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam
// silently ignore others (will be handled later)
}

// Bug fix for Cubase 6.5.5 which generates <staff>2</staff> in a single staff part
// Same fix is required in MxmlReaderFirstPass::initVoiceMapperAndMapVoices
int nStavesInPart = score->staff(staff)->part()->nstaves();
if (relStaff < 0 || relStaff >= nStavesInPart) {
qDebug("ImportMusicXml: invalid staff %d (staves is %d) at line %d col %d",
relStaff + 1, nStavesInPart, e.lineNumber(), e.columnNumber());
relStaff = 0;
}

// Bug fix for Sibelius 7.1.3 which does not write <voice> for notes with <chord>
if (!chord)
// remember voice
Expand Down
21 changes: 18 additions & 3 deletions mscore/importxmlfirstpass.cpp
Expand Up @@ -509,6 +509,7 @@ void MxmlReaderFirstPass::initVoiceMapperAndMapVoices(QDomElement e, int partNr)
Fraction loc_maxtick;
int timeSigLen = -1; // length in ticks of last timesig read
int timeSigType = -1; // type = beat-type = denominator of last timesig read
int staves = 1;

// count number of chordrests on each MusicXML staff
for (e = e.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
Expand All @@ -529,6 +530,15 @@ void MxmlReaderFirstPass::initVoiceMapperAndMapVoices(QDomElement e, int partNr)
qDebug("measurelength loc_divisions %d", loc_divisions);
#endif
}
else if (eee.tagName() == "staves") {
bool ok;
staves = MxmlSupport::stringToInt(eee.text(), &ok);
if (!ok || staves <= 0) {
qDebug("MusicXml-Import: bad staves value: <%s>",
qPrintable(eee.text()));
staves = 1;
}
}
else if (eee.tagName() == "time") {
QString beats = "";
QString beatType = "";
Expand Down Expand Up @@ -592,13 +602,18 @@ void MxmlReaderFirstPass::initVoiceMapperAndMapVoices(QDomElement e, int partNr)
if (rest)
pitch = "rest";
if (!chord) {
// Bug fix for Cubase 6.5.5 which generates <staff>2</staff> in a single staff part
// Same fix is required in MusicXml::xmlNote
// make sure staff is valid
int corrStaff = (staff >= 0 && staff < staves) ? staff : 0;

// count the chords (only the first note in a chord is counted)
if (0 <= staff && staff < MAX_STAVES) {
if (corrStaff < MAX_STAVES) {
if (!parts[partNr].voicelist.contains(voice)) {
VoiceDesc vs;
parts[partNr].voicelist.insert(voice, vs);
}
parts[partNr].voicelist[voice].incrChordRests(staff);
parts[partNr].voicelist[voice].incrChordRests(corrStaff);
}
// determine note length for voice overlap detection
if (!grace) {
Expand All @@ -609,7 +624,7 @@ void MxmlReaderFirstPass::initVoiceMapperAndMapVoices(QDomElement e, int partNr)
aaamoveTick(loc_tick, loc_maxtick, loc_divisions, ee,
duration, noteDurDesc, errorStr);
// TODO: migrate voice overlap detector to Fraction
vod.addNote(startTick.ticks(), loc_tick.ticks(), voice, staff);
vod.addNote(startTick.ticks(), loc_tick.ticks(), voice, corrStaff);
}
}
}
Expand Down
117 changes: 117 additions & 0 deletions mtest/musicxml/io/testIncorrectMidiProgram.xml
@@ -0,0 +1,117 @@
<?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-title>Incorrect MIDI program numbers</work-title>
</work>
<identification>
<encoding>
<software>MuseScore 0.7.0</software>
<encoding-date>2007-09-10</encoding-date>
</encoding>
<miscellaneous>
<miscellaneous-field name="description">
Check incorrect MIDI program number handling, which must be in the range
from 1 to 128. If out of range, MuseScore will use either 1 or 128.
Cubase 6.5.5 exports midi-program 0.
</miscellaneous-field>
</miscellaneous>
</identification>
<part-list>
<score-part id="P1">
<part-name>Voice</part-name>
<part-abbreviation>Vo.</part-abbreviation>
<score-instrument id="P1-I3">
<instrument-name>Voice</instrument-name>
</score-instrument>
<midi-instrument id="P1-I3">
<midi-channel>1</midi-channel>
<midi-program>129</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<score-part id="P2">
<part-name>Piano</part-name>
<part-abbreviation>Pno.</part-abbreviation>
<score-instrument id="P2-I3">
<instrument-name>Piano</instrument-name>
</score-instrument>
<midi-instrument id="P2-I3">
<midi-channel>2</midi-channel>
<midi-program>0</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>
<mode>major</mode>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<note>
<rest/>
<duration>4</duration>
<voice>1</voice>
</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>
<mode>major</mode>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>G</sign>
<line>2</line>
</clef>
<clef number="2">
<sign>F</sign>
<line>4</line>
</clef>
</attributes>
<note>
<rest/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
</score-partwise>
110 changes: 110 additions & 0 deletions mtest/musicxml/io/testIncorrectMidiProgram_ref.xml
@@ -0,0 +1,110 @@
<?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-title>Incorrect MIDI program numbers</work-title>
</work>
<identification>
<encoding>
<software>MuseScore 0.7.0</software>
<encoding-date>2007-09-10</encoding-date>
</encoding>
</identification>
<part-list>
<score-part id="P1">
<part-name>Voice</part-name>
<part-abbreviation>Vo.</part-abbreviation>
<score-instrument id="P1-I3">
<instrument-name>Voice</instrument-name>
</score-instrument>
<midi-instrument id="P1-I3">
<midi-channel>1</midi-channel>
<midi-program>128</midi-program>
<volume>78.7402</volume>
<pan>0</pan>
</midi-instrument>
</score-part>
<score-part id="P2">
<part-name>Piano</part-name>
<part-abbreviation>Pno.</part-abbreviation>
<score-instrument id="P2-I3">
<instrument-name>Piano</instrument-name>
</score-instrument>
<midi-instrument id="P2-I3">
<midi-channel>2</midi-channel>
<midi-program>1</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>
<mode>major</mode>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<clef>
<sign>G</sign>
<line>2</line>
</clef>
</attributes>
<note>
<rest/>
<duration>4</duration>
<voice>1</voice>
</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>
<mode>major</mode>
</key>
<time>
<beats>4</beats>
<beat-type>4</beat-type>
</time>
<staves>2</staves>
<clef number="1">
<sign>G</sign>
<line>2</line>
</clef>
<clef number="2">
<sign>F</sign>
<line>4</line>
</clef>
</attributes>
<note>
<rest/>
<duration>4</duration>
<voice>1</voice>
<staff>1</staff>
</note>
<backup>
<duration>4</duration>
</backup>
<note>
<rest/>
<duration>4</duration>
<voice>5</voice>
<staff>2</staff>
</note>
<barline location="right">
<bar-style>light-heavy</bar-style>
</barline>
</measure>
</part>
</score-partwise>

0 comments on commit 9133473

Please sign in to comment.