humdrum-tools / verovio-humdrum-viewer

Verovio Humdrum Viewer
http://verovio.humdrum.org
37 stars 9 forks source link

Accidental few notes too early - how to encode? #301

Open jacekiwaszko1 opened 4 years ago

jacekiwaszko1 commented 4 years ago

This is case common in 16th century music, but happens also later:

early-acc1

Basic Humdrum encoding:

**kern
*clefF4
*k[b-]
*M3/4
=
8C\L
8BBn
8C
8D
8E
8DJ
=
*-

Accidental, that logicaly belongs to 8BBn is placed before previous note.

It is possible to render this in Verovio by hidding accidendtal in note element and adding <add> element containing <accid>. In this case:

<add>
    <accid accid="n" ploc="b" oloc="2" />
</add>

early-acc2

target (?) MEI encoding:

<?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-04-23T18:59:00" version="2.7.0-dev-9b84e3d">
                    <name>Verovio</name>
                    <p>Transcoded from Humdrum</p>
                </application>
            </appInfo>
        </encodingDesc>
        <workList>
            <work>
                <title />
            </work>
        </workList>
    </meiHead>
    <music>
        <body>
            <mdiv xml:id="mdiv-0000000493509894">
                <score xml:id="score-0000001705230118">
                    <scoreDef xml:id="scoredef-0000000953002994">
                        <staffGrp xml:id="staffgrp-0000000850532481">
                            <staffDef xml:id="staffdef-0000001662882299" n="1" lines="5">
                                <clef xml:id="clef-L2F1" shape="F" line="4" />
                                <keySig xml:id="keysig-L3F1" sig="1f" />
                                <meterSig xml:id="metersig-L4F1" count="3" unit="4" />
                            </staffDef>
                        </staffGrp>
                    </scoreDef>
                    <section xml:id="section-L1F1">
                        <measure xml:id="measure-L1">
                            <staff xml:id="staff-0000000045595741" n="1">
                                <layer xml:id="layer-L1F1N1" n="1">
                                    <add>
                                        <accid accid="n" ploc="b" oloc="2" />
                                    </add>
                                    <beam xml:id="beam-L6F1-L11F1">
                                        <note xml:id="note-L6F1" dur="8" oct="3" pname="c" stem.dir="down" accid.ges="n" />
                                        <note xml:id="note-L7F1" dur="8" oct="2" pname="b" accid.ges="n" />
                                        <note xml:id="note-L8F1" dur="8" oct="3" pname="c" accid.ges="n" />
                                        <note xml:id="note-L9F1" dur="8" oct="3" pname="d" accid.ges="n" />
                                        <note xml:id="note-L10F1" dur="8" oct="3" pname="e" accid.ges="n" />
                                        <note xml:id="note-L11F1" dur="8" oct="3" pname="d" accid.ges="n" />
                                    </beam>
                                </layer>
                            </staff>
                        </measure>
                    </section>
                </score>
            </mdiv>
        </body>
    </music>
</mei>

It would be of course nice to encode it in Humdrum and convert to MEI.

I guess it would be the best to ecode this early accidental on 8BBn since it's where it belongs. !LO:N:acc seems like a good place for it. Maybe !LO:N:acc:b=1 where b=1 would mean that accidental should be displayed one note before the note it is encoded with. So for the example above it could look like that:

**kern
*clefF4
*k[b-]
*M3/4
=
8C\L
!LO:N:acc:b=1
8BBn
8C
8D
8E
8DJ
=
*-

Second option would be to encode accidental before first note in this measure, and link it to second note with matching labels or tags:

**kern
*clefF4
*k[b-]
*M3/4
=
!LO:N:acc:d:l=1
8C\L
!LO:N:acc:l=1
8BBn
8C
8D
8E
8DJ
=
*-

l=1 would mean label=1 d would mean display.

I'd guess second option is easier to convert ;)

Or maybe there's better third option?

What do you think?

craigsapp commented 4 years ago

I guess it would be the best to encode this early accidental on 8BBn since it's where it belongs.

Yes, that is the best way. I want to reserve b for meaning "below" rather than "before" (as it is in LO:TX) so something other than b should be used as the parameter name. Maybe back, which is shorter than before?:

**kern
*clefF4
*k[b-]
*M3/4
=
8C\L
!LO:N:acc:back=1
8BBn
8C
8D
8E
8DJ
=
*-

Otherwise, prev (for previous) might be good since it does not start with a "b" to distance further from "below".

This parameter will automatically suppress a visual accidental directly on the note (so the accidental will be converted to @accid.ges in MEI conversion on the note).

Is there a reason you are using <add>? I don't this this element is needed in such a case since this is not an addition to the manuscript, but was placed in the manuscript at the same time as the rest of the music.

<?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-04-23T18:59:00" version="2.7.0-dev-9b84e3d">
                    <name>Verovio</name>
                    <p>Transcoded from Humdrum</p>
                </application>
            </appInfo>
        </encodingDesc>
        <workList>
            <work>
                <title />
            </work>
        </workList>
    </meiHead>
    <music>
        <body>
            <mdiv xml:id="mdiv-0000000493509894">
                <score xml:id="score-0000001705230118">
                    <scoreDef xml:id="scoredef-0000000953002994">
                        <staffGrp xml:id="staffgrp-0000000850532481">
                            <staffDef xml:id="staffdef-0000001662882299" n="1" lines="5">
                                <clef xml:id="clef-L2F1" shape="F" line="4" />
                                <keySig xml:id="keysig-L3F1" sig="1f" />
                                <meterSig xml:id="metersig-L4F1" count="3" unit="4" />
                            </staffDef>
                        </staffGrp>
                    </scoreDef>
                    <section xml:id="section-L1F1">
                        <measure xml:id="measure-L1">
                            <staff xml:id="staff-0000000045595741" n="1">
                                <layer xml:id="layer-L1F1N1" n="1">
                                    <accid accid="n" ploc="b" oloc="2" />
                                    <beam xml:id="beam-L6F1-L11F1">
                                        <note xml:id="note-L6F1" dur="8" oct="3" pname="c" stem.dir="down" accid.ges="n" />
                                        <note xml:id="note-L7F1" dur="8" oct="2" pname="b" accid.ges="n" />
                                        <note xml:id="note-L8F1" dur="8" oct="3" pname="c" accid.ges="n" />
                                        <note xml:id="note-L9F1" dur="8" oct="3" pname="d" accid.ges="n" />
                                        <note xml:id="note-L10F1" dur="8" oct="3" pname="e" accid.ges="n" />
                                        <note xml:id="note-L11F1" dur="8" oct="3" pname="d" accid.ges="n" />
                                    </beam>
                                </layer>
                            </staff>
                        </measure>
                    </section>
                </score>
            </mdiv>
        </body>
    </music>
</mei>

There could be other complexities:

jacekiwaszko1 commented 4 years ago

Is there a reason you are using ?

No - I'm not the best in MEI encoding (yet?), so I thought that <accid> has to be attached to some other musical element like <note>. Good to know that it hasn't ;)

Should rests be counted? Probably not, but there may be some case where the accidental is moved before a rest for some reason. For now I will not worry about that.

I don't think so too - I don't think I've ever seen something like that

Will an accidental ever be moved from the beginning of one measure to the end of the previous one? Such a case would not be covered by the back parameter, since it would move by note count.

I don't think I've ever seen an accidental placed before barline. And I think it is not that important as moving accidental by notes - in 16th century music flat or natural moved back to the begining of a musical phrase not only changed this particular pitch, but also was indicating change of hexachord what is important when you're dealing with musica ficta.

I'll try to find early music example of this practice. And do you think moving accidental by notes to any note in previous measure (or few measures back) would be possible?

craigsapp commented 4 years ago

so I thought that <accid> has to be attached to some other musical element like <note>.

That is how it usually works. From the documentation for accid: https://music-encoding.org/guidelines/v4/elements/accid.html

There is a "Contained by" section on that page which lists the elements that can directly include <accid> as a child element:

abbr, add, corr, damage, del, expan, layer, lem, note, oLayer, orig, rdg, reg, restore, sic, supplied, unclear

So you can see that a bare accidental in the <layer> element is allowed.

craigsapp commented 4 years ago

And do you think moving accidental by notes to any note in previous measure (or few measures back) would be possible?

Anything is possible :-)

I convert from Humdrum into MEI by measure, so an element that is specified in one measure in Humdrum but needs to be placed into another in MEI would become complicated. Placing things into future measures is easier, since I can store them off to the side and wait for that measure, but placing in the past either requires that I pre-process the score to identify such cases, or I go back though the MEI data structure. In this case I would have to go back through the layer data which is more complex since the insertion sequence is important.

Finding the nth note backwards in Humdrum is trivial, but in MEI it is non-trivial. Since this is a rare case, it is more efficient to do the action when it is found, meaning that searching for the back note should be done in MEI, but it is non-trivial in MEI, so I will probably implement in Humdrum by adding a prefix accidental to the earlier note before I convert to MEI. Then the accidental will be inserted when processing the measure that should contain the note, and I will not have to search backwards in the layer data for the nth note.

jacekiwaszko1 commented 4 years ago

Should rests be counted? Probably not, but there may be some case where the accidental is moved before a rest for some reason. For now I will not worry about that.

I just got an example of accidental before the rest:

early-acc

There are two sharps actually - one before rest and one (smaller) before the note...