mei2hum: multi-measure rests
Closed this issue · 5 comments
Currently multi-measure rests (element multiRest) are not converted. See attached MEI file.
a.mei.zip
In VHV a sequence of whole measure rests is encoded as a sequence of rests. For OMR purposes, I propose something like:
rr<N>
were stands for the number of measures the rest spans (e.g. rr21 would encode the muti-measure rest below). For measures occupied by the rest the null token can be used.
You can paste MEI text directly into the issues by adding a line that started with three back quotes followed by xml
(which allows the data to be colorized), then a newline followed by the file contents, then ended with three back quotes on a line by themselves:
(then I do not have to unzip to look at the data :-)
<?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>
<date>2017-08-29 20:22:12</date>
</pubStmt>
</fileDesc>
<encodingDesc>
<projectDesc>
<p>Encoded with Verovio version 2.0.0-dev-cba6710</p>
</projectDesc>
</encodingDesc>
</meiHead>
<music>
<body>
<mdiv>
<score>
<scoreDef xml:id="scoredef-0000000217865287" key.sig="2s" meter.count="3" meter.unit="8">
<staffGrp xml:id="staffgrp-0000000250901313">
<staffDef xml:id="staffdef-0000001387968530" clef.shape="G" clef.line="2" n="1" lines="5" />
</staffGrp>
</scoreDef>
<section xml:id="section-0000002084467629">
<measure xml:id="measure-0000000804640754" right="single">
<staff xml:id="staff-0000001746707092" n="1">
<layer xml:id="layer-0000000390544858" n="1">
<multiRest xml:id="multirest-0000001177403174" num="21" />
</layer>
</staff>
</measure>
<measure xml:id="measure-0000000559856503" right="single">
<staff xml:id="staff-0000001700821960" n="1">
<layer xml:id="layer-0000000584447299" n="1">
<rest xml:id="rest-0000000215552915" dur="4" />
<note xml:id="note-0000002140413563" dur="8" oct="4" pname="d" />
</layer>
</staff>
</measure>
<measure xml:id="measure-0000001693620732" right="single">
<staff xml:id="staff-0000001432182444" n="1">
<layer xml:id="layer-0000000210393664" n="1">
<beam xml:id="beam-0000000433569437">
<note xml:id="note-0000001328227886" dots="1" dur="8" oct="4" pname="a" />
<note xml:id="note-0000000589513388" dur="16" oct="4" pname="g" />
</beam>
<note xml:id="note-0000001609448505" dur="8" oct="4" pname="f" />
</layer>
</staff>
</measure>
<measure xml:id="measure-0000001026552233" right="single">
<staff xml:id="staff-0000000297005923" n="1">
<layer xml:id="layer-0000000602258485" n="1">
<note xml:id="note-0000001067929084" dur="16" oct="4" pname="g" grace="unacc" stem.dir="up" />
<note xml:id="note-0000000015793162" dur="8" oct="4" pname="b" />
<note xml:id="note-0000001295185153" dur="8" oct="4" pname="a" />
<beam xml:id="beam-0000000561541967">
<note xml:id="note-0000001282620479" dur="16" oct="4" pname="f" />
<note xml:id="note-0000001792694451" dur="16" oct="5" pname="d" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-0000001935028185" right="single">
<staff xml:id="staff-0000000620070547" n="1">
<layer xml:id="layer-0000000564880678" n="1">
<beam xml:id="beam-0000002037816184">
<note xml:id="note-0000002071835406" dur="8" oct="4" pname="g" />
<note xml:id="note-0000001507402132" dur="8" oct="4" pname="f" />
</beam>
<note xml:id="note-0000001043048865" dur="8" oct="4" pname="e" />
</layer>
</staff>
</measure>
<measure xml:id="measure-0000001347202405" right="single">
<staff xml:id="staff-0000000613263594" n="1">
<layer xml:id="layer-0000001397882918" n="1">
<note xml:id="note-0000000747104646" dots="1" dur="4" oct="4" pname="f" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Current conversion to Humdrum with mei2hum, with the missing multi-bar rest and a complaint about it:
Don't know how to process layer/multiRest in measure 0
Warning: GridSlice is null in GridMeasure 1
**kern
*part1
*staff1
*clefG2
*k[f#c#]
*M3/8
4r
8d
=1
8.aL
16gJ
8f
=2
16qg
8b
8a
16fL
16ddJ
=3
8gL
8fJ
8e
=4
4.f
=
*-
The syntax rr<N>
cannot be allowed because all digits in **kern
data must be **recip
numbers for the rhythms of the notes. If numbers for other purposes are allowed, then standard methods of extracting rhythmic data from **kern
spines would become confused.
The preferred method for representing the mutibar rest is to give it in an expanded form, which I will work on adding to the converter. Here is the expected conversion for this MEI data:
**kern
*part1
*staff1
*clefG2
*k[f#c#]
*M3/8
=1
4.r
=2
4.r
=3
4.r
=4
4.r
=5
4.r
=6
4.r
=7
4.r
=8
4.r
=9
4.r
=10
4.r
=11
4.r
=12
4.r
=13
4.r
=14
4.r
=15
4.r
=16
4.r
=17
4.r
=18
4.r
=19
4.r
=20
4.r
=21
4.r
=22
4r
8d
=23
8.aL
16gJ
8f
=24
16qg
8b
8a
16fL
16ddJ
=25
8gL
8fJ
8e
=26
4.f
=
*-
which will convert back into MEI similar to the original MEI data:
<?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"?>
<?xml-model href="https://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="2020-03-11T21:11:40" version="2.6.0-dev-098781c">
<name>Verovio</name>
<p>Transcoded from Humdrum</p>
</application>
</appInfo>
</encodingDesc>
<workList>
<work>
<title />
</work>
</workList>
</meiHead>
<music>
<body>
<mdiv xml:id="mdiv-0000000518102036">
<score xml:id="score-0000001985278622">
<scoreDef xml:id="scoredef-0000000634086122">
<staffGrp xml:id="staffgrp-0000000338546106">
<staffDef xml:id="staffdef-0000000706752111" n="1" lines="5">
<clef xml:id="clef-L4F1" shape="G" line="2" />
<keySig xml:id="keysig-L5F1" sig="2s" />
<meterSig xml:id="metersig-L6F1" count="3" unit="8" />
</staffDef>
</staffGrp>
</scoreDef>
<section xml:id="section-L1F1">
<measure xml:id="measure-L1" n="1">
<staff xml:id="staff-0000000919147998" n="1">
<layer xml:id="layer-L1F1N1" n="1">
<multiRest xml:id="multirest-0000001751757302" num="21" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L49" n="22">
<staff xml:id="staff-L49F1N1" n="1">
<layer xml:id="layer-L49F1N1" n="1">
<rest xml:id="rest-L50F1" dur="4" />
<note xml:id="note-L51F1" dur="8" oct="4" pname="d" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L52" n="23">
<staff xml:id="staff-L52F1N1" n="1">
<layer xml:id="layer-L52F1N1" n="1">
<beam xml:id="beam-L53F1-L54F1">
<note xml:id="note-L53F1" dots="1" dur="8" oct="4" pname="a" accid.ges="n" />
<note xml:id="note-L54F1" dur="16" oct="4" pname="g" accid.ges="n" />
</beam>
<note xml:id="note-L55F1" dur="8" oct="4" pname="f" accid="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L56" n="24">
<staff xml:id="staff-L56F1N1" n="1">
<layer xml:id="layer-L56F1N1" n="1">
<note xml:id="note-L57F1" dur="16" oct="4" pname="g" grace="unacc" accid.ges="n" />
<note xml:id="note-L58F1" dur="8" oct="4" pname="b" accid.ges="n" />
<note xml:id="note-L59F1" dur="8" oct="4" pname="a" accid.ges="n" />
<beam xml:id="beam-L60F1-L61F1">
<note xml:id="note-L60F1" dur="16" oct="4" pname="f" accid="n" />
<note xml:id="note-L61F1" dur="16" oct="5" pname="d" accid.ges="n" />
</beam>
</layer>
</staff>
</measure>
<measure xml:id="measure-L62" n="25">
<staff xml:id="staff-L62F1N1" n="1">
<layer xml:id="layer-L62F1N1" n="1">
<beam xml:id="beam-L63F1-L64F1">
<note xml:id="note-L63F1" dur="8" oct="4" pname="g" accid.ges="n" />
<note xml:id="note-L64F1" dur="8" oct="4" pname="f" accid="n" />
</beam>
<note xml:id="note-L65F1" dur="8" oct="4" pname="e" accid.ges="n" />
</layer>
</staff>
</measure>
<measure xml:id="measure-L66" n="26">
<staff xml:id="staff-L66F1N1" n="1">
<layer xml:id="layer-L66F1N1" n="1">
<note xml:id="note-L67F1" dots="1" dur="4" oct="4" pname="f" accid="n" />
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
Notice that the original notation in MEI:
And the round trip through Humdrum and back to MEI:
Identifies a problem: The F4
pitches in the original MEI data should have @accid.ges="s"
applied to them. In other words, the notes have no accidental signs on them so @accid
is should not be specified; however, the notes have a sounding sharp, so @accid.ges="s"
should be inferred from the key signature (if the data is coming from OMR output).
The conversion into Humdrum is an F-natural since there is no @accid
or @accid.ges
on the original notes. When the Humdrum-to-MEI convert processes the data, it analyzes the accidental states of the notes, and it notices that the notes are F-nautral, but the key signature has an F-sharp, so it automatically adds a visual natural (@accid="n"
). This can be overridden in Humdrum by placing a y
after the accidental, such as: Fny
, but that is not the intention of the notation in this case, and the sounding accidental should be inferred in the MEI data before conversion to Humdrum.
A solution could be duplicating the 'r' as many times as number of spanned bars, but for the example above we would have to encode:
rrrrrrrrrrrrrrrrrrrrr
that is not very useful.
Yes, that method is possible, but for the best match to how Humdrum works for analysis, encoding the 21 individual measures of rest will be the best thing to do. I informally use rr
to mean a whole measure rest, which could be considered a form of multibar rest.
The most common method of doing rr<N>
would be to use the layout system:
**kern
*part1
*staff1
*clefG2
*k[f#c#]
*M3/8
=1
!LO:N:mrest=21
2%63rr
=22
(Where I am guessing 21 dotted quarter notes which have a duration of 31.5 quarter notes, or 63/2 quarter notes is converted into the **recip
value of 2%63
).
These layout parameters are local comments (or global comments) that immediately precede another token. Inside of the layout parameter is given a list of non-kern parameters.
**kern
*M4/4
=1
4c
4c
4c
4c
=
!LO:N:vis=8
4c
!LO:N:vis=16
4c
!LO:N:vis=1
4c
!LO:N:vis=0
4c;
==
*-
Results in: