From 18750421a0b21611b7263cdf041c017b6da06d3f Mon Sep 17 00:00:00 2001 From: Johannes Kepper Date: Wed, 20 May 2020 14:55:59 +0200 Subject: [PATCH] addition of events/controlevents and timestamps --- .../02-eventscontrolevents.md | 36 ++++++++++++++++++- .../02-basicconcepts/03-timestamps.md | 21 +++++++++++ .../{03-meiprofiles.md => 04-meiprofiles.md} | 0 ...ustomization.md => 05-meicustomization.md} | 0 .../examples/shared/controlevents-dynam1.txt | 11 ++++++ .../examples/shared/controlevents-dynam2.txt | 11 ++++++ .../examples/shared/timestamp-durations1.txt | 8 +++++ 7 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 _guidelines-v4/01-introduction/02-basicconcepts/03-timestamps.md rename _guidelines-v4/01-introduction/02-basicconcepts/{03-meiprofiles.md => 04-meiprofiles.md} (100%) rename _guidelines-v4/01-introduction/02-basicconcepts/{04-meicustomization.md => 05-meicustomization.md} (100%) create mode 100644 _includes/v4/examples/shared/controlevents-dynam1.txt create mode 100644 _includes/v4/examples/shared/controlevents-dynam2.txt create mode 100644 _includes/v4/examples/shared/timestamp-durations1.txt diff --git a/_guidelines-v4/01-introduction/02-basicconcepts/02-eventscontrolevents.md b/_guidelines-v4/01-introduction/02-basicconcepts/02-eventscontrolevents.md index 8e25d1c597b..aaaaf93fc48 100644 --- a/_guidelines-v4/01-introduction/02-basicconcepts/02-eventscontrolevents.md +++ b/_guidelines-v4/01-introduction/02-basicconcepts/02-eventscontrolevents.md @@ -4,4 +4,38 @@ title: "Events and Controlevents" sectionid: "eventsControlevents" --- -MEI differentiates between two essential aspects of music notation. +MEI differentiates between two essential aspects of music notation: *Events* and *ControlEvents*. There are other examples for such a separation of concerns with regard to music. In Greg's Copy-Text Theory (W.W.Greg: *The Rationale of Copy-Text*, 1950), a distinction between primary and secondary text is made; similar attempts have been made for music specifically. + +In MEI, elements describing the basic musical text are referred to as *Events*. They are the building blocks for the stream of music – mostly those are {% include link elem="note"%}s, {% include link elem="rest"%}s, and {% include link elem="chord"%}s. +In contrast, *ControlEvents* make no independent contribution to that flow of music. Instead, they provide additional information about the encoded *Events*, they *control* their performance. Examples for such *ControlEvents* are {% include link elem="dynam"%}ic markings, {% include link elem="tempo"%}s indications, or performance {% include link elem="dir"%}ectives. Depending on the encoding strategy used, {% include link elem="slur"%}s and {% include link elem="tie"%}s often also fall into this category (they may be encoded as attributes instead, in which case they become a property of the basic events). +Simply put, *Events* describe ***what*** needs to be performed, and *ControlEvents* indicate ***how*** it needs to be performed. In ({% include link id="cmn" %}-based) MEI, *Events* are nested inside a {% include link elem="layer"%} element, while *ControlEvents* are direct children of the first {% include link elem="measure" %} they apply to, following all {% include link elem="staff" %} elements there. +These structural differences result in different markup concepts. As *Events* are encoded inside {% include link elem="layer"%}s, their *semantic position* inside the encoded work can be derived from their *structural position* – the measure, staff and layer they're nested in, and within that layer by their position inside the sequence of all layer children. As mentioned above, it is highly *recommended* to encode *ControlEvents* inside the first measure they apply to, but they still require references to the actual events they apply to. There are two common concepts to provide such a connection, both of which offering specific benefits and drawbacks. +A technically very stable connection between *ControlEvents* and *Events* can be established by using **pointers**. In this case, all events that need to be referenced need an *@xml:id* attribute, which holds a globally unique identifier for this very element. The referencing controlevent then uses a *@startid* and, if necessary, *@endid* attribute to create a link to where in the stream of music it is supposed to start or end. + +{% include mei example="shared/controlevents-dynam1.txt" valid="" %} + +In the example above, the {% include link elem="dynam"%} element references the second quarter in the given measure. Additional attributes like *@place* may be used to describe the position of the *forte* indication within the score. A {% include link elem="hairpin"%} element may use the *@endid* attribute to indicate the duration of the hairpin using the same mechanism as above. + +{% include desc atts="att.startId/startid att.startEndId/endid" %} + +A *ControlEvent* encoded like above will be strictly tied to the referenced *Events* – if their position inside the XML document changes for whatever reason, they will keep that connection. This means that the *semantic position* to which they are bound may change without affecting the binding. An example could be an inserted additional note in front – the dynamic marking would not start on the second quarter, but perhaps on the third instead. + +As this behavior may not be desired in all cases, an alternative binding between *ControlEvents* and *Events* is possible, relying on *timestamps* instead. This mechanism is illustrated in the following example: + +{% include mei example="shared/controlevents-dynam2.txt" valid="" %} + +Here, no *@xml:id* is required on notes. Instead, the {% include link elem="dynam"%} element uses the *@staff* and *@layer* attributes to indicate to which set of events the following *@tstamp* attribute refers to. + +{% include desc atts="att.timestamp.logical/tstamp" %} + +This mechanism actually depends on what has been only recommended above: placing the controlevent inside the measure where it starts. The *@startid* reference mechanism would work equally well if all controlevents where positioned in the very first or last measure, or actually even inside a separate file. The *@tstamp* references however would not, they depend on correct placement of the controlevents inside the XML tree. For consistency, it is therefore *recommended* to always use this placement. + +The benefit of this concept is that controlevents are tied to a *semantic position*, but not necessarily to a given XML element. The *forte* may still be placed on the second quarter, even though the composer may have replaced that quarter G4 with a different pitch and / or duration. Actually, it is not required that an *Event* can be found at the position indicated by a timestamp. This may be useful to encode a slur ending at an arbitrary position between two events, or dynam markings spread across otherwise empty measures. + +If the ending of a *ControlEvent* shall be given by timestamp, the *@tstamp2* attribute is used. + +{% include desc atts="att.timestamp2.logical/tstamp2" %} + +Because of potential inconsistencies, an encoding should not offer both *@startid* and *tstamp* or *@endid* and *@tstamp2*. Though not being recommendable, it is possible to mix *@startid* with *@tstamp2* and *@tstamp* with *@endid*. In general, it is easier for software to process *@startid* and *@endid*. When no other arguments apply, using *@xml:id*-based pointers is therefore the most common way to connect *ControlEvents* with *Events*. + +The details on how timestamps are calculated and used in MEI are given in {% include link id="timestamps" %}. diff --git a/_guidelines-v4/01-introduction/02-basicconcepts/03-timestamps.md b/_guidelines-v4/01-introduction/02-basicconcepts/03-timestamps.md new file mode 100644 index 00000000000..ee3531da2a8 --- /dev/null +++ b/_guidelines-v4/01-introduction/02-basicconcepts/03-timestamps.md @@ -0,0 +1,21 @@ +--- +version: "v4" +title: "Timestamps in MEI" +sectionid: "timestamps" +--- + +In MEI, timestamps are treated in a slightly simplified way: they have no notion of *beat*. Instead, timestamps rely solely on the numbers given in the meter signature. In a measure of 4/4, timestamps will range from 1 to 4. The second eighth note will be 1.5 in this case. If the same measure would be given in 2/2, it would be 1.25 instead. + +{% include desc atts="att.timestamp.logical/tstamp" %} + +At this point, MEI uses real numbers only to express timestamps. In case of (nested or complex) tuplets, this solution is inferior to fractions because of rounding errors. It is envisioned to introduce a fraction-based value for timestamps in a future revision of MEI. For now, it is recommended to round the fractional part of the number to no more than five digits to avoid such problems. + +Durations may also be expressed based on timestamps. In this case, the values are a combination of the *count of measures* that need to be moved forward to reach the measure in which an encoded feature ends, and the *timestamp* within that measure. + +{% include desc atts="att.timestamp2.logical/tstamp2" %} + +The following example contains a number of {% include link elem="slur"%} examples illustrating durations expressed by timestamps. + +{% include mei example="shared/timestamp-durations1.txt" valid="" %} + +Sometimes, timestamps are used to indicate positions where no music *Events* are located (see {% include link id="eventsControlevents" %}). Therefore, the allowed range of timestamps stretches from 0 to the current meter count + 1. By definition, a timestamp of 1 indicates the position of the left barline, while a timestamp of 5 (in case of a 4/4 meter) indicates the right barline. This makes it possible to encode open-ended slurs in a graphical way. However, it should be kept in mind that such timestamps may not be converted to *@startid* and *@endid*, and not every application may be able to render them correctly, even though they are perfectly valid MEI, and sometimes are necessary to faithfully transcribe a source. diff --git a/_guidelines-v4/01-introduction/02-basicconcepts/03-meiprofiles.md b/_guidelines-v4/01-introduction/02-basicconcepts/04-meiprofiles.md similarity index 100% rename from _guidelines-v4/01-introduction/02-basicconcepts/03-meiprofiles.md rename to _guidelines-v4/01-introduction/02-basicconcepts/04-meiprofiles.md diff --git a/_guidelines-v4/01-introduction/02-basicconcepts/04-meicustomization.md b/_guidelines-v4/01-introduction/02-basicconcepts/05-meicustomization.md similarity index 100% rename from _guidelines-v4/01-introduction/02-basicconcepts/04-meicustomization.md rename to _guidelines-v4/01-introduction/02-basicconcepts/05-meicustomization.md diff --git a/_includes/v4/examples/shared/controlevents-dynam1.txt b/_includes/v4/examples/shared/controlevents-dynam1.txt new file mode 100644 index 00000000000..9d62a24296f --- /dev/null +++ b/_includes/v4/examples/shared/controlevents-dynam1.txt @@ -0,0 +1,11 @@ + + + + + + + + + + f + diff --git a/_includes/v4/examples/shared/controlevents-dynam2.txt b/_includes/v4/examples/shared/controlevents-dynam2.txt new file mode 100644 index 00000000000..0f9c5a925c1 --- /dev/null +++ b/_includes/v4/examples/shared/controlevents-dynam2.txt @@ -0,0 +1,11 @@ + + + + + + + + + + f + diff --git a/_includes/v4/examples/shared/timestamp-durations1.txt b/_includes/v4/examples/shared/timestamp-durations1.txt new file mode 100644 index 00000000000..b5b4b3392da --- /dev/null +++ b/_includes/v4/examples/shared/timestamp-durations1.txt @@ -0,0 +1,8 @@ + + + + + + + +