Git Product home page Git Product logo

Comments (6)

webern avatar webern commented on May 25, 2024

So, the backstory is that mx::core is an exact(ish) representation of the MusicXML. As such it is quite difficult to use because it supports so many features. The MusicXML spec is a beast.

The easier mx:api structure was meant to simplify everything by restricting features.

The MusicXML document lives in memory as an mx::core data structure and is converted to-and-from mx:api through the DocumentManager such that mx::core is never exposed to the user of mx::api.

Currently I don't think you can easily get the mx::core representation from the DocumentManager. The only way I can think of to do this would be to return some sort of void* and say, "don't use this function unless you know what you're doing", then that void star could be "downcasted" to a DocumentPtr.

Alterations to that DocumentPtr that are not 'supported' by mx:api would be lost when round-tripping mx::core->mx::api->mx::core. But you could conceivable make alterations when you are done with mx::api and then serialize the DocumentPtr.

Anyway, if it's just for the Db Minor, it might not be necessary. I'm wondering what happens if you specify keyData.fifths = -8; keyData.mode = KeyMode::minor;

Can you show me the musicxml representation that you want as your output?

from mx.

webern avatar webern commented on May 25, 2024

I created #45 because I think that you will bump up against other places where you need more features than mx::api exposes, even if the key signature turns out to be a non-issue.

from mx.

webern avatar webern commented on May 25, 2024

I did a little research. This program:

    mx::api::ScoreData score;
    score.workTitle = "Db Minor";
    mx::api::PartData part;
    part.displayName = "Flute";
    part.instrumentData.uniqueId = "FLUTE1";
    part.instrumentData.soloOrEnsemble = SoloOrEnsemble::solo;
    part.instrumentData.soundID = SoundID::windFlutesFlute;
    part.measures.emplace_back();
    auto& measure = part.measures.back();
    mx::api::KeyData dbMinor;
    dbMinor.fifths = -8;
    dbMinor.mode = KeyMode::minor;
    measure.keys.push_back( dbMinor );
    score.parts.push_back( std::move(part));
    auto& docMgr = mx::api::DocumentManager::getInstance();
    const auto id = docMgr.createFromScore( score );
    std::cout << std::endl;
    docMgr.writeToStream(id, std::cout);
    std::cout << std::endl;

Produces this xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.0 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
<score-partwise>
  <work>
    <work-title>Db Minor</work-title>
  </work>
  <part-list>
    <score-part id="ID">
      <part-name print-object="no" />
      <part-name-display>
        <display-text>Flute</display-text>
      </part-name-display>
      <score-instrument id="FLUTE1">
        <instrument-name />
        <instrument-sound>wind.flutes.flute</instrument-sound>
        <solo />
      </score-instrument>
    </score-part>
  </part-list>
  <part id="ID">
    <measure number="1">
      <attributes>
        <divisions>420</divisions>
        <key>
          <fifths>-8</fifths>
          <mode>minor</mode>
        </key>
      </attributes>
    </measure>
  </part>
</score-partwise>

I opened this in Finale, Dorico and MuseScore. None of them produce precisely the key signature that you linked to on wikipedia. MuseScore gets it wrong, Finale and Dorico produce the right flats but they have the Bbb on the left instead of the right.

Finale

image

Dorico

image

MuseScore

image

How do they Represent Db Minor?

Neither MuseScore nor Finale has a way of creating Db Minor through the easy path, both would require the user to construct a custom key signature. With Dorico, you can create Db Minor through the usual interface, and it again places the B double-flat on the left.

What if I need the Bbb on the Right

If you absolutely need the Bbb on the right instead of the left, as it is pictured in the Wiki link, then I discovered by creating a custom key signature with MuseScore and exporting... MusicXML can specify it like this:

<key>
          <key-step>E</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>A</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>D</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>G</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>D</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>F</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>B</key-step>
          <key-alter>-2</key-alter>
          <key-accidental>flat-flat</key-accidental>
</key>

Conclusion

I think the best way to represent Db Minor semantically in MusicXML is probably like this (which can be done using mx::api.):

        <key>
          <fifths>-8</fifths>
          <mode>minor</mode>
        </key>

But if you want to represent it the other way (key-alter, key-accidental) then we will have to come up with a solution either by adding this to mx::api or otherwise.

from mx.

p-groarke avatar p-groarke commented on May 25, 2024

Thanks for the research! I did try using the -8 value previously. I use musescore and it doesn't display the correct key signature (you can see no Bbb in your screenshot). I thought the problem was with Mx/musicxml, but it seems to be musescore after all. Reading the musicxml manual doesn't specify the min/max of that element.

In musescore, if you create a custom key for d flat minor and save to music xml, you'll get this output. Which is what I believe the core apis can do.

        <key>
          <key-step>E</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>A</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>D</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>G</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>C</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>F</key-step>
          <key-alter>-1</key-alter>
          <key-accidental>flat</key-accidental>
          <key-step>B</key-step>
          <key-alter>-2</key-alter>
          <key-accidental>flat-flat</key-accidental>
          </key>

(The order is wrong, but it's "good enough").

I also think the best solution is to use <fifths> element. I'll send a feature request to musescore for it, but I doubt it'll be supported anytime soon.

In how this applies to Mx, if I can get the mx::core DocumentPtr like you mention in issue #45, than I'm all good. I have no issue doing the conversion from -8 to NonTraditionalKey myself before serializing. Of course, if you feel like adding custom key support to mx::api, I won't complain ;)

Cheers.

edit : I can't post a feature request for it since you need a paying subscription to do so.

from mx.

webern avatar webern commented on May 25, 2024

BTW, it is possible to poke into the mx::core data structure with this;
#45 (comment)

from mx.

p-groarke avatar p-groarke commented on May 25, 2024

Perfect, I'll let you know if I hit any roadblocks with it.

from mx.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.