[MusicXML] Support breaks in secondary beams (import and export)

• Aug 17, 2015 - 20:10
S4 - Minor

Currently MuseScore's MusicXML engine ignores breaks in secondary beams -- both when importing MusicXML and when exporting to MusicXML.

Here's example data for you. I created the following notation in Finale:


The attached MusicXML file musicxml_broken_secbeams.xml was generated by Finale with the latest Dolet plugin. When I import this in MuseScore 2.0.2, the beam breaks are ignored:


The attached MuseScore file musicxml_broken_secbeams.mscz has broken secondary beams. When I export it to MusicXML using MuseScore, the secondary beams are no longer broken in the resulting MusicXML file (musicxml_broken_secbeams_musescore.xml).


I would be happy to put together a test for the MuseScore test suite, but it's not immediately obvious to me how I can do that. Let me know, and I'll get to work! :-)

Hi Adrian, Thank you for the report.

A more involved MusicXML file made with Finale involving 32nd beam too would be very helpful.
Something like this

Capture d'écran 2015-08-18 10.10.50.png

Indeed export is more complex, especially when "auto" beams are involved.
I tried this inside the writeBeam function:
{syntaxhighlighter brush:c++;collapse:true;}
// find beam level previous chord
for (int i = idx - 1; blp == -1 && i >= 0; --i) {
ChordRest* crst = elements[i];
if (crst->type() == Element::Type::CHORD) {
if ((static_cast<Chord*>(cr))->beamMode() == Beam::Mode::BEGIN32) // hack: using cr instead of crst
blp = 1;
else if ((static_cast<Chord*>(cr))->beamMode() == Beam::Mode::BEGIN64) // hack: using cr instead of crst
blp = 2;
blp = (static_cast<Chord*>(crst))->beams();
// find beam level current chord
blc = (static_cast<Chord*>(cr))->beams();
// find beam level next chord
for (int i = idx + 1; bln == -1 && i < elements.size(); ++i) {
ChordRest* crst = elements[i];
if (crst->type() == Element::Type::CHORD) {
if ((static_cast<Chord*>(crst))->beamMode() == Beam::Mode::BEGIN32)
bln = 1;
else if ((static_cast<Chord*>(crst))->beamMode() == Beam::Mode::BEGIN64)
bln = 2;
bln = (static_cast<Chord*>(crst))->beams();
and it works for beams set with the beam options (the score in the issue report, for example). However, beams set with "auto" options are more complex: where the "auto" options is internally considered as "begin32" or "begin64"?
Try for example to input 8 consecutive 32nd notes inside My_First_score. They are divided in two group of 4 notes with a single beam linking the two groups, but they give all "auto" as beamMode.
Moreover, the handling of the direction of a hook (forward or backward) of a broken beam is probably not easy.

Was off-line for a short vacation, could not reply sooner.

Code looks OK to me, but I am not very familiar with MuseScores beam handling details, so I may misunderstand some things.

Does it also handle forward and backward hooks correctly ? Such as when one of the 16th around the split in the first example is a dotted 16th paired with a 32nd ?