Corruption on deleting initial rest in voice 2 tuplet
Priority
P2 - Medium
Type
Functional
Frequency
Few
Severity
S2 - Critical
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project
To reproduce:
1) new score, treble template, 4/4
2) measure 1, note input
3) voice 2
4) 5 Ctrl+3 0 C C (to enter triplet starting with a rest)
5) exit note input
6) select leading rest
7) delete
At this point, the file is in an awkward position, and while corruption isn't necessarily present yet, it can be induced in several ways. For one, try selecting the measure and pressing "R", for instance) - you'll see the measures gets copied well enough but the one after is rendered corrupt in voice 2, with something other 4 beats of rest. Or try swapping voices 1-2 - corruption results in voice 1 as the rests inserted to fill the beginning of the measure are not part of the tuplet and don't add up.
Fix version
3.5.0
Comments
I still wish we didn't support deleting rests at all, as there are lots of problems internally with this that we keep having to patch. But given that we aren't ready to disallow it in general, we could at least disallow it for rests within tuplets. That will prevent people from creating this type of situation in the future. It won't help with people who already have scores of this form, though - not corrupt yet, but with corruption waiting to happen. That's actually how I discovered this, from a thread where someone was trying to copy content from such a score to a new one. See https://musescore.org/en/node/269973.
Unfortunately, preventing the problem once the hole is created probably means adding checks and handling for this in multiple places. The original problem was an error on copy paste because the duration of the tuplet was calculated incorrect. The copy paste problem I mention above happens elsewhere. The voice exchange problem might be different still, although it's possible both of these problems are in makeGap() or some such.
In makegap, the main issue is that we call it based on the voice gap stored at the beginning of the clipboard. In this case, it's 160 for voice 2 (a 8th note in a triplet). When we call
makeGap
,makeGap1
and in the endexpandVoice
, we end up callingsetRest()
without even a tuplet being set... so in the end, noRest
are created and that's the beginning of the end.In deleteItem(), replacing the removal of a Rest in voice > 1 by switching visibility off is doable.
I wonder, then, could we detect these incomplete tuplets when reading a score and convert the holes to hidden rests right then?
See https://musescore.org/en/node/270386
This is mostly fixed now. You can still get corruption with some work, but it takes more determined effort and I can't reproduce the steps. So I'm leaving this open, but reducing priority.
Came up again in: https://musescore.org/fr/node/305662#comment-1000812
Steps:
1) Load this test file: test2.mscz
2) Remove the first eighth rest (tuplet voice 2)
3) Save/Quit/Reload
Result: corruption: test3.mscz
https://github.com/musescore/MuseScore/pull/6129
Fixed in branch 3.x, commit f87ad41ba0
_Fix #270043 - Corruption on deleting initial rest in voice 2 tuplet
Prevent deleting the first Rest of a tuplet on voice > 1._
Fixed in branch 3.x, commit 26e554f8df
_Merge pull request #6129 from njvdberg/issue-270043-delete-tuplet
Fix #270043 - Corruption on deleting initial rest in voice 2 tuplet_
Automatically closed -- issue fixed for 2 weeks with no activity.
now fixed in master too