ported #7211 : fix #298438: Correctly import notes without beams from MusicXML.

This commit is contained in:
Igor Korsukov 2021-02-18 13:34:01 +02:00 committed by pereverzev+v
parent f726aef895
commit ebcbecb266
3 changed files with 23 additions and 7 deletions

View file

@ -202,7 +202,7 @@ static void copyOverlapData(VoiceOverlapDetector& vod, VoiceList& vcLst)
//---------------------------------------------------------
MusicXMLParserPass1::MusicXMLParserPass1(Score* score, MxmlLogger* logger)
: _divs(0), _score(score), _logger(logger)
: _divs(0), _score(score), _logger(logger), _hasBeamingInfo(false)
{
// nothing
}
@ -1151,7 +1151,12 @@ void MusicXMLParserPass1::identification()
_score->setMetaTag("copyright", _e.readElementText());
} else if (_e.name() == "encoding") {
// TODO
_e.skipCurrentElement(); // skip but don't log
while (_e.readNextStartElement()) {
if (_e.name() == "supports" && _e.attributes().value("element") == "beam" && _e.attributes().value("type") == "yes") {
_hasBeamingInfo = true;
}
_e.skipCurrentElement();
}
// _score->setMetaTag("encoding", _e.readElementText()); works with DOM but not with pull parser
// temporarily fake the encoding tag (compliant with DOM parser) to help the autotester
if (MScore::debugMode) {
@ -3216,6 +3221,7 @@ void MusicXMLParserPass1::note(const QString& partId,
} else if (_e.name() == "accidental") {
_e.skipCurrentElement(); // skip but don't log
} else if (_e.name() == "beam") {
_hasBeamingInfo = true;
_e.skipCurrentElement(); // skip but don't log
} else if (_e.name() == "chord") {
chord = true;

View file

@ -127,7 +127,7 @@ public:
void scoreInstrument(const QString& partId);
void midiInstrument(const QString& partId);
void part();
void measure(const QString& partId, const Fraction cTime, Fraction& mdur, VoiceOverlapDetector& vod,const int measureNr);
void measure(const QString& partId, const Fraction cTime, Fraction& mdur, VoiceOverlapDetector& vod, const int measureNr);
void print(const int measureNr);
void attributes(const QString& partId, const Fraction cTime);
void clef(const QString& partId);
@ -163,6 +163,7 @@ public:
Fraction getMeasureStart(const int i) const;
int octaveShift(const QString& id, const int staff, const Fraction f) const;
const CreditWordsList& credits() const { return _credits; }
bool hasBeamingInfo() const { return _hasBeamingInfo; }
private:
// functions
@ -181,6 +182,7 @@ private:
QMap<QString, MusicXMLInstruments> _instruments; ///< instruments for each part, mapped on part id
Score* _score; ///< MuseScore score
MxmlLogger* _logger; ///< Error logger
bool _hasBeamingInfo; ///< Whether the score supports or contains beaming info
// part specific data (TODO: move to part-specific class)
Fraction _timeSigDura; ///< Measure duration according to last timesig read

View file

@ -1820,7 +1820,7 @@ static void removeBeam(Beam*& beam)
// handleBeamAndStemDir
//---------------------------------------------------------
static void handleBeamAndStemDir(ChordRest* cr, const Beam::Mode bm, const Direction sd, Beam*& beam)
static void handleBeamAndStemDir(ChordRest* cr, const Beam::Mode bm, const Direction sd, Beam*& beam, bool hasBeamingInfo)
{
if (!cr) {
return;
@ -1860,10 +1860,18 @@ static void handleBeamAndStemDir(ChordRest* cr, const Beam::Mode bm, const Direc
beam->add(cr);
}
}
// if no beam, set stem direction on chord itself and set beam to auto
// if no beam, set stem direction on chord itself
if (!beam) {
static_cast<Chord*>(cr)->setStemDirection(sd);
cr->setBeamMode(Beam::Mode::AUTO);
// set beam to none if score has beaming information and note can get beam, otherwise
// set to auto
bool canGetBeam = (cr->durationType().type() >= TDuration::DurationType::V_EIGHTH
&& cr->durationType().type() <= TDuration::DurationType::V_1024TH);
if (hasBeamingInfo && canGetBeam) {
cr->setBeamMode(Beam::Mode::NONE);
} else {
cr->setBeamMode(Beam::Mode::AUTO);
}
}
// terminate the current beam and add to the score
if (beam && bm == Beam::Mode::END) {
@ -4716,7 +4724,7 @@ Note* MusicXMLParserPass2::note(const QString& partId,
// regular note
// handle beam
if (!chord) {
handleBeamAndStemDir(c, bm, stemDir, currBeam);
handleBeamAndStemDir(c, bm, stemDir, currBeam, _pass1.hasBeamingInfo());
}
// append any grace chord after chord to the previous chord