Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MU3 Backend] ENG-25: Improve placement defaults #8325

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions importexport/musicxml/importmxmlpass1.cpp
Expand Up @@ -3192,6 +3192,7 @@ void MusicXMLParserPass1::note(const QString& partId,
else if (_e.name() == "lyric") {
const auto number = _e.attributes().value("number").toString();
_parts[partId].lyricNumberHandler().addNumber(number);
_parts[partId].hasLyrics(true);
_e.skipCurrentElement();
}
else if (_e.name() == "notations")
Expand Down
1 change: 1 addition & 0 deletions importexport/musicxml/importmxmlpass1.h
Expand Up @@ -166,6 +166,7 @@ class MusicXMLParserPass1 {
int octaveShift(const QString& id, const int staff, const Fraction f) const;
const CreditWordsList& credits() const { return _credits; }
bool hasBeamingInfo() const { return _hasBeamingInfo; }
bool isVocalStaff(const QString& id) const { return _parts[id].isVocalStaff(); }
static VBox* createAndAddVBoxForCreditWords(Score* const score, const int miny = 0, const int maxy = 75);

private:
Expand Down
27 changes: 22 additions & 5 deletions importexport/musicxml/importmxmlpass2.cpp
Expand Up @@ -852,8 +852,11 @@ static void addElemOffset(Element* el, int track, const QString& placement, Meas
el->setPlacement(placement == "above" ? Placement::ABOVE : Placement::BELOW);
}
#endif
el->setPlacement(placement == "above" ? Placement::ABOVE : Placement::BELOW);
el->setPropertyFlags(Pid::PLACEMENT, PropertyFlags::UNSTYLED);
if (placement != "") {
el->setPlacement(placement == "above" ? Placement::ABOVE : Placement::BELOW);
el->setPropertyFlags(Pid::PLACEMENT, PropertyFlags::UNSTYLED);
}


el->setTrack(el->isTempoText() ? 0 : track); // TempoText must be in track 0
Segment* s = measure->getSegment(SegmentType::ChordRest, tick);
Expand Down Expand Up @@ -2476,6 +2479,8 @@ void MusicXMLParserDirection::direction(const QString& partId,

_placement = _e.attributes().value("placement").toString();
int track = _pass1.trackForPart(partId);
bool isVocalStaff = _pass1.isVocalStaff(partId);
bool isExpressionText = false;
//qDebug("direction track %d", track);
QList<MusicXmlSpannerDesc> starts;
QList<MusicXmlSpannerDesc> stops;
Expand Down Expand Up @@ -2556,6 +2561,7 @@ void MusicXMLParserDirection::direction(const QString& partId,
if (_wordsText != "" || _metroText != "") {
t = new StaffText(_score);
t->setXmlText(_wordsText + _metroText);
isExpressionText = _wordsText.contains("<i>") && _metroText.isEmpty();
}
else {
t = new RehearsalMark(_score);
Expand All @@ -2580,16 +2586,22 @@ void MusicXMLParserDirection::direction(const QString& partId,
t->setFrameType(FrameType::SQUARE);
t->setFrameRound(0);
}

QString wordsPlacement = placement();
// Case-based defaults
if (wordsPlacement.isEmpty())
if (isVocalStaff) wordsPlacement = "above";
else if (isExpressionText) wordsPlacement = "below";
iveshenry18 marked this conversation as resolved.
Show resolved Hide resolved

if (isLikelyFingering()) {
_logger->logDebugInfo(QString("Inferring fingering: %1").arg(_wordsText));
MusicXMLInferredFingering* inferredFingering = new MusicXMLInferredFingering(totalY(), t, _wordsText, track, placement(), measure, tick + _offset);
MusicXMLInferredFingering* inferredFingering = new MusicXMLInferredFingering(totalY(), t, _wordsText, track, wordsPlacement, measure, tick + _offset);
inferredFingerings.push_back(inferredFingering);
}
else {
// Add element to score later, after collecting all the others and sorting by default-y
// This allows default-y to be at least respected by the order of elements
MusicXMLDelayedDirectionElement* delayedDirection = new MusicXMLDelayedDirectionElement(hasTotalY() ? totalY() : 100, t, track, placement(), measure, tick + _offset);
MusicXMLDelayedDirectionElement* delayedDirection = new MusicXMLDelayedDirectionElement(hasTotalY() ? totalY() : 100, t, track, wordsPlacement, measure, tick + _offset);
delayedDirections.push_back(delayedDirection);
}
}
Expand Down Expand Up @@ -2629,9 +2641,14 @@ void MusicXMLParserDirection::direction(const QString& partId,
dyn->setVelocity( dynaValue );
}

QString dynamicsPlacement = placement();
// Case-based defaults
if (dynamicsPlacement.isEmpty())
dynamicsPlacement = isVocalStaff ? "above" : "below";

// Add element to score later, after collecting all the others and sorting by default-y
// This allows default-y to be at least respected by the order of elements
MusicXMLDelayedDirectionElement* delayedDirection = new MusicXMLDelayedDirectionElement(hasTotalY() ? totalY() : 100, dyn, track, placement(), measure, tick + _offset);
MusicXMLDelayedDirectionElement* delayedDirection = new MusicXMLDelayedDirectionElement(hasTotalY() ? totalY() : 100, dyn, track, dynamicsPlacement, measure, tick + _offset);
delayedDirections.push_back(delayedDirection);
}

Expand Down
16 changes: 16 additions & 0 deletions importexport/musicxml/importxmlfirstpass.cpp
Expand Up @@ -16,6 +16,16 @@ namespace Ms {

// TODO: move somewhere else

static const std::vector<QString> vocalInstrumentNames({"Voice",
"Soprano",
"Mezzo-Soprano",
"Alto",
"Tenor",
"Baritone",
"Bass",
"Women",
"Men"});

MusicXmlPart::MusicXmlPart(QString id, QString name)
: id(id), name(name)
{
Expand Down Expand Up @@ -92,6 +102,12 @@ void MusicXmlPart::calcOctaveShifts()
}
}

bool MusicXmlPart::isVocalStaff() const
{
return (std::find(vocalInstrumentNames.begin(), vocalInstrumentNames.end(), name) != vocalInstrumentNames.end()
|| _hasLyrics);
}

//---------------------------------------------------------
// interval
//---------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions importexport/musicxml/importxmlfirstpass.h
Expand Up @@ -81,6 +81,8 @@ class MusicXmlPart {
const LyricNumberHandler& lyricNumberHandler() const { return _lyricNumberHandler; }
void setMaxStaff(const int staff);
int maxStaff() const { return _maxStaff; }
bool isVocalStaff() const;
void hasLyrics(bool b) { _hasLyrics = b; }
private:
QString id;
QString name;
Expand All @@ -92,6 +94,7 @@ class MusicXmlPart {
QVector<MusicXmlOctaveShiftList> octaveShifts; // octave shift list for every staff
LyricNumberHandler _lyricNumberHandler;
int _maxStaff = 0; // maximum staff value found (1 based), 0 = none
bool _hasLyrics = false;
};

} // namespace Ms
Expand Down
Binary file added mtest/musicxml/io/testPlacementDefaults.pdf
Binary file not shown.