Plugin API: harmony.text field is not available

• Apr 27, 2018 - 16:43
Reported version
P1 - High
S5 - Suggestion

I'm trying to write a plugin for which I need to be able to read the chord symbols in the current score. I can access the Harmony object of a given Segment (if there is one) through the [annotations] property. I'd like to use the harmony.text property to determine the quality/extensions etc of a chord symbol but in a newly opened score this field doesn't appear to be set properly (every Harmony object has an empty string for it's text property).

After double clicking a chord symbol to edit it the text field contains the correct value (even if the chord is not modified - just opened for editing and then esc is pressed immediately). Once the first chord is in edit mode, the other chords can be cycled through with space/tab and their text fields will be correct too.

Tested using MuseScore 2.2.1 and the 2.3 development branch on Arch Linux.


Severity S4 - Minor S5 - Suggestion

AFAIK this is currently by design. The .text property only relates to the non-parsed input text for the Harmony.
But I do agree that it would make sense to have it filled at construction time.

OK, so is there any other way to find what the chord symbol is? The built-in plugin documentation for the Harmony object mentions the id field being the harmony identifier, does that refer to the chord symbol? The values I get from the id field don't correspond to any of the chord ids in the various chord XML files, are they supposed to? If so, I'd better make another report...

I believe the "id" field is a leftover from musescore 1.x which did have quite a big list of known Chords (as that was from before the text was really parsed/understood).
I fear that your only solution will have to be "fixing" the text property on the MuseScore side.

"id" indeed has no useful user-visible purpose any more and is retained for historical reasons only.

In theory, we could eventually expose our internal parsed representation of the chord as well as the raw text field, but as noted, the latter isn't actually populated until necessary.

It seems that "id" has a meaning, but it's not as in MuseScore 1, where styles/chords.xml contained 241 chord types. I put a console.log in my plugin and found five id values:
1001 = major
1002 = diminished
1003 = minor
1004 = dominant seventh
1005 = augmented

Yes, MuseScore 1.x was severely hampered by the requirement to have a fixed finite list of accepted chords, that had to be typed exactly as expected in order to be recognized. Thus, there was a fixed finite set of id's. MuseScore 2 is far more flexible, able to parse and make sense out of virtually anything, so it no longer depends on a fixed list of id's. i'ds as, as I mentioned, used internally, but they are generated as needed on the fly, so the specific id's for different chords will vary from score to score. I can't really imagine any particular use they would have to plugins, but if you can describe a real world use case for this, I'm sure it could be considered. But really, it's the text field that is more likely to be useful. This currently doesn't get populated on read but only on edit, but we could presumably add something to force it to be populated on demand.

I'm replying to Marc's comment in #277020: plugins: element "harmony", empty field "text" after loading score (replying here as this issue is the feature request):

"Now that the plugin framework is beginning to stabilize again (?) for 3.0, maybe this can be dealt with. All we'd need to do is force the text to be generated on load the same way we do on edit, shouldn't be difficult."

Actually the reason I wanted to access the text field in the first place is to be able to find what the chords are, and the Harmony.text field was a means to that end. But what would be really nice is to have access to the internal parsed representation in some way, for example the chord with input text C7b9#11/Bb would give something similar to:

Harmony.root -> "C"
Harmony.quality -> "dominant"
Harmony.extensions -> ["b9", "#11"]
Harmony.bass -> "Bb"

Does Musescore already have some notion of these chord properties internally?

When I initially reported this it was because I thought that the text field not being filled was a bug, but in the context of a feature request having access to the chord components would be more useful. For the plugin I was writing, given the raw text, it would have to do that parsing on its own anyway (I assume most of us wanting to make use of this field would be in a similar situation).

Obviously this might be a less straightforward addition than simply filling the text field earlier, and I wouldn't be surprised if it's a lower priority for you. But if work is happening on the plugin framework for 3.0, perhaps this could be considered.

Anyway, if this particular issue is considered a feature request for access to the raw text, should I file a separate issue for what I wrote above?

In reply to by othersimon

MuseScore does parse a chord into a format not unlike that at all, and in principle exposing that to the plugin framework is no more difficult than exposing the raw text. It wouldn't hurt to create a separate issue, although probably if/when someone gets around to this, they'll deal with both at once anyhow.

Fix version