Closed notator closed 3 years ago
The <action>
element described in the accel. example in #214 is redundant since <speedChange>
can be placed directly inside <global><measure><directions>
. The <actions>
element, containing a list of actions to be executed one at a time, is still needed (for da Capo s etc.).
Here's an example of an accelerando enclosed in a repeat:
<global>
<measure index= 1>
<directions>
<tickResolution unit="1/4" ticksPerUnit="1024" />
<millisecondsPerTick value="1" /> <!-- changing this later changes the performance speed -->
<target location="0" id="startRepeat1">
</directions>
</measure>
<!-- more measures -->
<measure>
<directions>
<millisecondsPerTick value="0.8345" /> <!--abrupt speed change (default location="0") -->
<speedChange location="1/4" factor="200%" type="linear" duration="7/8" />
</directions>
</measure>
</measure>
<measure>
<actions location="4/4">
<goto target="#startRepeat1" />
<stop />
</actions >
</measure>
</global>
(<speedChange>
's precise definition still has to be discussed. It could, for example, have an endLocation
rather than a duration
attribute.)
Having privately updated the ID references in all the MNX by Example examples (possibly the subject of one or more future PRs), I still think it would be much better to use indexing where possible. (The references in the beam definitions don't look nice at all!) Having a '#' character at the beginning of each ID reference is important, but
The final <goto>
in the above code would then just point at the beginning of measure 1. (Issue: Indices should begin at 0.)
<measure>
<actions location="4/4">
<goto target="0:0" />
<stop />
</actions >
</measure>
MNX's primary goal is to represent printed sheet music, so timing information should be encoded as it is in sheet music (i.e. as a tempo in BPM). Compatibility with MIDI is a secondary goal, so there is no need to store MIDI-style timings if they can be calculated from BPM tempos (which they can). Detailed performance information (e.g. for rubato) can be facilitated by adding additional non-printing tempo markings with non-integer BPM values (e.g. bpm="121.457"
).
Note that the specification already contains a secondary form of timing information for the purposes of syncing playback with a recording (see Synchronisation Content and the score-audio
element), but this is based on seconds rather than ticks.
Restricting event positions to a grid of (integer) ticks has advantages in both graphical and temporal domains.
For graphics it means that the vertical alignments of synchronous events are always exact. That in turn means that horizontal justification algorithms never have to deal with rounding errors, even when the spacing is extremely wide or when the events are inside (nested) tuplets. Justification algorithms can start with the pixel (inch, cm) width of the system and the sum of the ticks per event that have to be fit into the space. The (integer) tick duration of each event remains unchanged, while the (float) pixel x-location of each event symbol is found.
Similarly, its possible (for example) to create very slow but accurate performances for score-checking purposes when composing. This scenario works just by changing the global millisecondsPerTick value, and also leaves the individual (integer tick) event durations unchanged.
This is not a MIDI-specific strategy but, as you say, BPM can be converted easily to tickResolution plus milisecondsPerTick:
<tempo bpm="121.457" value="/4"/>
converts to
<tickResolution unit="1/4" ticksPerUnit="1024" />
<millisecondsPerTick value="0.48242" />
as follows:
121.457bpm => (60/121.457) seconds per quarter note
=> 494.00199... milliseconds per quarter note
=> (494.00199... / 1024) = 0.48242... milliseconds per tick
This is no more complicated than the other MusicXML->MNX conversions being proposed in MNX by Example.
The Draft Spec's <score-audio>
element connects the timings in an external recording with measure locations (not IDs or timings) in the MNX. I see no problems there. [Edit: <score-audio-mapping>
could be improved, binding the timings more closely to the score's content, but that's not the subject of this issue.]
BTW: Two errors in the Draft Spec:
value="4"
.)<score-audio-mapping>
should, according to the definition, be score-start
and score-end
, not simply start
and end
.I agree with @shoogle here. Playback timing can already be expressed in MNX via tempo markings (which can either be visible or invisible).
@ahankinson Thanks again for the link to MEI's MIDI handling documentation (in https://github.com/w3c/mnx/issues/216#issuecomment-760201655). :-)
I want to change the way a score's performance speed is set by replacing the following code in Example 6 in our Draft Spec:
by a tick-based version. A tick-based temporal model would interface better with all performing applications, not just (web) MIDI applications). I've added some explanations below, but here's how I now want the code to look:
Tick resolution
In MEI's 14.5.1. PPQ in scoreDef and staffDef, MEI has:
<scoreDef ... meter.unit="4" ppq="48">
So a more flexible, MEI-like version of my<ticksPerQuarter>
would be:<tickResolution unit="1/4" ticksPerUnit="1024" />
defining 1024 ticks per quarter note symbol. Note that:<tickResolution>
remains constant for the whole score, regardless of the duration of a tick.ticksPerUnit
value is an integer, and the number of ticks in the other (basic) duration classes is calculated automatically in the usual way. That means it should be a power of 2, and be chosen so that the temporal resolution is imperceptible in performance. (Issue: The Draft Spec doesn't explicitly say which basic duration classes are supported.) For example:list_of_tickDurations = intDivide(outerTicksDuration, divisor)
Tick duration
The
<millisecondsPerTick> value
is a floating point value that can be changed at any point in the score (in<global><measure><directions>
) so as to change the performance speed. It should have an optionallocation
attribute (default is "0"), so that the "tempo" can change at any point in the<measure>
. Thevalue
should be chosen so that ticks are below the level of human perception in music. I would always keep this value below about 2 milliseconds. Combining<tickResolution unit="1/4" ticksPerUnit="1024" />
and<millisecondsPerTick> value
is 1, is equivalent to a "tempo" of ((1000/1024) * 60) = 58,59375 quarter notes per minute. A "tempo" of exactly 60 quarter notes per minute can be achieved by combining<tickResolution unit="1/4" ticksPerUnit="1024" />
with a<millisecondsPerTick> value
of (1000/1024) = 0.9765625.