BIAB MGU Import loses note durations, MuseScore crashes on save

• May 5, 2020 - 09:31
Reported version
3.4
Type
Functional
Frequency
Few
Severity
S2 - Critical
Reproducibility
Always
Status
active
Regression
Yes
Workaround
Yes
Project

Download, unzip and import the attached MGU file into MuseScore. Result:
MuseSore-MGU.jpg

In BIAB it looks like this though:
BIAB-MGU.jpg

On top, if (auto)saving that score, MuseScore crashes


Comments

Strack trace on Save as:

1 Ms::Fraction::ticks fraction.h 238 0xfce99d
2 Ms::ChordRest::writeProperties chordrest.cpp 182 0x8d7bff
3 Ms::Chord::write chord.cpp 973 0x8b67a6
4 Ms::Score::writeSegments scorefile.cpp 1321 0xad4329
5 Ms::Measure::write measure.cpp 1896 0x98c7e3
6 Ms::writeMeasure scorefile.cpp 73 0xacc427
7 Ms::Score::writeMovement scorefile.cpp 237 0xacda95
8 Ms::Score::write scorefile.cpp 270 0xace0e0
9 Ms::Score::saveFile scorefile.cpp 763 0xad12e3
10 Ms::Score::saveCompressedFile scorefile.cpp 611 0xad00e0
11 Ms::Score::saveCompressedFile scorefile.cpp 533 0xacf936
12 Ms::MuseScore::saveAs file.cpp 2046 0x4c0af7
13 Ms::MuseScore::saveAs file.cpp 2577 0x4c4cac
14 Ms::MuseScore::cmd musescore.cpp 6179 0x42fb8d
15 Ms::MuseScore::cmd musescore.cpp 5956 0x42e933
16 Ms::MuseScore::qt_static_metacall moc_musescore.cpp 513 0x59e6eb
17 QMetaObject::activate(QObject *, int, int, void * *) 0x68a947c8
18 QActionGroup::hovered(QAction *) 0x2aad4db2
19 QActionGroup::qt_static_metacall(QObject *, QMetaObject::Call, int, void * *) 0x2aad573c
20 QMetaObject::activate(QObject *, int, int, void * *) 0x68a947c8
...

Looks like a division by 0 in

            const auto result = sgn * (static_cast<int_least64_t>(sgn * _numerator) * MScore::division * 4 + (_denominator/2)) / _denominator;

Preventing the crash seems easy:

$ git diff
diff --git a/libmscore/fraction.h b/libmscore/fraction.h
index 0c05c55c2..658959076 100644
--- a/libmscore/fraction.h
+++ b/libmscore/fraction.h
@@ -228,7 +228,7 @@ class Fraction {
 
       int ticks() const
             {
-            if (_numerator == -1 && _denominator == 1)        // HACK
+            if ((_numerator == -1 && _denominator == 1) || _denominator == 0)        // HACK
                   return -1;
 
             // MScore::division     - ticks per quarter note

But after that the score (of course) gets reported as corrupt:

Measure 2, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 4, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 6, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 8, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 10, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 11, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 12, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 13, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 14, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 15, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 16, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 18, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 19, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 20, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 21, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 22, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 23, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 24, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 25, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 26, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 27, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 28, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 29, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 30, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 31, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 32, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 34, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 35, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 36, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 37, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 38, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 39, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 40, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 41, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 42, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 44, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 46, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 48, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 50, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 52, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 54, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 56, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 58, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 59, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 60, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 61, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 62, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 63, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 64, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 66, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 67, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 68, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 69, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 70, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 71, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 72, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 73, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 74, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 76, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 78, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 80, staff 1 incomplete. Expected: 4/4; Found: 0/1
Measure 81, staff 1 incomplete. Expected: 4/4; Found: 0/1

Interesting that some few measures are not corrupt.

And the durations are (of course) still incorrect

Another possible workaround might be to go through the entire score right after the import, select one note/ (and rest) after the other, check the status bar for the beat of the next note and change the durations accordingly (probably best to go through the score backwards, last to first). Need to switch off autosave during the process though

Title BIAB MGU Import looses note durations, MuseScore crashes on save BIAB MGU Import loses note durations, MuseScore crashes on save

The crash is pretty eassy to resolve, as mentioned earlier (I just reinvented the wheel :-()

diff --git a/libmscore/fraction.h b/libmscore/fraction.h
--- a/libmscore/fraction.h
+++ b/libmscore/fraction.h
@ -237,7 +237,7 @@ class Fraction {

      int ticks() const
            {
            if (_numerator == -1 &amp;&amp; _denominator == 1)        // HACK
            if ((_numerator == -1 &amp;&amp; _denominator == 1) || _denominator == 0)        // HACK
                  return -1;

            // MScore::division     - ticks per quarter note

Which IMHO is a sane thing to do, to prevent division by 0 faults.
But it does nothing to fix the broken BIAB import, the scores are still utterly corrupt