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 support for sostenuto pedal to MusicXML and MEI #20219

Merged
merged 13 commits into from Dec 4, 2023
21 changes: 20 additions & 1 deletion src/importexport/mei/internal/meiconverter.cpp
Expand Up @@ -2328,6 +2328,20 @@ void Convert::pedalFromMEI(engraving::Pedal* pedal, const libmei::Pedal& meiPeda
pedal->setEndHookType(engraving::HookType::HOOK_90);
}

// @func
if (meiPedal.GetFunc() == "soft") {
// This is just for importing MEI files and will not be exported
if (pedal->beginText() != "") {
pedal->setBeginText(u"una corda");
pedal->setContinueText(u"");
}
} else if (meiPedal.GetFunc() == "sostenuto") {
if (pedal->beginText() != "") {
pedal->setBeginText(u"<sym>keyboardPedalSost</sym>");
pedal->setContinueText(u"(<sym>keyboardPedalSost</sym>)");
}
}

// @color
Convert::colorlineFromMEI(pedal, meiPedal);
}
Expand All @@ -2339,7 +2353,7 @@ libmei::Pedal Convert::pedalToMEI(const engraving::Pedal* pedal)
// @dir
meiPedal.SetDir(libmei::pedalLog_DIR_down);

bool symbol = (pedal->beginText() == engraving::Pedal::PEDAL_SYMBOL);
bool symbol = (!pedal->beginText().isEmpty());
bool star = (pedal->endText() == engraving::Pedal::STAR_SYMBOL);

// @form
Expand All @@ -2351,6 +2365,11 @@ libmei::Pedal Convert::pedalToMEI(const engraving::Pedal* pedal)
meiPedal.SetForm(libmei::PEDALSTYLE_line);
}

// @func
if (pedal->beginText() == u"<sym>keyboardPedalSost</sym>" || pedal->beginText() == u"<sym>keyboardPedalS</sym>") {
meiPedal.SetFunc("sostenuto");
}

// @color
Convert::colorlineToMEI(pedal, meiPedal);

Expand Down
40 changes: 37 additions & 3 deletions src/importexport/mei/tests/data/pedal-01.mei
Expand Up @@ -110,17 +110,51 @@
<note xml:id="n1l2ndi8" dur="2" pname="e" oct="3" />
</layer>
</staff>
<pedal xml:id="ppabeif" dir="down" startid="#n2hbom" form="line" endid="#n5q6lda" />
<pedal xml:id="ppabeif" dir="down" startid="#n2hbom" form="line" endid="#nz3prom" />
</measure>
<measure xml:id="m4wkmip" right="end" n="6">
<measure xml:id="m4wkmip" n="6">
<staff xml:id="m6s1" n="1">
<layer xml:id="m6s1l1" n="1">
<mRest xml:id="m1kfd01j" />
</layer>
</staff>
<staff xml:id="m6s2" n="2">
<layer xml:id="m6s2l1" n="1">
<note xml:id="n5q6lda" dur="1" pname="c" oct="3" />
<note xml:id="nq9kjgk" dur="2" pname="g" oct="3" />
<note xml:id="nz3prom" dur="2" pname="e" oct="3" />
</layer>
</staff>
</measure>
<measure xml:id="m1xddgfa" n="7">
<staff xml:id="m7s1" n="1">
<layer xml:id="m7s1l1" n="1">
<mRest xml:id="m1tijj0h" />
</layer>
</staff>
<staff xml:id="m7s2" n="2">
<layer xml:id="m7s2l1" n="1">
<chord xml:id="c1355bah" dur="1">
<note xml:id="n18x98u8" pname="c" oct="3" />
<note xml:id="n11f0csg" pname="e" oct="3" />
<note xml:id="n17f32e3" pname="g" oct="3" />
</chord>
</layer>
</staff>
<pedal xml:id="p8rxxq9" dir="down" func="sostenuto" startid="#c1355bah" form="pedstar" endid="#c1cx1uhh" />
</measure>
<measure xml:id="mvtnhjb" right="end" n="8">
<staff xml:id="m8s1" n="1">
<layer xml:id="m8s1l1" n="1">
<mRest xml:id="mbahumz" />
</layer>
</staff>
<staff xml:id="m8s2" n="2">
<layer xml:id="m8s2l1" n="1">
<chord xml:id="c1cx1uhh" dur="1">
<note xml:id="n1x918h7" pname="c" oct="3" />
<note xml:id="nm617w5" pname="e" oct="3" />
<note xml:id="n17x5zeq" pname="g" oct="3" />
</chord>
</layer>
</staff>
</measure>
Expand Down
83 changes: 81 additions & 2 deletions src/importexport/mei/tests/data/pedal-01.mscx
Expand Up @@ -108,6 +108,22 @@
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
Expand Down Expand Up @@ -245,8 +261,7 @@
</Pedal>
<next>
<location>
<measures>1</measures>
<fractions>1/1</fractions>
<measures>2</measures>
</location>
</next>
</Spanner>
Expand All @@ -266,6 +281,62 @@
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>55</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>52</pitch>
<tpc>18</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Spanner type="Pedal">
<prev>
<location>
<measures>-2</measures>
</location>
</prev>
</Spanner>
<Spanner type="Pedal">
<Pedal>
<lineVisible>0</lineVisible>
<beginText>&lt;sym&gt;keyboardPedalSost&lt;/sym&gt;</beginText>
</Pedal>
<next>
<location>
<measures>1</measures>
<fractions>1/1</fractions>
</location>
</next>
</Spanner>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>48</pitch>
<tpc>14</tpc>
</Note>
<Note>
<pitch>52</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>55</pitch>
<tpc>15</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
Expand All @@ -274,6 +345,14 @@
<pitch>48</pitch>
<tpc>14</tpc>
</Note>
<Note>
<pitch>52</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>55</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<BarLine>
<subtype>end</subtype>
Expand Down
9 changes: 6 additions & 3 deletions src/importexport/musicxml/internal/musicxml/exportxml.cpp
Expand Up @@ -5156,12 +5156,15 @@ void ExportMusicXml::pedal(Pedal const* const pd, staff_idx_t staff, const Fract
pedalType = "change";
break;
case HookType::NONE:
pedalType = "resume";
pedalType = pd->lineVisible() ? "resume" : "start";
break;
default:
pedalType = "start";
}
signText = pd->beginText() == "" ? " sign=\"no\"" : " sign=\"yes\"";
signText = pd->beginText().isEmpty() ? " sign=\"no\"" : " sign=\"yes\"";
if (pd->beginText() == u"<sym>keyboardPedalSost</sym>" || pd->beginText() == u"<sym>keyboardPedalS</sym>") {
pedalType = "sostenuto";
}
} else {
if (!pd->endText().isEmpty() || pd->endHookType() == HookType::HOOK_90) {
pedalType = "stop";
Expand All @@ -5170,7 +5173,7 @@ void ExportMusicXml::pedal(Pedal const* const pd, staff_idx_t staff, const Fract
}
// "change" type is handled only on the beginning of pedal lines

signText = pd->endText() == "" ? " sign=\"no\"" : " sign=\"yes\"";
signText = pd->endText().isEmpty() ? " sign=\"no\"" : " sign=\"yes\"";
}
pedalXml = QString("pedal type=\"%1\"").arg(pedalType);
pedalXml += lineText;
Expand Down
12 changes: 11 additions & 1 deletion src/importexport/musicxml/internal/musicxml/importmxmlpass2.cpp
Expand Up @@ -3531,7 +3531,7 @@ void MusicXMLParserDirection::pedal(const QString& type, const int /* number */,
}
}
auto& spdesc = _pass2.getSpanner({ ElementType::PEDAL, number });
if (type == "start" || type == "resume") {
if (type == "start" || type == "resume" || type == "sostenuto") {
if (spdesc._isStarted && !spdesc._isStopped) {
// Previous pedal unterminated—likely an unrecorded "discontinue", so delete the line.
// TODO: if "change", create 0-length spanner rather than delete
Expand All @@ -3547,7 +3547,13 @@ void MusicXMLParserDirection::pedal(const QString& type, const int /* number */,
if (!p->lineVisible() || sign == "yes") {
p->setBeginText(u"<sym>keyboardPedalPed</sym>");
p->setContinueText(u"(<sym>keyboardPedalPed</sym>)");
if (type == "sostenuto") {
p->setBeginText(u"<sym>keyboardPedalSost</sym>");
rettinghaus marked this conversation as resolved.
Show resolved Hide resolved
p->setContinueText(u"(<sym>keyboardPedalSost</sym>)");
}
} else {
p->setBeginText(u"");
p->setContinueText(u"");
p->setBeginHookType(type == "resume" ? HookType::NONE : HookType::HOOK_90);
}
p->setEndHookType(HookType::NONE);
Expand Down Expand Up @@ -3592,6 +3598,10 @@ void MusicXMLParserDirection::pedal(const QString& type, const int /* number */,
} else {
p->setLineVisible(false);
}
if (sign == "no") {
p->setBeginText(u"");
p->setContinueText(u"");
}
if (color.isValid()) {
p->setColor(color);
}
Expand Down
4 changes: 2 additions & 2 deletions src/importexport/musicxml/tests/data/testDirections1.xml
Expand Up @@ -102,7 +102,7 @@
<measure number="2">
<direction placement="above">
<direction-type>
<pedal type="resume" line="no" sign="yes"/>
<pedal type="start" line="no" sign="yes"/>
</direction-type>
</direction>
<note>
Expand Down Expand Up @@ -132,7 +132,7 @@
</note>
<direction placement="below">
<direction-type>
<pedal type="resume" line="no" sign="yes"/>
<pedal type="start" line="no" sign="yes"/>
</direction-type>
</direction>
<note>
Expand Down
4 changes: 2 additions & 2 deletions src/importexport/musicxml/tests/data/testDirections1_ref.xml
Expand Up @@ -102,7 +102,7 @@
<measure number="2">
<direction placement="above">
<direction-type>
<pedal type="resume" line="no" sign="yes"/>
<pedal type="start" line="no" sign="yes"/>
</direction-type>
</direction>
<note>
Expand Down Expand Up @@ -132,7 +132,7 @@
</note>
<direction placement="below">
<direction-type>
<pedal type="resume" line="no" sign="yes"/>
<pedal type="start" line="no" sign="yes"/>
</direction-type>
</direction>
<note>
Expand Down