rism-digital / verovio

🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)
https://www.verovio.org
GNU Lesser General Public License v3.0
667 stars 183 forks source link

Timemap contains same qstamp twice with similar tstamp #3216

Closed wergo closed 1 year ago

wergo commented 1 year ago

When exporting the timemap through the toolkit, some events appear twice with an identical qstamp value, but _almost identical tstamp values.

An example is Beethoven Op. 119 No. 5

Bildschirmfoto 2023-01-19 um 17 04 55

This first staff line outputs this timemap object, in which qstamp="3.5" and qstamp="9.5" each appears twice with very similar tstamp values; the first such event contains onsets, the other offsets of the same event.

Bildschirmfoto 2023-01-19 um 16 40 15

(The screenshots done with Verovio 3.14, but same behavior with 3.15.)

This could be due to a rounding error between the offset and the onset time values.

Expected behavior Each qstamp value should appear only once in the timemap.

rettinghaus commented 1 year ago

Is this a js toolkit only problem?

wergo commented 1 year ago

No, it is the same output through the command line (version 3.15.0-dev-4e449f6):

Bildschirmfoto 2023-01-19 um 21 30 54
craigsapp commented 1 year ago

Is this a js toolkit only problem?

It is a general problem with fixed-precision calculations. This is not necessarily something to fix, but it can be fixed to look tidy.

The best thing would be to round the the nearest millisecond. The tstamps are in millisecond units I believe, so rounding them to the nearest integer is a reasonable thing to do:

      tstamp = int(tstamp + 0.5);

But also, I would expect that it would be possible to give true performance times in the timemap, rather than hacking them from the score durations as is currently done. The intent of qstamp is to give the pure ratio rhythms from the score such as 0.5 for an eighth note, while for tstamps they could represent an arpeggio where there is a chord in the score. Or in other words, it is not bad that the tstamp values have small round-off problems, and should not confuse applications that use it.

If there are a lot of tuplets in the score, there will be problems with round off in the qstamp values as well (but fixing round-off errors on qstamps would be more complicated since they represent rational numbers, i.e., integer fractions).

tstamp is monotonic (the stamp value should always increase from the last entry, which they are doing in the example. qstamp, on the other hand is not monotonic in cases where there are repeats in the score. In other words, there can be multiple entries for the same qstamp in the timemap, one for each time the score repeats the chord at that point in the score. tstamps should never repeat (or at least never go negative).

wergo commented 1 year ago

Rounding to the nearest millisecond would certrainly solve this problem. I will do a PR for that. We could think about rounding to a higher precision, if milliseconds appear too coarse.

But also, I would expect that it would be possible to give true performance times in the timemap, rather than hacking them from the score durations as is currently done.

What do you mean by "true performance times" -- a specific performance, such as by a human professional?

craigsapp commented 1 year ago

What do you mean by "true performance times" -- a specific performance, such as by a human professional?

Yes, I can imagine that the timings generated by a human (professional or not :-) could be inserted into the timemap from a timeline stored in the same MEI file as the score.