verovio
verovio copied to clipboard
Time-reversed beamSpan@plist behavior
When the time order of ID references in a beamSpan@plist
are reversed, the slope of the beam is negated, caused by the assumption that the plist is time sorted (or at least that the endpoints are time sorted).
Here is an example:
![Screen Shot 2022-02-20 at 5 40 27 PM](https://user-images.githubusercontent.com/3487289/154875481-3ac5c7ac-cfb0-4444-8cbe-d37758cc85bd.png)
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2022-02-20T17:37:39" version="3.9.0-dev-93a6934">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="my1g1q7">
<score xml:id="subgqe3">
<scoreDef xml:id="sdi2iao">
<staffGrp xml:id="sfodwl6">
<staffDef xml:id="sscfq3m" n="1" lines="5">
<clef xml:id="cl21gk7" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="3" unit="8" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1">
<staff xml:id="s6qlbpv" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<rest xml:id="rest-L3F1" dur="4" />
<note xml:id="note-L4F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="ba8be3h" plist="#note-L7F1 #note-L6F1 #note-L4F1" startid="#note-L4F1" endid="#note-L7F1" />
</measure>
<measure xml:id="measure-L5">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="8" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L7F1" dur="8" oct="4" pname="c" accid.ges="n" />
<rest xml:id="rest-L8F1" dur="8" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L9">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<rest xml:id="rest-L10F1" dur="4" />
<note xml:id="note-L11F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="bajjy18" plist="#note-L14F1 #note-L13F1 #note-L11F1" startid="#note-L11F1" endid="#note-L14F1" />
</measure>
<measure xml:id="measure-L12">
<staff xml:id="staff-L12F1N1" n="1">
<layer xml:id="layer-L12F1N1" n="1">
<note xml:id="note-L13F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L14F1" dur="8" oct="4" pname="g" accid.ges="n" />
<rest xml:id="rest-L15F1" dur="8" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Putting the ID refs in time order fixes the problem:
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2022-02-20T17:37:39" version="3.9.0-dev-93a6934">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="my1g1q7">
<score xml:id="subgqe3">
<scoreDef xml:id="sdi2iao">
<staffGrp xml:id="sfodwl6">
<staffDef xml:id="sscfq3m" n="1" lines="5">
<clef xml:id="cl21gk7" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="3" unit="8" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1">
<staff xml:id="s6qlbpv" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<rest xml:id="rest-L3F1" dur="4" />
<note xml:id="note-L4F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="ba8be3h" plist="#note-L4F1 #note-L6F1 #note-L7F1" startid="#note-L4F1" endid="#note-L7F1" />
</measure>
<measure xml:id="measure-L5">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="8" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L7F1" dur="8" oct="4" pname="c" accid.ges="n" />
<rest xml:id="rest-L8F1" dur="8" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L9">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<rest xml:id="rest-L10F1" dur="4" />
<note xml:id="note-L11F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="bajjy18" plist="#note-L11F1 #note-L13F1 #note-L14F1" startid="#note-L11F1" endid="#note-L14F1" />
</measure>
<measure xml:id="measure-L12">
<staff xml:id="staff-L12F1N1" n="1">
<layer xml:id="layer-L12F1N1" n="1">
<note xml:id="note-L13F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L14F1" dur="8" oct="4" pname="g" accid.ges="n" />
<rest xml:id="rest-L15F1" dur="8" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Of course, it is more logical to place the @plist
in time-sorted order, but I do not see that requirement here: https://music-encoding.org/guidelines/dev/attribute-classes/att.plist.html
Putting a sanity check to test if the @plist
is time ordered would be good (checking against reverse time order and random order). If discouraged, then perhaps add a time order rule for beamSpan@plist
in MEI Schematron.
An interesting case occurs if the @plist
does not include the @startid
or @endid
elements:
![Screen Shot 2022-02-20 at 5 55 27 PM](https://user-images.githubusercontent.com/3487289/154876745-68a8a357-f053-49a9-9f1e-524b59918c71.png)
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2022-02-20T17:37:39" version="3.9.0-dev-93a6934">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="my1g1q7">
<score xml:id="subgqe3">
<scoreDef xml:id="sdi2iao">
<staffGrp xml:id="sfodwl6">
<staffDef xml:id="sscfq3m" n="1" lines="5">
<clef xml:id="cl21gk7" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="3" unit="8" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1">
<staff xml:id="s6qlbpv" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<rest xml:id="rest-L3F1" dur="4" />
<note xml:id="note-L4F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="ba8be3h" plist="#note-L4F1 #note-L6F1" startid="#note-L4F1" endid="#note-L7F1" />
</measure>
<measure xml:id="measure-L5">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="8" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L7F1" dur="8" oct="4" pname="c" accid.ges="n" />
<rest xml:id="rest-L8F1" dur="8" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L9">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<rest xml:id="rest-L10F1" dur="4" />
<note xml:id="note-L11F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="bajjy18" plist="#note-L13F1 #note-L14F1" startid="#note-L11F1" endid="#note-L14F1" />
</measure>
<measure xml:id="measure-L12">
<staff xml:id="staff-L12F1N1" n="1">
<layer xml:id="layer-L12F1N1" n="1">
<note xml:id="note-L13F1" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L14F1" dur="8" oct="4" pname="g" accid.ges="n" />
<rest xml:id="rest-L15F1" dur="8" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
This is a corner case to think about: Probably it is better to allow the @startid
and @endid
ID refs to be added to @plist
if they are not present in the list? Otherwise, printing a warning would be good when the @startid
or @endid
are not included in @plist
(if @plist
is explicitly given).
This leads to interesting cases where (1) The endpoints are excluded, and there is a single-note beam in the next example (which results in a visual quarter note). And (2) where the non-plist notes are not attached to the beam:
![Screen Shot 2022-02-20 at 6 11 50 PM](https://user-images.githubusercontent.com/3487289/154877740-ea35a636-996a-4e3b-b3bf-675f23b7ddf3.png)
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2022-02-20T17:37:39" version="3.9.0-dev-93a6934">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="my1g1q7">
<score xml:id="subgqe3">
<scoreDef xml:id="sdi2iao">
<staffGrp xml:id="sfodwl6">
<staffDef xml:id="sscfq3m" n="1" lines="5">
<clef xml:id="cl21gk7" shape="G" line="2" />
<meterSig xml:id="metersig-L2F1" count="3" unit="8" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1">
<staff xml:id="s6qlbpv" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<rest xml:id="rest-L3F1" dur="4" />
<note xml:id="note-L4F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="ba8be3h" plist="#note-L6F1" startid="#note-L4F1" endid="#note-L7F1" />
</measure>
<measure xml:id="measure-L5">
<staff xml:id="staff-L5F1N1" n="1">
<layer xml:id="layer-L5F1N1" n="1">
<note xml:id="note-L6F1" dur="8" oct="4" pname="d" accid.ges="n" />
<note xml:id="note-L7F1" dur="8" oct="4" pname="c" accid.ges="n" />
<rest xml:id="rest-L8F1" dur="8" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L9">
<staff xml:id="staff-L9F1N1" n="1">
<layer xml:id="layer-L9F1N1" n="1">
<rest xml:id="rest-L10F1" dur="4" />
<note xml:id="note-L11F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="bajjy18" plist="#note-L11F1 #note-L14F1" startid="#note-L11F1" endid="#note-L14F1" />
</measure>
<measure xml:id="measure-L12">
<staff xml:id="staff-L12F1N1" n="1">
<layer xml:id="layer-L12F1N1" n="1">
<note xml:id="note-L13F1" stem.dir="down" dur="8" oct="4" pname="f" accid.ges="n" />
<note xml:id="note-L14F1" dur="8" oct="4" pname="g" accid.ges="n" />
<rest xml:id="rest-L15F1" dur="8" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
The first case is not desired (since the eighth note looks like a quarter note), but the second case is useful to create a single layer with interlocking beamSpans:
![Screen Shot 2022-02-20 at 6 20 21 PM](https://user-images.githubusercontent.com/3487289/154878549-ec40a442-785d-4c7d-9bf5-6d9ac790646d.png)
Click to view MEI data for above example
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/dev/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0.0-dev">
<meiHead>
<fileDesc>
<titleStmt>
<title />
</titleStmt>
<pubStmt />
</fileDesc>
<encodingDesc>
<appInfo>
<application isodate="2022-02-20T18:14:39" version="3.9.0-dev-93a6934">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mri4t7s">
<score xml:id="s9lhrs0">
<scoreDef xml:id="s3nbx86">
<staffGrp xml:id="s95jbbt">
<staffDef xml:id="s8t0tdi" n="1" lines="5">
<clef xml:id="c2g68nc" 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">
<staff xml:id="snawn0w" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<note xml:id="note-L3F1" type="placed" dur="8" oct="4" pname="b" stem.dir="up" accid.ges="n" />
<note xml:id="note-L4F1" type="placed" dur="8" oct="4" pname="b" stem.dir="down" accid.ges="n" />
<note xml:id="note-L5F1" type="placed" dur="8" oct="4" pname="b" stem.dir="up" accid.ges="n" />
<note xml:id="note-L6F1" type="placed" dur="8" oct="4" pname="b" stem.dir="down" accid.ges="n" />
<note xml:id="note-L8F1" type="placed" dur="8" oct="4" pname="b" stem.dir="up" accid.ges="n" />
<note xml:id="note-L9F1" type="placed" dur="8" oct="4" pname="b" stem.dir="down" accid.ges="n" />
<note xml:id="note-L10F1" type="placed" dur="8" oct="4" pname="b" stem.dir="up" accid.ges="n" />
<note xml:id="note-L11F1" type="placed" dur="8" oct="4" pname="b" stem.dir="down" accid.ges="n" />
</layer>
</staff>
<beamSpan xml:id="bbtkp99" plist="#note-L3F1 #note-L5F1" startid="#note-L3F1" endid="#note-L5F1" />
<beamSpan xml:id="asegser" plist="#note-L4F1 #note-L6F1" startid="#note-L4F1" endid="#note-L6F1" />
<beamSpan xml:id="est32te" plist="#note-L8F1 #note-L10F1" startid="#note-L8F1" endid="#note-L10F1" />
<beamSpan xml:id="f32tewe" plist="#note-L9F1 #note-L11F1" startid="#note-L9F1" endid="#note-L11F1" />
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>