w3c / musicxml

MusicXML specification
479 stars 56 forks source link

*Après un rêve* example lacks a `cautionary` attribute for last accidental #500

Open lemzwerg opened 2 months ago

lemzwerg commented 2 months ago

In the MusicXML listing of Après un rêve, bar 4, first beat, the a flat accidental in the lowest staff lacks a cautionary="yes" attribute.

image

At least I think it should be added, because this accidental definitely is a cautionary one in the classical sense: According to Gould's Behind Bars, a cautionary accidental can be either a plain accidental, an accidental in parentheses, or an accidental above the note – it is thus a semantic markup. However, it seems that major MusicXML handlers (I've tested Finale and MuseScore) automatically convert the cautionary attribute to a parenthesized accidental. If this is the intention, the description of this attribute should be clarified accordingly.

Jojo-Schmitz commented 2 months ago

In MuseScure (3.x) I see:

static Accidental* accidental(QXmlStreamReader& e, Score* score)
      {
      const bool cautionary = e.attributes().value("cautionary") == "yes";
      const bool editorial = e.attributes().value("editorial") == "yes";
      const bool parentheses = e.attributes().value("parentheses") == "yes";
      const bool bracket = e.attributes().value("bracket") == "yes";
      const QColor accColor = e.attributes().value("color").toString();
      QString smufl = e.attributes().value("smufl").toString();

      const auto s = e.readElementText();
      const auto type = mxmlString2accidentalType(s, smufl);

      if (type != AccidentalType::NONE) {
            auto a = new Accidental(score);
            a->setAccidentalType(type);
            if (cautionary || parentheses) {
                  a->setBracket(AccidentalBracket(AccidentalBracket::PARENTHESIS));
                  a->setRole(AccidentalRole::USER);
                  }
            else if (editorial || bracket) {
                  a->setBracket(AccidentalBracket(AccidentalBracket::BRACKET));
                  a->setRole(AccidentalRole::USER);
                  }
            if (accColor.isValid()/* && preferences.getBool(PREF_IMPORT_MUSICXML_IMPORTLAYOUT)*/)
                  a->setColor(accColor);
            return a;
            }

      return 0;
      }

so yes, cautionary gets parenthesized on import

lemzwerg commented 2 months ago

Thanks for confirmation – LilyPond's musicxml2ly converter does the same, BTW.

My conclusion: the MusicXML standard should explicitly mention that the attributes editorial and cautionary do exactly the same as bracket and parentheses, respectively, for the sake of compatibility.

And let's hope that MNX will do better in separating semantic from visual appearance.

lemzwerg commented 2 months ago

Something else: Is the glaring typo in the last bar of Fauré's song intentional? The last two chords in the fourth bar are wrong; there should be a 'b flat' and not 'c':

image

Jojo-Schmitz commented 2 months ago

Note that MuseScore just now changed this slighlty: it still imports with brackets/parentheses, but not any longer if these are explicitly switched off. On export it explicitly switches them off if there are no brackets/parentheses in the score

see https://github.com/musescore/MuseScore/blob/3463d14ca6df411f69c048b688719d25f264db5a/src/importexport/musicxml/internal/musicxml/importmxmlnotepitch.cpp#L49-L82 and https://github.com/musescore/MuseScore/blob/3463d14ca6df411f69c048b688719d25f264db5a/src/importexport/musicxml/internal/musicxml/exportxml.cpp#L2832-L2845

mscuthbert commented 2 months ago

Ah, I logged on specifically to ask this -- what is the behavior if cautionary="yes" but parentheses is explicitly turned off. Is this standard enough across modern rendering systems that we can make this a recommendation going forward, that parentheses defaults to no unless cautionary is yes, but can be overridden?

It does make good sense to have an indication of why the accidental is being shown (cautionary="yes/no"), how it should be displayed (parentheses, etc.), and also to have sensible defaults for interpretation if one is set and not the other.

mscuthbert commented 2 months ago

Will look into the wrong note after checking both old and new sources for the piece. Funny, I never even considered that the music on the example might be wrong in addition to the encoding.

lemzwerg commented 2 months ago

what is the behavior if cautionary="yes" but parentheses is explicitly turned off

It's not clear to me what you mean with 'explicitly turned off' – do you mean a global setting within the rendering system, or whether the parentheses attribute is set to no?

I can imagine that the combination

<accidental cautionary="yes" parentheses="no">

is equal to what I've called forced in a similar question for MNX, i.e., a cautionary accidental that doesn't have parentheses, and which would be right for the above Fauré example.

Jojo-Schmitz commented 2 months ago

the latter, parentheses="no", basically making "yes" the default

lemzwerg commented 2 months ago

Thanks for the code links, very helpful. What I notice is that the new MusicXML import code of MuseScore makes bracket and parentheses mutually exclusive. I have never seen that in the wild, but theoretically there could be the need for a parenthesized accidental surrounded by brackets...

Jojo-Schmitz commented 2 months ago

Well, MuseScore can't have both at the same time/accidental, independent from MusicXML

lemzwerg commented 2 months ago

ok, thanks. What is the policy of MuseScore (or other major notation programs) if it encounters MusicXML constructions that can't be supported (contrary to invalid MusicXML)? Is there an extended 'lint' mode that checks input files and reports such things? Especially for larger pieces I can imagine that due to such issues stuff gets silently omitted or is incorrectly converted.

Jojo-Schmitz commented 2 months ago

MuseScore silently ignores them. It might write something to the logs or to stderr.