mir_eval icon indicating copy to clipboard operation
mir_eval copied to clipboard

Chord encoding always adds root note even if not annotated

Open fdlm opened this issue 6 years ago • 4 comments
trafficstars

Currently, the root of the chord is always added to the semitone bitmap. The encoding thus does not distinguish between, e.g., C:maj (or, C:(1,3,5)) and C:(3,5):

>>> mir_eval.chord.encode('C:maj')
(0, array([1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]), 0)
>>> mir_eval.chord.encode('C:(3,5)')
(0, array([1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]), 0)

According to Harte's format definition (see his dissertation, page 100), the two should be treated differently:

This syntax also allows for the case where we have a chord with an implied root note (such as the C major chord in the example from the second bar in Figure 4.6). In the example of the C major chord where the root is not voiced (Figure 4.7d) we can represent it in this way: C:(3,5)

fdlm avatar Jan 13 '19 16:01 fdlm

@ejhumphrey @bmcfee

craffel avatar Jan 13 '19 19:01 craffel

I see what you mean, but I think the example that Harte gives is inconsistent with the general semantics of added / suppressed notes. My understanding, which may diverge from Harte's, is that notes in parenthesis are added or suppressed relative to the stated quality, and that the default quality (absent an explicit name) is a major triad. In that sense, a rootless C:maj could be encoded as C:(*1), where the 3 and 5 are left in by default. I would expect C:(3,5) to be a no-op on C:maj since those notes are already present.

If we do not take the above interpretation, then the consistent alternative is that when parentheses are used, all notes must be explicitly coded. I don't think that's how most people use this notation, but I'm willing to be convinced otherwise.

bmcfee avatar Jan 14 '19 15:01 bmcfee

In Harte's definition, parentheses are not used to denote added/suspended notes. Instead, they directly define the chord intervals. According to Harte, the fundamental notation is root : (interval1, interval2, ...) / bass. There is no such thing as "default quality" (see 4.2.3 in his diss). Shorthand notations like maj, min, sus2 etc. are only introduced afterwards. These "map directly to pre-defined interval lists for the most common chordtypes" (4.2.4). One can then change these pre-defined interval lists with additional intervals in parentheses, and remove intervals using the * symbol. As shown in his thesis, the syntax becomes root : shorthand (additional intervals) / bass.

I believe his definition is consistent, and I think we should stick to it until some better alternative is found. This probably does not affect many use cases, as annotations as G:(3,5) are rare, but I think they still should be parsed correctly (i.e., according to Harte's syntax definition).

fdlm avatar Jan 14 '19 16:01 fdlm

I think that makes sense -- I'd like to get @ejhumphrey and @mattmcvicar 's take on things as well, since they've been at chords longer than I.

Having thought about your interpretation a bit more, I think it all comes down to the default quality assumption. When a quality shorthand is explicitly coded, I think both of our interpretations are equivalent, and perhaps I was incorrectly generalizing the add/suppress notion to the case without shorthand.

bmcfee avatar Jan 14 '19 19:01 bmcfee