Chord symbols with a bass extension don't export to MusicXML correctly (nor import back)

• May 3, 2021 - 21:52
Reported version
3.6
Type
Functional
Frequency
Few
Severity
S3 - Major
Reproducibility
Always
Status
closed
Regression
No
Workaround
Yes
Project

Had issue with exported files from different projects so tried creating new score.

Done the same with two MIDI files.
1) Created new score in musescore
2) Copied notes from midi.
3) ran Chord Identifier(pop,Jazz)
4) Export file as mxl (MusicXML)

load in Finale - get XML error "the content of element type "Harmony" must match ..."
Load in Dorico - get MusicXML validation failed (ERROR - Element 'bass': this element is not expected. ...)

Attachment Size
test02.mscz 49.28 KB
test.mscz 35.21 KB
test02.mxl 49.52 KB
newtest.mxl 29.8 KB

Comments

Workaround No Yes

On import into MuseScore 3.6.2 test02.mxl gives:
Fatal error: line 622 column 14 Element bass is not defined in this scope.

On import into MuseScore 3.6.2 newest.mxl gives:
Fatal error: line 4397 column 14 Element bass is not defined in this scope.

This is the questionably XML code:

      <harmony print-frame="no">
        <root>
          <root-step>E</root-step>
          <root-alter>-1</root-alter>
          </root>
        <kind parentheses-degrees="yes">major</kind>
        <degree>
          <degree-value>9</degree-value>
          <degree-alter>0</degree-alter>
          <degree-type>add</degree-type>
          </degree>
        <bass>                                                      <!-- this line  -->
          <bass-step>F</bass-step>
          </bass>
        </harmony>
 

Both match Dorico's message, and are taken right from the MusicXML specification.

In both cases MuseScore imports them when ingnoring that error

Are there steps to reproduce this don't involve running a plugin? I haven't encountered issues with chords I enter by hand. Maybe the plugin is creating the chords incorrectly?

Title MusicXML not valid when load into other applicaitons. Certain chord symbols not export to MusicXML correctly (generated by plugin)
Status active needs info

I tried a different plugin and got the same errors. but if the plugin was set to not include BASS the musicXML file worked.
Plugins used (ChordIdentifierPopJazz, ChordIdentifierSp3_2)

When comparing the list of errors from Dorico with the XML in the file found it would error when the was after a section. Found other sections containing showing no errors.

Attachment Size
Test02 dorico errors.txt 12.2 KB

I wonder how a plugin can add information to a score that doesn't then export to MusicXML, and why these can't (or don't) get added when 'manually' adding chord symbols.
I wonder what the shortest possible score(like having just one such 'bogus' cord symbol) looks like that exhibits this issue. Would like to compare it with the same score but bit the same chord symbol entered manually. That'd help pinpointing the real underlying issue I guess

Here's a minimal example.
text.mscx has the chord symbol as:

          <Harmony>
            <root>11</root>
            <name>m(add9)</name>
            <base>13</base>
            </Harmony>
 

Exporting it to test.musicxml results in

      <harmony print-frame="no">
        <root>
          <root-step>E</root-step>
          <root-alter>-1</root-alter>
          </root>
        <kind text="m" parentheses-degrees="yes">minor</kind>
        <degree>
          <degree-value>9</degree-value>
          <degree-alter>0</degree-alter>
          <degree-type>add</degree-type>
          </degree>
        <bass>
          <bass-step>F</bass-step>
          </bass>
        </harmony>
 

and on import leads to the complaint:
Fatal error: line 106 column 14 Element bass is not defined in this scope.

What is strange is that there are 2 more harmonies in the muscixml

      <harmony print-frame="no">
        <root>
          <root-step text="">C</root-step>
          </root>
        <kind text="">none</kind>
        </harmony>
 

apparently stemming from the mscx:

          <Harmony>
            <name></name>
            </Harmony>
 

Trying to get to those (double-clicking the first and only visible chord symbol, pressing space twice) results in a crash...
I guess the plugin inserted those invisible ones.
So we'd need 2-3 more issuues, 1 against (each of= the plugin(s) to not insert empty chord symbols and 1 against MuseScore to not crash on those. I've just done the latter, see #320862: Empty chord symbols causes crash

Attachment Size
test.mscx 10.87 KB
test.musicxml 8.3 KB

Adding the same chord symbols 'manually' results in the mscx to look like this:

          <Harmony>
            <root>11</root>
            <rootCase>1</rootCase>
            <name>m(add9)</name>
            <base>13</base>
            <baseCase>1</baseCase>
            </Harmony>
 

Different from before, but in the musicxml still looks like this:

      <harmony print-frame="no">
        <root>
          <root-step>E</root-step>
          <root-alter>-1</root-alter>
          </root>
        <kind text="m" parentheses-degrees="yes">minor</kind>
        <degree>
          <degree-value>9</degree-value>
          <degree-alter>0</degree-alter>
          <degree-type>add</degree-type>
          </degree>
        <bass>
          <bass-step>F</bass-step>
          </bass>
        </harmony>
 

and, of course, still results in the same error.

Title Certain chord symbols not export to MusicXML correctly (generated by plugin) Certain chord symbols not export to MusicXML correctly

So somehow the Chord Symbol "E♭m(add9)/F" is causing grief here, and it is not related to those plugins

Unfortunately, it is easy to define the correct output, but due to lack of familiarity with the Harmony class, I find it somewhat difficult to create a fix that is certainly correct. I did look at it, but can't quickly fix it.

I'm not really following all this, could someone give a simple set of steps for me to follow? Or describe in more detail what needs to happen and I can explain whatever is needed about the Harmony class.

Title Certain chord symbols don't export to MusicXML correctly Chord symbols with a bass extension don't export to MusicXML correctly (nor import back)

So, the bass info is written here:

https://github.com/musescore/MuseScore/blob/bd3c7495800b275fa3793afb840…

This would need to be moved up to right before the degree is written:

https://github.com/musescore/MuseScore/blob/bd3c7495800b275fa3793afb840…

That section is code is within an "if" that is designed to handle kinds we know about. For kinds we don't know about, we could conceivable also copy that same bass code to the "else" clause:

https://github.com/musescore/MuseScore/blob/bd3c7495800b275fa3793afb840…

Note - it would also be possible to restructure the code to not separate the clauses out so much. But I'm not really sure what the real world cases are that would trigger that "else". Seems they'd be likely to also generate an invalid kind. The xmlKind is normally set through a pretty exhaustive set of special case tests, in this general area:

https://github.com/musescore/MuseScore/blob/master/src/engraving/libmsc…

So the trick would be figuring out what fell through the cracks. I wrote that code, and am not particularly proud of it, but also, realistically, the syntax of chord symbols and the way MusicXML represents them are complex enough that it would be tough to make it much more elegant.

So bottom line, I wouldn't risk restructuring that original if/then and breaking something. Just duplicate the bass code in both clauses and call it a day, is my recommendation.

@@Marc Sabatella: I understand your 1st and 2nd point (moving the bass code and where to), and that indeed does seem to solve the issue, but not the 3rd point, what exactly to copy into that else branch, that same bass code? Just one level up? Or 2 levels? Why would that be needed?

What I seem to have been saying is, right now the code in question happens whether h->xmlKind().isEmpty() or not - it happens after both the if & else clauses of https://github.com/musescore/MuseScore/blob/bd3c7495800b275fa3793afb840…. By moving the code as your PR does, it means the code happens at the right time if it happens at all, but it happens only happens in the "if" clause, not also in the "else" clause.

I think the else clause really just an error condition - I don't think "xmlKind" should ever be empty for a well-formed chord symbol. Maybe something like "Cgarbage/D" but do we really expect meaningful MusicXML output in that case? ANyhow, with your PR, if we ever do hit the else clause, the bass info won't be written at all. So I was suggestion copying that same block of code to the else clause as well - right after https://github.com/musescore/MuseScore/blob/bd3c7495800b275fa3793afb840…. That way the bass info gets written whether xmlKind is empty or not.

Fixed in branch master, commit 9b56d47568

_Merge pull request #17693 from Jojo-Schmitz/musicxml-chord-symbols-bass

Fix #320818: Chord symbols with a bass extension don't export to MusicXML correctly (nor import back)_

Fixed in branch 4.1.0, commit 7d15ce0a43

_Merge pull request #18110 from Jojo-Schmitz/musicxml-chord-symbols-bass

Fix #320818: Chord symbols with a bass extension don't export to MusicXML correctly (nor import back)_

Fix version
4.1.0