Working with ChordRecognizer

Hey,

I’m trying to make use of ChordRecognizer / FindChordName. I have some samples that contain full orchestra chords (major, minor, diminished and dom7). I’d like to detect if the currently played chord is a major or minor chord (or none of them).

I’ve seen that the algorithm seems to always consider the lowest note to be the root note so the recognition only works if the chords are played in root position. In real life that’s not very helpful for me because I use every voicing in all inversions. So I first tried to extend the ChordRecognizer with RemoveChordInterval and AddChordInterval but this can’t use the root note issue.

My next idea was to extract the root note from the ChordName string (result of FindChordName) and extract the first character of the string. Here I don’t know if this is already possible in GPScript because I couldn’t find a function like copy (Pascal) or substr(ing) (JavaScript) that can extract a part of the string. (And accessing a string like an array and writing ChordName[0] or ChordName[1] doesn’t work as well - I suppose that David doesn’t like this approach ;-)) So I was not able to extract the first character or check if the second character is a “#”.

If I could manage that, my approach were to figure out if the found chord type is a “Min 6th”, then take the root note, convert it into an integer and subtract 4 to get my “real” root note. And the same thing for “Major 2nd” and -5. By the way: Recognizing “C F A” results in “C major 2nd” which in fact has to be “F major 2nd”.

I’ve written some different chord detections in JavaScript which work pretty well in my own projects ( http://player.leadsheeteditor.com/Chords ) and also detect very advanced chords with many tensions, but in this case I just need to find out if the played chord is a major or a minor chord and then get the right root note to send the correct note to KONTAKT.

Thanks for any suggestions or help!

Lukas

That ChordRecognizer was something I threw in to do some testing and it’s certainly not complete. I’m open to suggestions to improving the algorithms. It’s never been clear to me how to deal with root note though…for example, if you play C E A, is that a C6th chord or an inverted Am? So I just used the bottom and assumed that was the root. Again suggestions for improvement are welcome.

Also, I can easily add more string functions if needed — strings were just never really high on the list because I didn’t really expect people to do string processing in what’s supposed to be a real-time environment. Give me a list of what string functions you would like.

Thanks for the answer David.

>> for example, if you play C E A, is that a C6th chord or an inverted Am?
Yes. Some people call it C6 if the fifths is included (C E G A), the first inversion of Am7 (A C E G). But I think more basic chord types should always be prefered. So a minor triad is more basic than a major chord with some extensions (C6, Cmaj7, C7, Cadd9, Csus4 etc.)

It’s the same for Csus2 and Gsus4… or Bm7b5 and Dm6: Same notes but different root note.

For further improvements I could imagine one more bool parameter for FindChordName that decides if the lowest note should be considered to be the root note or if it should return a chord symbol with inversions (Am/C) (in my cases I would always use the second option). And if some don’t want to see the bass note (“Am” instead of “Am/C”), they can use StringContains(ChordName, “/”) and StringBefore :slight_smile:

String functions:

  • Copy/Substring(source : String, index : Integer, count : Integer)
  • LastIndexOfSubstring (like IndexOfSubstring, but returns the last occurance)
  • StringBefore(source : String, substring : String) -> StringBefore(“C major 7”, " ") should return “C”
  • StringAfter(source : String, substring : String)
  • StringContains or similar (source : String, substring : String) -> returns if source contains substr. That would be only for convenience because we can do this with IndexOfSubstring and -1

But “G C E” returning “G major 2nd” is a bug, right? (there’s no easy chord symbol that would describe these notes from a root of G -> it would be Gsus4add13omit5 or something but this makes no sense. I would prefer if it simply returned “C/G” or “C/E” for “E G C” because that’s what would be found on a leadsheet or song book)

Yes, I can only agree with jazzundso. This would make the most sense and would be very cool. I’d like to make a script that adds the root (one or two octaves lower) to a chord, played with one hand. The root, not the lowest note. I’m also aware of the problem that it can’t always be “right”, but would be very satisfied with the logic of jazzundso “more basic chord types should always be prefered”, and the “on bass notation” C/G…

I forgot all about those chord definitions. It is possible to remove them and replace them with your own definitions but I should fix those blatantly wrong ones. Thanks for reminding me

Yes, I’d love to add my own definitions.

There are two functions, AddChordInterval and RemoveChordInterval that you can use to do this.

That whole thing probably needs some improvement, it’s very simple right now. You pass in an array of intervals, always starting at 0 (which is probably unneccessary!) Suggestions to enhance this are welcome

E.g.

RemoveChordInterval(cr, [0,4,7])   // Removes the definition of a major chord
AddChordInterval(cr, [0,4,7], "Major") // Adds it back in again

Hi,
Is there any chance of a simple example of how to use the chord recognizer please…(as I have a feeling I am over thinking it)

Ta
Barry

Nobody?

Are you not talking to us ?

This is a user forum.
The developers sure read - when they have time.

Fair enough - except I originally asked on Oct 25 and its now 3rd Nov. Yet there has been other voluminous feedback to lots of other questions asked since mine (including coding ones). I personally would have thought that when LeeHarvey answered with ‘Nobody’ 3 days ago then someone could have just said that they would respond when they had time. Its no big deal - I’ll figure it out - I just thought there had to be a simple obvious solution that I was missing.

Hi all,
This is a pretty old post and I’d like to start exploring the Chord Recognizer. Has there been any examples posted? I’ve not found it in the documentation, knowledge base nor here on the forum. Maybe I’m looking in the wrong place.

Maybe this?

In the script functions, I believe the relevant ones are under NoteManagement:
https://gigperformer.com/docs/GPScript36/content/reference/list-of-functions.html#notemanagement

Depending on what you want to do, of course, but the free pizMidi chord analyser plugin is handy;

https://code.google.com/archive/p/pizmidi/downloads

Thanks @rank13 , I’ve downloaded the latest (2012) version for OSX and unfortunately, the midiChordAnalyzer VST is missing in the library and also the documentation. Before I check out older versions, can you confirm if this plugin gives the string as output or some other form that can be processed further?

My intention is to build triads from input notes (e.g. play C4 while the C major key is selected, you get C4-E4-G4, or C4-E4-G3, etc.). An early version can be found in this post. It currently works such that while playing (single notes), it will automatically select the inversion that results in the smallest overall change in voicing (e.g. play C4 and then A4, you’ll get C major C4-E4-G4 in root position and then A minor A4-C4-E4 in second inversion, but play C4 and then D4, you’ll get C: C4-E4-G4, and then Dm: D4-F4-A4, both in root position).

The next step is to allow for 7th chords, by hitting both the root and the third (e.g. C and E, I get a C major and E minor to form a Cmaj7: C-E-G-B in some order depending on which was hit first and what the last inversion was before that). As the code works now, if I hold two notes at the same time, I’ll get two triads with two bass notes (2 octaves lower than their roots). But I want to recognize that this is a C chord (whichever weird orchestral voicing is selected) and only play the C bass note and suppress the E (because that leads to low-frequency droning, that a keyboard player would avoid).

In order to do this I need to recognize the chord’s root. Maybe later, a few other bells and whistles.

I tried the ChordRecognizer and the only output I get is “D#”, whichever notes I play. So, please if you have some experience with this function, share an example.