Skip to content
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

Fix corruption issues on old files #20230

Merged
merged 5 commits into from
Nov 30, 2023

Conversation

mike-spa
Copy link
Contributor

@mike-spa mike-spa commented Nov 28, 2023

Resolves: #17940 *
Resolves: #17752

Shoutout to @sammik for figuring out the true cause of the corruption and logging the clearest issue.

* (corruptions will still be reported in this file, but these are identical to those that 3.6 reports; it will now actually open and display)

@Jojo-Schmitz
Copy link
Contributor

Jojo-Schmitz commented Nov 28, 2023

The changes to the unit test scores reverts them back to what they looked like in Mu3. Not sure what that says about those tests though, no idea why they haed been change for Mu4 rather than triggering more investigations into the "why"?

Jojo-Schmitz added a commit to Jojo-Schmitz/MuseScore that referenced this pull request Nov 28, 2023
backport of musescore#20230, as far as it makes sense
Comment on lines 1745 to 1751
Rest* rest = Factory::createRest(segment2);
Rest* rest = Factory::createRest(ctx.score()->dummy()->segment());
rest->setDurationType(DurationType::V_MEASURE);
rest->setTicks(m->timesig() / timeStretch);
rest->setTrack(ctx.track());
readRest(m, rest, e, ctx);
if (!rest->segment()) {
rest->setParent(segment2);
}

Segment* segment2 = m->getSegment(SegmentType::ChordRest, ctx.tick());
rest->setParent(segment2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand this change yet. So in the old situation, a rest was created with the segment specified as the parent; but then m_isParentExplicitlySet is still false, so explicitParent returns nullptr, and thus segment() too; and thus the parent does get set explicitly in the old line 1751.
And in the new situation, actually exactly the same thing happens, except that the initial parent (which doesn't really count anyway) is the dummy segment.

(I'm not saying I don't like the change, I'm just wondering about is since I still don't fully understand it 🙂)

Also, from the lines below, segment2 = rest->segment(); looks a bit unnecessary now; and inside readRest there is also some code that looks suspiciously similar to the code you modified, so I wonder if that would need to be adjusted too.

Copy link
Contributor Author

@mike-spa mike-spa Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On old files, the way that the second voice was written was not by opening a new <voice> tag, like we do now, but by using a <tick> tag to "rewind" the time. As in: write the first voice for the whole measure, then rewind the tick to the beginning of the measure, then write the second voice. The problem is that the <tick> tag which signals the rewind is written inside the <rest> and therefore read as part of readRest(), but segment2 was created earlier, when the tick was still at the end of the measure. As a result, the rest was being created at the end of the measure instead of the start.
The end of the story is: we shouldn't perform m->getSegment(...) until we have read the rest, hence why I'm now creating it with a dummy segment and setting the true segment later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, from the lines below, segment2 = rest->segment(); looks a bit unnecessary now

True, corrected it now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aah, that makes a whole lot of sense! :)

Jojo-Schmitz added a commit to Jojo-Schmitz/MuseScore that referenced this pull request Nov 30, 2023
backport of musescore#20230, as far as it makes sense
Not actually related to the corruption, but still a clear error: as it was, the method was always returning true.
unknown() is already called by the caller of this function where necessary, it shouldn't be called here.
This was corrupting entire scores because it was setting full-measure rests to wrong durations. At this stage timeSigMap isn't computed yet, so it can't be used.

The case of full-measure rests seems to be correctly managed anyway, without needing this check.
@mike-spa mike-spa force-pushed the fixCorruptionIssuesOnOldFiles branch from cb7f2db to 2678c54 Compare November 30, 2023 08:59
@cbjeukendrup cbjeukendrup merged commit e916524 into musescore:master Nov 30, 2023
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants