verovio
verovio copied to clipboard
dynam dir alignment
In the example from Brahms op. 116/6 the ‘p’ and the “dol. e ben legato’ are on the same line:
Typically, one would encode the first as <dynam>
, the second as <dir>
.
The same is true for the this example from K. 581/02, where the dynamic mark and the performance mark are meant to be read as one single expression. ‘p con sordino‘ (Of course, the ‘con sordino’ refers to first note as well, just like the p):
Vertical alignment of different elements such as <dynam>
and <dir>
with @vgrp
would be desirable.
Here is the code for K. 581/02:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<mei meiversion="4.0.0" xmlns="http://www.music-encoding.org/ns/mei">
<meiHead>
<fileDesc>
<titleStmt>
<title>K.581/02</title>
<respStmt/>
</titleStmt>
<pubStmt/>
</fileDesc>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv_543002">
<score xml:id="score_480">
<scoreDef key.mode="major" key.pname="d" key.sig="2s" meter.count="3" meter.unit="4" xml:id="scoreDef_01">
<staffGrp bar.thru="true" symbol="bracket" xml:id="staffGrp_01">
<staffDef clef.line="2" clef.shape="G" key.sig="1f" lines="5" n="1" trans.diat="-2" trans.semi="-3" xml:id="staffDef_P1">
<label xml:id="label_P1">Clarinetto <lb xml:id="lb_P1"/>in La/A</label>
</staffDef>
<staffGrp symbol="brace" xml:id="staffGrp_02">
<staffDef clef.line="2" clef.shape="G" lines="5" n="2" xml:id="staffDef_P2">
<label xml:id="label_P2">Violino I</label>
</staffDef>
<staffDef clef.line="2" clef.shape="G" lines="5" n="3" xml:id="staffDef_P3">
<label xml:id="label_P3">Violino II</label>
</staffDef>
</staffGrp>
<staffDef clef.line="3" clef.shape="C" lines="5" n="4" xml:id="staffDef_P4">
<label xml:id="label_P4">Viola</label>
</staffDef>
<staffDef clef.line="4" clef.shape="F" lines="5" n="5" xml:id="staffDef_P5">
<label xml:id="label_P5">Violoncello</label>
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section_564">
<measure facs="#zoneOf_measure1" n="1" xml:id="m1_k581_002">
<tempo midi.bpm="55" place="above" staff="1" tstamp="1" xml:id="tempo01">Larghetto</tempo>
<staff n="1" xml:id="staff_3876">
<layer n="1" xml:id="layer_3882">
<note dots="1" dur="4" oct="5" pname="c" tstamp="1" xml:id="note_3888"/>
<beam xml:id="beam_3894">
<note dur="8" oct="5" pname="f" tstamp="2.5" xml:id="note_3900"/>
<note dur="8" oct="5" pname="a" tstamp="3" xml:id="note_3906"/>
<note dur="8" oct="5" pname="f" tstamp="3.5" xml:id="note_3912"/>
</beam>
</layer>
</staff>
<staff n="2" xml:id="staff_3918">
<layer n="1" xml:id="layer_3924">
<beam xml:id="beam_3930">
<note accid.ges="s" dur="8" oct="4" pname="f" tstamp="1" xml:id="note_3936"/>
<note dur="8" oct="4" pname="d" tstamp="1.5" xml:id="note_3942"/>
<note accid.ges="s" dur="8" oct="4" pname="f" tstamp="2" xml:id="note_3948"/>
<note dur="8" oct="4" pname="d" tstamp="2.5" xml:id="note_3954"/>
<note accid.ges="s" dur="8" oct="4" pname="f" tstamp="3" xml:id="note_3960"/>
<note dur="8" oct="4" pname="d" tstamp="3.5" xml:id="note_3966"/>
</beam>
</layer>
</staff>
<staff n="3" xml:id="staff_3972">
<layer n="1" xml:id="layer_3978">
<beam xml:id="beam_3984">
<note dur="8" oct="4" pname="d" tstamp="1" xml:id="note_3990"/>
<note dur="8" oct="3" pname="a" tstamp="1.5" xml:id="note_3996"/>
<note dur="8" oct="4" pname="d" tstamp="2" xml:id="note_4002"/>
<note dur="8" oct="3" pname="a" tstamp="2.5" xml:id="note_4008"/>
<note dur="8" oct="4" pname="d" tstamp="3" xml:id="note_4014"/>
<note dur="8" oct="3" pname="a" tstamp="3.5" xml:id="note_4020"/>
</beam>
</layer>
</staff>
<staff n="4" xml:id="staff_4026">
<layer n="1" xml:id="layer_4032">
<beam xml:id="beam_4038">
<note dur="8" oct="3" pname="a" tstamp="1" xml:id="note_4044"/>
<note accid.ges="s" dur="8" oct="3" pname="f" tstamp="1.5" xml:id="note_4050"/>
<note dur="8" oct="3" pname="a" tstamp="2" xml:id="note_4056"/>
<note accid.ges="s" dur="8" oct="3" pname="f" tstamp="2.5" xml:id="note_4062"/>
<note dur="8" oct="3" pname="a" tstamp="3" xml:id="note_4068"/>
<note accid.ges="s" dur="8" oct="3" pname="f" tstamp="3.5" xml:id="note_4074"/>
</beam>
</layer>
</staff>
<staff n="5" xml:id="staff_4080">
<layer n="1" xml:id="layer_4086">
<note dots="1" dur="2" oct="3" pname="d" tstamp="1" xml:id="note_4092"/>
</layer>
</staff>
<dynam staff="1" startid="#note_3888" xml:id="dynam_4098">p</dynam>
<dynam staff="2" startid="#note_3936" xml:id="dynam_4110" vgrp="1">p</dynam>
<dynam staff="3" startid="#note_3990" xml:id="dynam_4122" vgrp="1">p</dynam>
<dynam staff="4" startid="#note_4044" xml:id="dynam_4134" vgrp="1">p</dynam>
<dynam staff="5" startid="#note_4092" xml:id="dynam_4146">p</dynam>
<dir place="below" staff="2" tstamp="1.2" xml:id="dir_4164" vgrp="1">
<rend fontstyle="normal" xml:id="rend_4164">con sordino</rend>
</dir>
<dir place="below" staff="3" tstamp="1.2" xml:id="dir_4176" vgrp="1">
<rend fontstyle="normal" xml:id="rend_4176">con sordino</rend>
</dir>
<supplied xml:id="supplied_4177">
<dir place="below" staff="4" tstamp="1.2" xml:id="dir_4177" vgrp="1">
<rend fontstyle="normal" xml:id="rend_4177">con sordino</rend>
</dir>
</supplied>
<slur endid="#note_3912" staff="1" startid="#note_3888" xml:id="slur_4188"/>
<slur endid="#note_3966" staff="2" startid="#note_3936" xml:id="slur_4194"/>
<slur endid="#note_4020" staff="3" startid="#note_3990" xml:id="slur_4200"/>
<slur endid="#note_4074" staff="4" startid="#note_4044" xml:id="slur_4206"/>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Slightly related to issue https://github.com/rism-ch/verovio/issues/1117.
One solution is to treat the combined text as a composite <dir>
, embedding the dynamic within the <dir>
. This would be an appropriate solution for cases such as this example from the first movement of Beethoven's moonlight sonata:
So something like
<dir>
sempre <dynam>pp</dynam> e senza sordini
</dir>
seems to be the best solution.
If there is no solution for this yet, it would be good to come up with one, as this sort of case is quite common. @vgrp
solves the horizontal alignment, but there is also the question of precedence: when multiple <dir>
and/or <dynam>
occur on the same note or timestamp, which one gets to go first, and which one gets moved to the end of the previous one? The order should not be faked by giving a slightly different timestamp to each dir/dynam.
This is somewhat similar to the case where a dynamic and a hairpin are attached to the same note. This case has been implemented:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2019-10-03T11:37:36" version="2.2.0-dev-33affbd-dirty">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000000937936252">
<score xml:id="score-0000001067919542">
<scoreDef xml:id="scoredef-0000000018255301" midi.bpm="400">
<staffGrp xml:id="staffgrp-0000001378649291">
<staffDef xml:id="staffdef-0000000997717923" n="1" lines="5">
<clef xml:id="clef-0000000488214972" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="4" unit="4" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1" n="0">
<staff xml:id="staff-0000000240671000" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<note xml:id="note-L4F1" dur="1" oct="4" pname="c" accid.ges="n" />
</layer>
</staff>
<dynam xml:id="dynam-L4F2" staff="1" tstamp="1.000000" vgrp="100">p</dynam>
<hairpin xml:id="hairpin-L4F2" staff="1" tstamp="1.000000" tstamp2="1m+1.0000" form="cres" vgrp="100" />
</measure>
<measure xml:id="measure-L5" n="2">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="1" oct="4" pname="d" accid.ges="n" />
</layer>
</staff>
<dynam xml:id="dynam-L6F2" staff="1" tstamp="1.000000" vgrp="100">f</dynam>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Here is a similar case that has not yet been addressed, where there is a mixture of a dynamic and a text direction:
In this case there is not enough information about whether the combined text should be p cresc.
or cresc. p
. Inferring the order is not good, since there are also reverse cases like subito p
.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://music-encoding.org/schema/4.0.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="4.0.0">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2019-10-03T11:39:17" version="2.2.0-dev-33affbd-dirty">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000001545811197">
<score xml:id="score-0000001790224813">
<scoreDef xml:id="scoredef-0000002129172812" midi.bpm="400">
<staffGrp xml:id="staffgrp-0000000549950010">
<staffDef xml:id="staffdef-0000001813418073" n="1" lines="5">
<clef xml:id="clef-0000000249622694" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="4" unit="4" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1" n="0">
<staff xml:id="staff-0000000580227469" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<note xml:id="note-L4F1" dur="1" oct="4" pname="c" accid.ges="n" />
</layer>
</staff>
<dynam xml:id="dynam-L4F2" staff="1" tstamp="1.000000" vgrp="100">p</dynam>
<dir xml:id="dir-L4F2" staff="1" vgrp="100" tstamp="1.000000">cresc.</dir>
</measure>
<measure xml:id="measure-L5" n="2">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="1" oct="4" pname="d" accid.ges="n" />
</layer>
</staff>
<dynam xml:id="dynam-L6F2" staff="1" tstamp="1.000000" vgrp="100">f</dynam>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
The order should not be faked by giving a slightly different timestamp to each dir/dynam.
This is an important point!
I like the <dynam>
nested into the <dir>
because it's simple, but something in my guts says, that this is not the solution.
What about a horizontal sequence controlled by @next
and @prev
?
What about a horizontal sequence controlled by
@next
and@prev
?
That sounds good to me.
Another way to look at this issue would be to make verovio render dynamic abbreviation, including within text, with the music font. Then you would simply have:
<dynam>
sempre pp e senza sordini
</dynam>
(I think this is something Lilypond does.) Alternatively, we could require a <rend>
to be added around the 'pp', but I am not sure this is actually necessary.
@ndubo support for @vgrp
should be added anyway.
A problem is that the pp
in sempre pp e senza sordini
needs to be identified as the dynamic to play the music. In other words when converting to MIDI, a converter needs to see the pp
as a dynamic to perform the music in. Conversely, if the dynamic in some text does not refer to the current dynamic of the music, there should be a way of telling the MIDI renderer not to use that dynamic in the performance rendering.
There are a lot of dynamics: p pp ppp pppp pppp etc, same for f, mp, mf, mfp fp pf ffp and also accents sf sfz sffz fz ffz etc. so it would be difficult to automatically identify all of them with 100% accuracy in order to give them the correct font (so using a <rend>
would probably be safer.
There are also case, particularly in 18th century music, where the printed dynamics are displayed in a roman-like font and the editorial dynamics are using the modern dynamic font, so some encoders would want to control the font of the dynamics.
This is the list of supported dynamics : https://w3c.github.io/smufl/gitbook/tables/dynamics.html
I think we can support them within dynam strings. For other cases, then <rend>
should be used, but this will yield other issues when letters are missing. The alignment of the letters will be another issue but let's not discuss it here. MIDI conversion should also be addressed in another issue when dynamics will be taken into account.
<dynam>
sempre pp e senza sordini
</dynam>
is now rendered as
@craigsapp : if you do not want to have this you can do
<dynam>
<rend fontfam="Times">sempre pp e senza sordini</rend>
</dynam>
@ndubo looking at the alignment of dir with dynam, I think we have a problem. Normally the order for laying out control event is:
- mordent / turn / trill
- dynam / hairpin
- brackets
- octave
- breath
- fermata
- dir
- tempo
- pedal
- harm
- (ending)
Grouping dynam and dir causes a problem. We can change the order and align dir with dynam / hairpin, but then there will be other complains. Any ideas what the algorithm should be?