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: division by zero in compatmidirenderer #24839

Closed
wants to merge 1 commit into from

Conversation

mikekirin
Copy link
Contributor

No description provided.

@RomanPudashkin RomanPudashkin added crash Issues involving a crash of MuseScore MIDI Issues related to MIDI input/export, or MIDI devices labels Sep 20, 2024
Copy link
Contributor

@cbjeukendrup cbjeukendrup left a comment

Choose a reason for hiding this comment

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

It might be nice to keep the logic somewhat synchronised with TremoloRenderer::doRender (as far as possible, of course, because there are also differences of course).

src/engraving/compat/midi/compatmidirender.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@cbjeukendrup cbjeukendrup left a comment

Choose a reason for hiding this comment

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

Sorry, I realised that there are still some issues...

if (t == 0) { // avoid crash on very short tremolo
t = 1;
}
double tpoch = muse::RealIsNull(tremoloPartOfChord) ? 1.0 : tremoloPartOfChord;
Copy link
Contributor

Choose a reason for hiding this comment

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

I took another look and this check appears to be unnecessary: just at the top of CompatMidiRender::renderTremolo, we already have

    if (muse::RealIsNull(tremoloPartOfChord)) {
        return;
    }

Comment on lines +409 to +410
int tremoloEventsSize = static_cast<int>(static_cast<double>(chord->ticks().ticks())
/ (static_cast<double>(t) * tpoch));
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the double casts don't make a difference here: when (static_cast<double>(t) * tpoch) > chord->ticks().ticks(), then the result of the division would be between 0.0 and 1.0, so casting that back to int will still result in 0.

But you are changing the meaning of the code. Essentially, this is what's happening:

-(chord->ticks().ticks() / t) * tremoloPartOfChord
+chord->ticks().ticks() / (t * tremoloPartOfChord)

I think that's incorrect: if the whole chord were a tremolo, then (chord->ticks().ticks() / t) would be the correct number of events; and if only part of the chord is a tremolo (i.e. tremoloPartOfChord < 1) then (chord->ticks().ticks() / t) * tremoloPartOfChord would be the correct number.

It looks like the calculation of tremoloEventsSize can stay as it is (even extra casts to double would not have any effect); all that's needed would be to check that tremoloEventsSize is not zero. If it is zero, then just do an early return, since the for loop below would not be run anyway in that case.

Apart from that, the precision of the calculations could of course be improved, by utilising Fraction and/or double everywhere, i.e. in t, tremoloEventsSize, tremoloTime, tremoloEventStep; and cast to int only at the very end. (Note that that ensures so that t != 0, since that would only happen as a result of rounding errors.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok
Initially I had a problem in another branch and this branch just doesn't have this check which you've mentioned.

    if (muse::RealIsNull(tremoloPartOfChord)) {
        return;
    }

And this more than enough.
Thank you for your help and time, @cbjeukendrup

Closing this PR.

@mikekirin mikekirin closed this Sep 23, 2024
@mikekirin mikekirin deleted the division-by-zero-m branch September 23, 2024 10:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash Issues involving a crash of MuseScore MIDI Issues related to MIDI input/export, or MIDI devices
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants