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

Add voice assignment to MEI support #24735

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/importexport/mei/internal/meiconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,9 @@ void Convert::dynamFromMEI(engraving::Dynamic* dynamic, const StringList& meiLin
dynamic->setDynamicType(meiLines.at(0));
}

// @layer
Convert::layerIdentFromMEI(dynamic, meiDynam);

// text content
StringList lines;
// For each line in the dynamic text
Expand Down Expand Up @@ -1307,6 +1310,12 @@ libmei::Dynam Convert::dynamToMEI(const engraving::Dynamic* dynamic, StringList&
meiDynam.SetPlace(Convert::directionToMEI(dynamic->direction()));
}

// @layer
Convert::layerIdentToMEI(dynamic, meiDynam);

// @staff
Convert::staffIdentToMEI(dynamic, meiDynam);

// @label
if (dynamic->dynamicType() != engraving::DynamicType::OTHER) {
meiDynam.SetLabel(engraving::TConv::toXml(dynamic->dynamicType()).ascii());
Expand Down Expand Up @@ -1605,6 +1614,9 @@ void Convert::hairpinFromMEI(engraving::Hairpin* hairpin, const libmei::Hairpin&

// @color
Convert::colorlineFromMEI(hairpin, meiHairpin);

// @layer
Convert::layerIdentFromMEI(hairpin, meiHairpin);
}

libmei::Hairpin Convert::hairpinToMEI(const engraving::Hairpin* hairpin)
Expand All @@ -1631,6 +1643,12 @@ libmei::Hairpin Convert::hairpinToMEI(const engraving::Hairpin* hairpin)
// @color
Convert::colorlineToMEI(hairpin, meiHairpin);

// @layer
Convert::layerIdentToMEI(hairpin, meiHairpin);

// @staff
Convert::staffIdentToMEI(hairpin, meiHairpin);

return meiHairpin;
}

Expand Down Expand Up @@ -2296,6 +2314,9 @@ libmei::Octave Convert::octaveToMEI(const engraving::Ottava* ottava)
// @color
Convert::colorlineToMEI(ottava, meiOctave);

// @staff
Convert::staffIdentToMEI(ottava, meiOctave);

return meiOctave;
}

Expand Down Expand Up @@ -2946,6 +2967,9 @@ libmei::Tempo Convert::tempoToMEI(const engraving::TempoText* tempoText, StringL
// text content - only split lines
meiLines = String(tempoText->plainText()).split(u"\n");

// @staff
Convert::staffIdentToMEI(tempoText, meiTempo);

return meiTempo;
}

Expand Down Expand Up @@ -3333,6 +3357,53 @@ std::list<std::string> Convert::getTypeValuesWithPrefix(const std::string& typeS
return values;
}

void Convert::layerIdentFromMEI(engraving::EngravingItem* item, const libmei::Element& meiElement)
{
if (!item->hasVoiceAssignmentProperties()) {
return;
}

const libmei::AttLayerIdent* layerAtt = dynamic_cast<const libmei::AttLayerIdent*>(&meiElement);

IF_ASSERT_FAILED(layerAtt) {
return;
}

if (layerAtt->HasLayer()) {
// without further check we assume the layer to match
item->setProperty(engraving::Pid::VOICE_ASSIGNMENT, engraving::VoiceAssignment::CURRENT_VOICE_ONLY);
}
}

void Convert::layerIdentToMEI(const engraving::EngravingItem* item, libmei::Element& meiElement)
{
libmei::AttLayerIdent* layerAtt = dynamic_cast<libmei::AttLayerIdent*>(&meiElement);

IF_ASSERT_FAILED(layerAtt) {
return;
}

if (item->hasVoiceAssignmentProperties()
&& (item->getProperty(engraving::Pid::VOICE_ASSIGNMENT).value<engraving::VoiceAssignment>()
== engraving::VoiceAssignment::CURRENT_VOICE_ONLY)) {
layerAtt->SetLayer(item->voice() + 1);
}
}

void Convert::staffIdentToMEI(const engraving::EngravingItem* item, libmei::Element& meiElement)
{
libmei::AttStaffIdent* staffAtt = dynamic_cast<libmei::AttStaffIdent*>(&meiElement);

IF_ASSERT_FAILED(staffAtt) {
return;
}

libmei::xsdPositiveInteger_List staffList;
staffList.push_back(item->staff()->idx() + 1);
// TODO: add staff number if centered between staves
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the 'discriminating factor' really be whether the number is centered between staves, or should it be when the voice assignment is set to ALL_VOICE_IN_INSTRUMENT?
It might be relatively easily to implement using item->part()->staveIdxList().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Information in the @staff attribute is more of a visual nature, i.e. staff="2 3" means something appears on staff 2 and staff 3, and has to be accompanied by a pleace="between". I'll look into this later.

staffAtt->SetStaff(staffList);
}

double Convert::tstampFromFraction(const engraving::Fraction& fraction, const engraving::Fraction& timesig)
{
return (double)fraction.numerator() / fraction.denominator() * timesig.denominator() + 1.0;
Expand Down
5 changes: 5 additions & 0 deletions src/importexport/mei/internal/meiconverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ class Convert
static void harmFromMEI(engraving::Harmony* harmony, const muse::StringList& meiLines, const libmei::Harm& meiHarm, bool& warning);
static libmei::Harm harmToMEI(const engraving::Harmony* harmony, muse::StringList& meiLines);

static void layerIdentFromMEI(engraving::EngravingItem* item, const libmei::Element& meiElement);
static void layerIdentToMEI(const engraving::EngravingItem* item, libmei::Element& meiElement);

static void lvFromMEI(engraving::Articulation* lv, const libmei::Lv& meiLv, bool& warning);
static libmei::Lv lvToMEI(const engraving::Articulation* lv);

Expand Down Expand Up @@ -281,6 +284,8 @@ class Convert
static StaffStruct staffFromMEI(const libmei::StaffDef& meiStaffDef, bool& warning);
static libmei::StaffDef staffToMEI(const engraving::Staff* staff);

static void staffIdentToMEI(const engraving::EngravingItem* item, libmei::Element& meiElement);

static std::pair<engraving::DirectionV, bool> stemFromMEI(const libmei::AttStems& meiStemsAtt, bool& warning);
static std::pair<libmei::data_STEMDIRECTION, double> stemToMEI(const engraving::DirectionV direction, bool noStem);

Expand Down
8 changes: 4 additions & 4 deletions src/importexport/mei/internal/meiexporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,7 @@ bool MeiExporter::writeChord(const Chord* chord, const Staff* staff)
meiChord.SetDots(chord->dots());
}
this->writeBeamTypeAtt(chord, meiChord);
this->writeStaffIdenAtt(chord, staff, meiChord);
this->writeStaffIdentAtt(chord, staff, meiChord);
this->writeStemAtt(chord, meiChord);
this->writeArtics(chord);
this->writeVerses(chord);
Expand Down Expand Up @@ -1273,7 +1273,7 @@ bool MeiExporter::writeNote(const Note* note, const Chord* chord, const Staff* s
meiNote.SetDots(chord->dots());
}
this->writeBeamTypeAtt(chord, meiNote);
this->writeStaffIdenAtt(chord, staff, meiNote);
this->writeStaffIdentAtt(chord, staff, meiNote);
this->writeStemAtt(chord, meiNote);
this->writeArtics(chord);
this->writeVerses(chord);
Expand Down Expand Up @@ -1343,7 +1343,7 @@ bool MeiExporter::writeRest(const Rest* rest, const Staff* staff)
}
Convert::colorToMEI(rest, meiRest);
this->writeBeamTypeAtt(rest, meiRest);
this->writeStaffIdenAtt(rest, staff, meiRest);
this->writeStaffIdentAtt(rest, staff, meiRest);
// this->writeVerses(rest);
const char prefix = (rest->visible()) ? 'r' : 's';
std::string xmlId = this->getXmlIdFor(rest, prefix);
Expand Down Expand Up @@ -2053,7 +2053,7 @@ bool MeiExporter::writeBeamTypeAtt(const ChordRest* chordRest, libmei::AttTyped&
* Write the cross-staff attribute (@staff) for a ChordRest (i.e., chord, note, rest or space).
*/

bool MeiExporter::writeStaffIdenAtt(const ChordRest* chordRest, const Staff* staff, libmei::AttStaffIdent& staffIdentAtt)
bool MeiExporter::writeStaffIdentAtt(const ChordRest* chordRest, const Staff* staff, libmei::AttStaffIdent& staffIdentAtt)
{
if (chordRest->staffMove() != 0) {
staff_idx_t staffN = staff->idx() + chordRest->staffMove() + 1;
Expand Down
2 changes: 1 addition & 1 deletion src/importexport/mei/internal/meiexporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class MeiExporter
* Methods for writing specific MEI attribute classes within elements
*/
bool writeBeamTypeAtt(const engraving::ChordRest* chordRest, libmei::AttTyped& typeAtt);
bool writeStaffIdenAtt(const engraving::ChordRest* chordRest, const engraving::Staff* staff, libmei::AttStaffIdent& staffIdentAtt);
bool writeStaffIdentAtt(const engraving::ChordRest* chordRest, const engraving::Staff* staff, libmei::AttStaffIdent& staffIdentAtt);
bool writeStemAtt(const engraving::Chord* chord, libmei::AttStems& stemsAtt);

/**
Expand Down
4 changes: 2 additions & 2 deletions src/importexport/mei/tests/data/color-01.mei
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
<note xml:id="n12667r3" dur="4" pname="c" oct="5" />
</layer>
</staff>
<octave xml:id="oggpsks" dis="8" dis.place="above" startid="#nx5z8ek" color="#0433FF" endid="#n1p30nx0" />
<hairpin xml:id="h1ofeby0" form="cres" startid="#nx5z8ek" color="#0433FF" endid="#n12667r3" />
<octave xml:id="oggpsks" staff="1" dis="8" dis.place="above" startid="#nx5z8ek" color="#0433FF" endid="#n1p30nx0" />
<hairpin xml:id="h1ofeby0" form="cres" staff="1" startid="#nx5z8ek" color="#0433FF" endid="#n12667r3" />
<tie xml:id="t1cu6c7m" startid="#n12667r3" color="#0433FF" endid="#n1oshtpn" />
</measure>
<measure xml:id="m1dsz34o" n="4">
Expand Down
16 changes: 8 additions & 8 deletions src/importexport/mei/tests/data/dynamic-01.mei
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@
<note xml:id="ns8t4tw" dur="1" pname="c" oct="4" />
</layer>
</staff>
<dynam xml:id="dvuqhls" label="p" startid="#nrgzdcj" place="above">p</dynam>
<dynam xml:id="d1hg5le3" label="mp" startid="#n6si3n7">mp</dynam>
<dynam xml:id="d1n0kf96" label="sffz" startid="#n7c44ti">sffz</dynam>
<dynam xml:id="d1btxom9" label="sfz" startid="#nvtsktx">sfz</dynam>
<dynam xml:id="d1rbma6l" label="pp" startid="#ns8t4tw">pp</dynam>
<dynam xml:id="dvuqhls" label="p" staff="1" startid="#nrgzdcj" place="above">p</dynam>
<dynam xml:id="d1hg5le3" label="mp" staff="1" startid="#n6si3n7">mp</dynam>
<dynam xml:id="d1n0kf96" label="sffz" staff="1" startid="#n7c44ti">sffz</dynam>
<dynam xml:id="d1btxom9" label="sfz" layer="1" staff="1" startid="#nvtsktx">sfz</dynam>
<dynam xml:id="d1rbma6l" label="pp" staff="1" startid="#ns8t4tw">pp</dynam>
</measure>
<measure xml:id="m428gem" right="end" n="2">
<staff xml:id="m2s1" n="1">
Expand All @@ -76,9 +76,9 @@
</chord>
</layer>
</staff>
<dynam xml:id="d1pv19cd" label="mp" startid="#noxjpqs">sempre mp e <lb />dolce</dynam>
<dynam xml:id="da76h31" label="p" startid="#c1bio1o2">p e sempre<lb />dolce</dynam>
<dynam xml:id="dqa2pt" label="ff" startid="#c19y1p0c">molto ff</dynam>
<dynam xml:id="d1pv19cd" label="mp" staff="1" startid="#noxjpqs">sempre mp e <lb />dolce</dynam>
<dynam xml:id="da76h31" label="p" staff="1" startid="#c1bio1o2">p e sempre<lb />dolce</dynam>
<dynam xml:id="dqa2pt" label="ff" staff="1" startid="#c19y1p0c">molto ff</dynam>
</measure>
</section>
</score>
Expand Down
1 change: 1 addition & 0 deletions src/importexport/mei/tests/data/dynamic-01.mscx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
<Dynamic>
<subtype>sfz</subtype>
<velocity>112</velocity>
<voiceAssignment>currentVoiceOnly</voiceAssignment>
</Dynamic>
<Chord>
<durationType>eighth</durationType>
Expand Down
2 changes: 1 addition & 1 deletion src/importexport/mei/tests/data/ending-01.mei
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
<note xml:id="nj5abn7" dur="1" pname="b" oct="2" />
</layer>
</staff>
<tempo xml:id="t1sz2k2m" type="mscore-infer-from-text" tstamp="1.000000" midi.bpm="320.000000">
<tempo xml:id="t1sz2k2m" type="mscore-infer-from-text" staff="1" tstamp="1.000000" midi.bpm="320.000000">
<rend glyph.auth="smufl"></rend> = 160</tempo>
</measure>
<ending xml:id="e56vjvc" label="1." type="mscore-ending-1">
Expand Down
14 changes: 7 additions & 7 deletions src/importexport/mei/tests/data/hairpin-01.mei
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<mRest xml:id="mfs9r97" />
</layer>
</staff>
<hairpin xml:id="h1dor5os" form="cres" startid="#n1n2q0nd" endid="#n14xf1ls" />
<hairpin xml:id="h1dor5os" form="cres" staff="1" startid="#n1n2q0nd" endid="#n14xf1ls" />
</measure>
<measure xml:id="mcatpri" n="2">
<staff xml:id="m2s1" n="1">
Expand All @@ -74,8 +74,8 @@
<mRest xml:id="m1sz0e05" />
</layer>
</staff>
<dynam xml:id="d1eogas6" label="f" startid="#nspxw9k">f</dynam>
<hairpin xml:id="hniw3gu" form="dim" startid="#nspxw9k" endid="#n1w9pjbk" />
<dynam xml:id="d1eogas6" label="f" staff="1" startid="#nspxw9k">f</dynam>
<hairpin xml:id="hniw3gu" form="dim" staff="1" startid="#nspxw9k" endid="#n1w9pjbk" />
</measure>
<measure xml:id="mzs8qux" n="3">
<staff xml:id="m3s1" n="1">
Expand Down Expand Up @@ -121,7 +121,7 @@
<note xml:id="naukxk7" dur="4" pname="g" oct="2" />
</layer>
</staff>
<dynam xml:id="d16couhq" label="f" startid="#n1h73eje">f</dynam>
<dynam xml:id="d16couhq" label="f" staff="2" startid="#n1h73eje">f</dynam>
<dir xml:id="dxfp0cj" type="mscore-hairpin mscore-decresc" startid="#n1h73eje" extender="true" endid="#n4ihxav">dim.</dir>
</measure>
<measure xml:id="m1suce6e" n="6">
Expand Down Expand Up @@ -166,7 +166,7 @@
<mRest xml:id="mks294k" />
</layer>
</staff>
<hairpin xml:id="hjs1sym" form="cres" startid="#n9ff3t1" lform="dashed" place="above" endid="#n2tj1jf" />
<hairpin xml:id="hjs1sym" form="cres" staff="1" startid="#n9ff3t1" lform="dashed" place="above" endid="#n2tj1jf" />
</measure>
<measure xml:id="moaa1gv" n="9">
<staff xml:id="m9s1" n="1">
Expand All @@ -182,7 +182,7 @@
<mRest xml:id="m1okzahl" />
</layer>
</staff>
<hairpin xml:id="hhnn0kt" form="dim" startid="#nq8sgb7" lform="dotted" place="above" endid="#n19df3r8" />
<hairpin xml:id="hhnn0kt" form="dim" staff="1" startid="#nq8sgb7" lform="dotted" place="above" endid="#n19df3r8" />
</measure>
<measure xml:id="m1vhuhz5" n="10">
<staff xml:id="m10s1" n="1">
Expand Down Expand Up @@ -212,7 +212,7 @@
<note xml:id="ntcvrux" dur="4" pname="d" oct="3" />
</layer>
</staff>
<hairpin xml:id="heiz76k" form="cres" startid="#n1ahnf5i" place="above" endid="#nsqyndt" />
<hairpin xml:id="heiz76k" form="cres" staff="2" startid="#n1ahnf5i" place="above" endid="#nsqyndt" />
</measure>
<measure xml:id="mjmh4f6" n="12">
<staff xml:id="m12s1" n="1">
Expand Down
12 changes: 6 additions & 6 deletions src/importexport/mei/tests/data/octave-01.mei
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<mRest xml:id="s2l1_t0_1" />
</layer>
</staff>
<octave xml:id="m1ot1" dis="8" dis.place="above" startid="#s1l1_t1_2" endid="#s1l1_t5_4" />
<octave xml:id="m1ot1" staff="1" dis="8" dis.place="above" startid="#s1l1_t1_2" endid="#s1l1_t5_4" />
</measure>
<measure xml:id="m2" n="2">
<staff xml:id="m2s1" n="1">
Expand All @@ -74,7 +74,7 @@
<mRest xml:id="s2l1_t1_1" />
</layer>
</staff>
<octave xml:id="m2ot1" dis="15" dis.place="above" startid="#s1l1_t3_2" lform="solid" endid="#s1l1_t5_2" />
<octave xml:id="m2ot1" staff="1" dis="15" dis.place="above" startid="#s1l1_t3_2" lform="solid" endid="#s1l1_t5_2" />
</measure>
<measure xml:id="m3" n="3">
<staff xml:id="m3s1" n="1">
Expand Down Expand Up @@ -104,7 +104,7 @@
<note xml:id="s2l1_t15_4" dur="4" pname="d" oct="3" oct.ges="2" />
</layer>
</staff>
<octave xml:id="m4ot1" dis="8" dis.place="below" startid="#s2l1_t7_2" lform="dotted" endid="#s2l1_t17_4" />
<octave xml:id="m4ot1" staff="2" dis="8" dis.place="below" startid="#s2l1_t7_2" lform="dotted" endid="#s2l1_t17_4" />
</measure>
<measure xml:id="m5" n="5">
<staff xml:id="m5s1" n="1">
Expand All @@ -120,7 +120,7 @@
<note xml:id="s2l1_t19_4" dur="4" pname="g" oct="3" oct.ges="1" />
</layer>
</staff>
<octave xml:id="m5ot1" dis="15" dis.place="below" startid="#s2l1_t9_2" lendsym="none" endid="#s2l1_t11_2" />
<octave xml:id="m5ot1" staff="2" dis="15" dis.place="below" startid="#s2l1_t9_2" lendsym="none" endid="#s2l1_t11_2" />
</measure>
<measure xml:id="m6" n="6">
<staff xml:id="m6s1" n="1">
Expand Down Expand Up @@ -149,8 +149,8 @@
<rest xml:id="s2l1_t13_2" dur="2" />
</layer>
</staff>
<octave xml:id="m7ot1" dis="22" dis.place="above" startid="#s1l1_t6_1" extender="false" endid="#s1l1_t13_2" />
<octave xml:id="m7ot2" dis="22" dis.place="below" startid="#s2l1_t6_1" endid="#s2l1_t13_2" />
<octave xml:id="m7ot1" staff="1" dis="22" dis.place="above" startid="#s1l1_t6_1" extender="false" endid="#s1l1_t13_2" />
<octave xml:id="m7ot2" staff="2" dis="22" dis.place="below" startid="#s2l1_t6_1" endid="#s2l1_t13_2" />
</measure>
</section>
</score>
Expand Down
Loading