Notes and rests shorter than 128th do not display or copy properly

• Nov 10, 2013 - 00:32
Type
Functional
Severity
S4 - Minor
Status
closed
Project

I can produce notes such as 256ths by inserting a 64th with two dots in note entry mode, exiting it, selecting the 256th rest (which does not appear properly), and re-entering the note entry mode, but when I try to copy and paste 256th notes, then the rhythms appear incorrectly.
As you know, MuseScore uses internal units for duration. While a 128th is 15 units, a 256th is 7.5, but the duration can be stored only as an integer.

To Reproduce:
1. Create a new score in 4/4 time.
2. Insert a dotted 128th note.
3. Exit note entry mode, select the rest after the note, and re-enter note entry mode.
4. Insert eight notes sequentially. Note that there should be a 32nd, 16th, 8th, quarter, and half rest.
5. Copy the eight notes, select the 32nd rest, then paste.
Expected: There should be a 16th, 8th, quarter, and half rest after the sixteen notes.
Actual: 256th (appears incorrectly), 128th, 64th, 32nd, 8th, quarter, half


Comments

It should be able to support very short note durations (AFAIK Finale supports 4096ths). Maybe if we store them as floating-point numbers, durations already supported will still work, and those that are fractions of powers of two will keep accuracy. The only downside is speed.

We could still have the old interface for choosing note durations as well as a method for inserting those with custom durations (e. g. 5/8 to get a half note tied to an eighth, and 1/256, 1/512, etc.). More, not less choice, is the answer.

Actually, the recent SMUFL integration introduced 512th and 1024th as valid duration types.
See: https://github.com/musescore/MuseScore/blob/master/libmscore/durationty…
However, these types are not yet handled properly through the whole code and, for example, the tables in durationtype.cpp are not yet updated (see for example https://github.com/musescore/MuseScore/blob/master/libmscore/durationty… and most of the duration tables and switch-case instructions in durationtype.cpp).
The problem with non-integer tick duration for these very short notes still remains.

1/ Less is more. I prefer to have only 128th note and a working and usable software for everyone

2/ Having the glyphs is not enough. The root problem is the quarter note value of 480. We can't go lower than 128th with that. So I would not change DurationType except if we have a global solution and test cases.

1/ Less is more. I prefer to have only 128th note and a working and usable software for everyone

2/ Having the glyphs is not enough. The root problem is the quarter note value of 480. We can't go lower than 128th with that. So I would not change DurationType except if we have a global solution and test cases.

I agree. However, as this bug repot points out, there is (at least) one way by which a user can introduce very short notes in the score (namely, by using single and/or double dots on 64th and 128th notes) by the user interface. Probably, the use of double dots on 64th notes and single and double dots on 128th notes can be disabled, so that a user can never introduce notes shorter than 128th.
256th notes were already there before the SMUFL introduction, but the corresponding gliph is not present so a zero-width segment is added to the score when a dotted 128th note is added (look in the debugger). In the double dotted 128th note the 512th segment is not created, resulting in measure corruption. The 256th segment is 8 ticks long: I don't know if this determines measure corruption.

I posted a pull request to at least complete all the tables inside durationtype.cpp, since for example V_MEASURE is accessing memory outside hooks table [ V_MEASURE is _val=14, but the hooks table is shorter than 15 elements (range 0-14) at the moment: it is 14 elements long (range 0-13). I noticed this yesterday evening while running MuseScore with address sanitizer ].

Edit: Added the images corresponding to the behavior of 8d8b6ccff personal (debug) build, Windows 8; the measure is a 4/4 measure. Similar behavior for a double dotted 64th note.

Attachment Size
dotted128.png 21.71 KB
doubledotted128.png 21.51 KB

Response to 1: Not everyone uses the 128th as the shortest note.
To 2: As I said earlier, we could use floating-point values for the notes. Existing precision would be retained, if I'm not mistaken, because the IEEE standard uses powers of 2 for the exponent part (rather than 10 as we do in real life).

We could change the internal tick resolution from 480/beat to 3840/beat to better support short notes. In the long run tick calculations should be replaced with Fraction values (two integers: numerator and denominator).

Does MIDI support such a High tick resolution?

960 tpq is the highest tick value I have come across in commercial sequencers (Cakewalk X2 is the one I have)

But indeed raising the tick resolution to 3840 tpq would enable the use of a 1024th note, and thus dotted 512th notes.

Unfortunately, with the new version of the PR, I get again the "Command Pad-dot not valid in current state" message when entering a point in a text :-(
Moreover, if I click on a 64th note after having clicked on a 128th note, the dot button is disabled.

We can maybe trash the idea at the base of the PR and try to do something else to cope with this situation (also involving tuplets) after the release of 2.0.

I don't have that error on entering a . in text (but I also updated the PR a few times meanwhile and indeed one of the intermediate changes was broken)
But yes, that other problem is still there. Workaround: click somewhere outside the score, then on the 64th. Seems clicking on a note the 2nd time in a row is not considered a state change?

What about enclosing the "setEnabled" from the original PR inside an "if" statement which limits their function?
I mean something like this:
{syntaxhighlighter brush:c++;}
if ((mscore->state() & STATE_NORMAL) | (mscore->state() & STATE_NOTE_ENTRY)) {
getAction("pad-dot")->setEnabled(true);
getAction("pad-dotdot")->setEnabled(true);
}
{/syntaxhighlighter}