New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tick-based timing #217
Comments
|
The ( 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!)
The final |
|
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. 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 |
|
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: converts to as follows: This is no more complicated than the other MusicXML->MNX conversions being proposed in MNX by Example. The Draft Spec's BTW: Two errors in the Draft Spec:
|
|
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 #216 (comment)). :-)
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.ticksPerUnitvalue 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:The inner tick durations have to be calculated consistently so that temporal alignments are preserved, for example using a function that returns a list of tick durations whose sum is the outerTicksDuration:
list_of_tickDurations = intDivide(outerTicksDuration, divisor)Tick duration
The
<millisecondsPerTick> valueis 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 optionallocationattribute (default is "0"), so that the "tempo" can change at any point in the<measure>.The
valueshould 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> valueis 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> valueof (1000/1024) = 0.9765625.The text was updated successfully, but these errors were encountered: