la-jarre-a-son / midi-jar

MIDI Jar is a tool box for musicians, learners, streamers, that want to route MIDI message between devices, and display a piano or chords while playing, and integrate it on a video or on a Twitch stream.
http://midi-jar.ljas.fr/
MIT License
77 stars 9 forks source link

Confusions with inversions #28

Open gotthehot opened 10 months ago

gotthehot commented 10 months ago

Expected Behavior

Simplest chords (triads, 7-th) inversions expected to be displayed as main chord (highest priority). Like midi-jar now displays Am/E chord:

ame-inversion

Current Behavior

Here is display for A/E (first) inversion

ae-inversion

Expected "A/E" display as main variant.

Here is display for C/E (second) inversion:

ce-inversion

Expected "C/E" display as main variant.

At least because both chords definitely sounds as pure major and are used in diatonic scales as A and C respectively.

Second inversion of minor chords displayed as 6 chord with omitted V but retains pure minor sound.

amc-inversion

Sometimes first inversion shows as expected but second (as far as I can see) never.

Role of inversions for 7-chord (except dominant-seventh) and more complex chords is not so clear topic (honestly it's a big mess) because of significant sound changes after inversions. But triads and dominant-7 inversions retain distinctive sound and thus their roles in diatonic scales they're used. So prioritizing of basic chords inversions have solid practical and functional background.

Steps to Reproduce

  1. Just play inversions of any major or minor triad

Suggested Solution (if any)

Globally prioritize basic triads inversions over their exotic relatives. Prioritizing of dominant-7 inversions also have a sense.

Your Environment

ArTiSTiX commented 9 months ago

Hello @gotthehot I'm still thinking about this issue, sorry for not having responded.

I'm working on the chord dictionary module, which could provide a way to eliminate any issue related to preferences in chord notation or detection.

Here is what the basic version on it look like: image

For your issue, i may implement 2 solutions:

I also plan to add a feature to also choose your preferred notation in the "Aliases" section, by toggling a little star next to it, so that you would be able to choose a new "preferred" chord notation setting (instead of only long/short/symbol).

image

LMKWYT about this, it could help me providing the best solution for the next release.

gotthehot commented 9 months ago

With such detailed approach utility becomes true offline chords encyclopedia. Definitely it should be helpful. But as for me such large chords database needs for some macro management to simplify refining and keep extensive dictionary functional.

For example: simple way to disable all maj13#11 and all minaddb9 chords without browsing all 12 keys. Or display some chord (Fm9 for your screenshot) but globally disable all too complex / uncommon chords interpretations (G#M7add13 or Eb6/11) thus display simple / common interpretations (for example Am7/C for C6 chord).

ArTiSTiX commented 9 months ago

@gotthehot of course you wouldn't have to disable for all keys, it will simple disable the whole chord type (it's just a disable toggle of the chord in tonal, which is something i was considering for a long time).

Also, navigation will be improved before release, the screenshot is the first basic implementation, but i'm already working it making it way easier to use (grouping chords by quality, or maybe making it iterative like "perfect 5th > minor 3rd > major 7th" sections would give you all chords derived from minmaj chords).

I'm currently working on the interactivity of the dictionary with 2 modes:

You will be able to go to the dictionary chord by through clicking on the chord display (chord, or a button, did not choose yet). And disabling a chord could be done then in the dictionary. Like disabling C6 will lead to detecting only considering Am7 inversion.

But if you are expecting C6 (and other major sixth chords) to still be detected as alternative, i would better consider having an ordering preference.

Once done, i may add an way to do it directly from the chord display, but that's not a prio, i fear this would be too much.

Note that the example you give is interesting, because the current calculation for the quiz complexity gives the same difficulty for both min7 and maj6 chords... so this ordering will not fix this particular example, which makes me think that this issue is highly related to personal preference and intepretation. How do you judge that a chord is a better interpretation than an other, not knowing anything more than the context.

Key signature could be an insight on the context, but this is complicated as soon as you consider key changes.

gotthehot commented 9 months ago

Right, 6th and m7 chords are similar not only for "complexity" but for functional purpose too. Usually 6th means "I want a touch of major here but with almost hidden majority" and m7 means "minor triad sounds too easy here, let me make it more mysterious with very gentle tend to next chord". Which of them to select is mostly a matter of diatonic scale you are in. And of chosen inversion - because all 7th chords except dominant-7th have inversion-sensitive sound in terms of ear perception.

Both 6th and m7 are side-by-side widely used in jazz, m7 is a bit more common. Unlikely somebody should have a will to disable only one of them. In general considering inversion sensitive sound I see the only algorithmic way to prioritize them: for m7, 6 and m6 chords always prefer basic form over inversions. I.e. C6 over Am7/C and Am7 over C6/A. As midi-jar does now.

ArTiSTiX commented 9 months ago

@gotthehot ok so that's basically what's currently implemented, so i may have misunterstood what you are say:

display simple / common interpretations (for example Am7/C for C6 chord).

You never expected Am7/C to be displayed over C6

but globally disable all too complex / uncommon chords interpretations (G#M7add13 or Eb6/11)

Thus this could be helpful to be able to disable M7add13 in dictonary so that it would display Fm9/G# instead. Same, disable 6/11 chord so that it display Fm11/Eb instead.

I think in both cases i calculated the same complexity too. The thing is, it's kinda hard to differentiate a G#maj7add13 (if the tonic is G#) to a Fmin9 inversion, and the detection algorithme does not take notes orders/octaves into account. So disabling uncommon chords could be a way to help it

gotthehot commented 9 months ago

Yes, Am7/C is really C6. There are complicated cases when inversions are used to simplify fingering and one inversion should be preferred over other concerning harmony context. For Am7 and C6 there is a basic "fingering shuffle" example. Progression Am7/E - Dm7 - G7/D - Cmaj7 (Fly Me To The Moon) uses inversion of tonic Am7/E, not C6/E as midi-jar shows now. But as for me showing Am7/E as alternative in case like this is not a harm.

ArTiSTiX commented 9 months ago

@gotthehot oh, you raised an interesting point here. Because the undetermined order here is as simple as... the order of the chords in the dictionary...

And while I was working on updating the chord dictionary from tonal, i also tried to order chords so that it's easier to maintained in code (starting from the original ordering of tonal)... not to be perfectly logic (even if it has impact on detection). And it happens that the order is (extracted from code comments):

So, min7 is simply after a majadd6... I might have some time to improve this order (like ensure unaltered chords are before additions, which are before altered additions and such...) while improving the chord dictionary with sections, it's a bit hard at the current state to see through a list of 152 chord types...

And this is clearly something that will need to be maintained/checked, and this is also the main reason i did not make a Pull Request to tonaljs yet: i am not confident enough in my skills and my work on the dictionary to make an update in one of the most used music theory library on the web. Tonaljs has become (unwillingly i suppose) kind of a reference, a lot of website use its dictionary, that i think is incomplete and a bit wrong sometimes... But because many times, developer forget to mention it's from tonal, i fear that it spreads incorrect knowledge, and that's not something i want for midi-jar, nor tonal if i contribute.

So once again, thank you for your help/suggestions.

gotthehot commented 9 months ago

imho above classification contains risk of things messing up. For example there are no "major diminished" triads because diminished chord consists of two minor thirds (augmented in turn - of two major thirds). Let me present my own prioritized chords list. More common chords first.

Triads

Four- & Five-notes Chords

Basic

NB: other seventh inversions as well as all sixth inversions should be used with care (or better not to be used) because of sound character significant changes after inversion. In general priority is always to basic form, if detected.

Relatively rare but usual for jazz

Much more exotic seventh chords personally I almost never seen in scores:


There are also "fifth chords" (aka "power chords") that are actually just intervals. Often with second tonic through octave. Used mostly for bass enhancing. Later note: current midi-jar 1.6.1 detects fifth chords excellent.

Hope structuring chords priority according to this list will decrease number of issues like "strange chord displayed".

piazic commented 9 months ago

I was also expecting to see some inversions as "main" chord, e.g. G/B seems more natural to me than Bm#5. It would be useful to have some way to favour such inversions.

ArTiSTiX commented 9 months ago

Hello @gotthehot and @piazic,

Thanks for the detailed answer about how to order chords better. I'll keep this in mind for later updates, because I think it has little influence on the algorithm, and it's a bit discouraging to have to go through all the chords in the dictionary again, i'll do it at another time. Most of the issues you reported was clearly not something i can really "fix", since for instance, detecting Bm#5 over a G/B inversion is logical as soons as min#5 chord is present in the dictionary, perfect matches will be prior to inversions or chords with omissions, and i doubt it makes much sense to give a complexity score that is not too opinionated. I'll consider it for later, i did not expect MIDI Jar to have a perfect nor complete chord dict/detection algorithm anyway so, as soon as i does not give wrong solutions, i consider it ok. I can't even imagine how this could also be WAYY more complicated if i was considering slash chords with bass notes not being an inversion but a compound chord, or even detecting stacked chords...

Now i just published the version 1.7.0 with the chord dictionary module. With it, you can disable the chords you don't find meaningful (i personally removed 5, m#5, maddb6) , and it should address any opinionated choice i made. You can also choose your preferred notation for any chord if it is int he chord dictionary of course. I rollbacked the "maj" -> "" notation in the dictionary, and added this as the default preferred alias for maj chords, because it can have impact on the code (empty strings in javascript is something that is prone to errors).

I invite you to make any feedback on missing aliases, or mistakes. I particularly have many doubts about notations that sometimes are "addb9" (implying there is no 7), and sometimes simply noted "b9". I'm pretty sure there are mistakes in the dictonary, and maybe missing solutions too. I took some inspiration from the https://www.scales-chords.com/ website, which has a very (too much ?) exhaustive database. I also would like to improve the dictionary to have notation with parenthesis, but i don't know exactly when this is relevant.

Anyway, hope you enjoy this new update.

gotthehot commented 9 months ago

@ArTiSTiX Thank you for your efforts! Seems midi-jar 1.7.0 became most comprehensive and flexible offline chords guide I saw ever. Database is well structured and personally I'm terrified with number of chords I never use and never seen in scores :)

I've disabled m#5 too. Also I've made default display maj7, maj9, maj11 and maj13 instead of M7 etc. because of common pronouncing them as [meɪdʒ]. From other hand [æm] usually means "minor", so pronouncing i.e. CM7 as C [æm] Seven leads to confusion of Cmaj7 and Cm7 and misunderstanding in speech. May be it's the reason why known chords detectors (i.e. Pianoteq built-in) are using "maj" notation.

BTW to continue on topic of confusions. Upper part of this screenshot is Pianoteq's chord detection:

fmaj7c

when playing mentioned above famous FMTTM standard using fingers shuffling from Am7/E to Am7 octave down:

Am7/E Dm7 G7/D Cmaj7 Fmaj7/C Bm7b5 E7/B Am7

And yes, that is Fmaj7 (VI) and definitely not C6/11. Because, when it comes to practice, chords definitions are not about some algorithmic rules but more about rules of harmony. Also tight inversions of 7, m7 and maj7 chords are widely used when playing "block chords" - that's another reason to prioritize them over (may be) algorithmicaly right exotic chords like C6/11 in the example above.

Also, as mentioned at topic start message, Am/C is minor triad sounding stable solid minor and should not be displayed as C6 - chord of dissonant and unstable nature also with V omission in case of Am/C. Just checked it with Pianoteq (upper part of screenshot) and it seems to be agree with me:

am-with-pianoteq

That's for now most annoying midi-jar feature because still can't fix it even with current very flexible settings. I need 6th chords and chords with omissions that's why can't simply disable them to get Am/C displayed as Am/C.

ArTiSTiX commented 9 months ago

OK, i'll pause a bit development for MIDI Jar this month, and try to think about how to tackle this correctly. I think my complexity approach i had for the chord quiz is kinda the right direction, but the complexity score is not precise enough to be used for detection, so i might have to find a more granular approach specifically designed to calculate this detection score.

Thanks for the examples, i totally agree with this.

NOTE: for the notation part, i also agree that maj instead of M feels more natural, but i don't see how to address this without this "preferred" feature of choosing aliases chord per chord.

ArTiSTiX commented 9 months ago

uhh, concerning the C6/11 (which gives me a Cmaj6add11 on my side) prioritised over Fmaj7/C, looks like a bug again to me... Might have a look soon because this is unexpected. Brain not working as expected on this.

gotthehot commented 9 months ago

@ArTiSTiX prioritizing of C6/11 over Fmaj7/C not seems a bug from the point of algorithm because C6/11 is at it's root (C) and Fmaj7 is inversion. From other hand Fmaj7/C is perfect example of ugly seventh inversion with ear-scratching obvious minor second dissonance when playing in block (tight) mode. But from musician's point of view Fmaj7 is much more common chord in progressions and thus IMHO should be prioritized in this (and similar) case.

evgeniyp commented 8 months ago

BTW, v1.7.0 still has an issue with recognizing the first inversion of some chords:

image
gotthehot commented 8 months ago

@evgeniyp yes, that"s why I use new 1.7.0 feature to disable #5 chords.