mir-evaluation / mir_eval

Evaluation functions for music/audio information retrieval/signal processing algorithms.
MIT License
609 stars 114 forks source link

function to build a chord alphabet? #22

Closed bmcfee closed 10 years ago

bmcfee commented 10 years ago

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

>>> alphabet = mir_eval.chords.alphabet('minmaj')
>>> print alphabet
    ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

I'm not married to that exact ordering, but we should try and keep things consistent.

dpwe commented 10 years ago

I bet someone with music theory could come up with the right ordering. But I think it should be something like manhattan distance to the relevant major triad. I'm just not sure how to compare chords with more than 3 notes - maybe just extend the root major triad to further octaves?

Oh, but that doesn't work because it makes, say, an augmented triad "tie" with a minor triad, which is absurd.

Instead, the score of a chord could be the per-note average of the note's value on the Krumhansl/Kessler Major Key Profile (fig 2 in http://psycnet.apa.org/journals/rev/89/4/334.pdf ). Then there are no ties. Interestingly, however, it scores unisons and 5ths (diads) above major triads.

DAn.

On Wed, Feb 19, 2014 at 9:06 PM, Brian McFee notifications@github.com wrote:

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

alphabet = mir_eval.chords.alphabet('minmaj') print alphabet ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

no-chord symbol always comes first maj/min in alphabetical order then remaining subsets (triads, 7ths, etc) each in alphabetical order

I'm not married to that exact ordering, but we should try and keep things consistent.

— Reply to this email directly or view it on GitHub.

mattmcvicar commented 10 years ago

The ability to spit out the chord alphabet sounds necessary, but I'm dubious about the ordering.

We could just fix the ordering in some sensible way for the alphabets we seed with, but what happens when people want to add a new alphabet? We should be prepared for this. The alphabets are likely to be supersets of each other:

{N,min,maj} < {N,min,maj} < {N, min, maj, sus, dim, aug} < etc

so we could ensure that the 'new' chords are appended to the previous alphabet. Beyond that, I'm not sure how to do it.

On Thu, Feb 20, 2014 at 11:33 PM, Dan Ellis notifications@github.comwrote:

I bet someone with music theory could come up with the right ordering. But I think it should be something like manhattan distance to the relevant major triad. I'm just not sure how to compare chords with more than 3 notes - maybe just extend the root major triad to further octaves?

Oh, but that doesn't work because it makes, say, an augmented triad "tie" with a minor triad, which is absurd.

Instead, the score of a chord could be the per-note average of the note's value on the Krumhansl/Kessler Major Key Profile (fig 2 in http://psycnet.apa.org/journals/rev/89/4/334.pdf ). Then there are no ties. Interestingly, however, it scores unisons and 5ths (diads) above major triads.

DAn.

On Wed, Feb 19, 2014 at 9:06 PM, Brian McFee notifications@github.com wrote:

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

alphabet = mir_eval.chords.alphabet('minmaj') print alphabet ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

no-chord symbol always comes first maj/min in alphabetical order then remaining subsets (triads, 7ths, etc) each in alphabetical order

I'm not married to that exact ordering, but we should try and keep things consistent.

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35626510 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

dpwe commented 10 years ago

We could just fix the ordering in some sensible way for the alphabets we seed with, but what happens when people want to add a new alphabet? We should be prepared for this. The alphabets are likely to be supersets of each other:

{N,min,maj} < {N,min,maj} < {N, min, maj, sus, dim, aug} < etc

so we could ensure that the 'new' chords are appended to the previous alphabet. Beyond that, I'm not sure how to do it.

But that's why I proposed an algorithmic ordering, since we can't predict which chords will be in the dictionaries. In general, we can't guarantee "superset" numbering (since it's path dependent), but with algorithmic ordering we can at least achieve consistent ordering for subsets that follow our notion of "order".

DAn.

On Thu, Feb 20, 2014 at 11:33 PM, Dan Ellis notifications@github.comwrote:

I bet someone with music theory could come up with the right ordering. But I think it should be something like manhattan distance to the relevant major triad. I'm just not sure how to compare chords with more than 3 notes - maybe just extend the root major triad to further octaves?

Oh, but that doesn't work because it makes, say, an augmented triad "tie" with a minor triad, which is absurd.

Instead, the score of a chord could be the per-note average of the note's value on the Krumhansl/Kessler Major Key Profile (fig 2 in http://psycnet.apa.org/journals/rev/89/4/334.pdf ). Then there are no ties. Interestingly, however, it scores unisons and 5ths (diads) above major triads.

DAn.

On Wed, Feb 19, 2014 at 9:06 PM, Brian McFee notifications@github.com wrote:

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

alphabet = mir_eval.chords.alphabet('minmaj') print alphabet ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

no-chord symbol always comes first maj/min in alphabetical order then remaining subsets (triads, 7ths, etc) each in alphabetical order

I'm not married to that exact ordering, but we should try and keep things consistent.

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35626510 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

— Reply to this email directly or view it on GitHub.

mattmcvicar commented 10 years ago

ok, sure sounds good. But then our algorithmic ordering needs to know about every possible chord type. With chords contained within one octave this is upper bounded by 2^12 (many fewer in practice of course). Things get more complex if we consider chords above the octave or with inversions.

So our algorithmic ordering will have to be quite advanced, I think. Just a word of caution I guess.

On Sat, Feb 22, 2014 at 9:34 AM, Dan Ellis notifications@github.com wrote:

We could just fix the ordering in some sensible way for the alphabets we seed with, but what happens when people want to add a new alphabet? We should be prepared for this. The alphabets are likely to be supersets of each other:

{N,min,maj} < {N,min,maj} < {N, min, maj, sus, dim, aug} < etc

so we could ensure that the 'new' chords are appended to the previous alphabet. Beyond that, I'm not sure how to do it.

But that's why I proposed an algorithmic ordering, since we can't predict which chords will be in the dictionaries. In general, we can't guarantee "superset" numbering (since it's path dependent), but with algorithmic ordering we can at least achieve consistent ordering for subsets that follow our notion of "order".

DAn.

On Thu, Feb 20, 2014 at 11:33 PM, Dan Ellis notifications@github.comwrote:

I bet someone with music theory could come up with the right ordering. But I think it should be something like manhattan distance to the relevant major triad. I'm just not sure how to compare chords with more than 3 notes - maybe just extend the root major triad to further octaves?

Oh, but that doesn't work because it makes, say, an augmented triad "tie" with a minor triad, which is absurd.

Instead, the score of a chord could be the per-note average of the note's value on the Krumhansl/Kessler Major Key Profile (fig 2 in http://psycnet.apa.org/journals/rev/89/4/334.pdf ). Then there are no ties. Interestingly, however, it scores unisons and 5ths (diads) above major triads.

DAn.

On Wed, Feb 19, 2014 at 9:06 PM, Brian McFee notifications@github.com

wrote:

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

alphabet = mir_eval.chords.alphabet('minmaj') print alphabet ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

no-chord symbol always comes first maj/min in alphabetical order then remaining subsets (triads, 7ths, etc) each in alphabetical order

I'm not married to that exact ordering, but we should try and keep things consistent.

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35626510> .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional)

blog/website: www.mattmcvicar.com

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35788336 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

dpwe commented 10 years ago

Yes, we'll need to convert symbols into actual notes. But can't we borrow Harte's function for this?

DAn.

On Friday, February 21, 2014, Matt McVicar notifications@github.com wrote:

ok, sure sounds good. But then our algorithmic ordering needs to know about every possible chord type. With chords contained within one octave this is upper bounded by 2^12 (many fewer in practice of course). Things get more complex if we consider chords above the octave or with inversions.

So our algorithmic ordering will have to be quite advanced, I think. Just a word of caution I guess.

On Sat, Feb 22, 2014 at 9:34 AM, Dan Ellis notifications@github.com<javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

We could just fix the ordering in some sensible way for the alphabets we seed with, but what happens when people want to add a new alphabet? We should be prepared for this. The alphabets are likely to be supersets of each other:

{N,min,maj} < {N,min,maj} < {N, min, maj, sus, dim, aug} < etc

so we could ensure that the 'new' chords are appended to the previous alphabet. Beyond that, I'm not sure how to do it.

But that's why I proposed an algorithmic ordering, since we can't predict which chords will be in the dictionaries. In general, we can't guarantee "superset" numbering (since it's path dependent), but with algorithmic ordering we can at least achieve consistent ordering for subsets that follow our notion of "order".

DAn.

On Thu, Feb 20, 2014 at 11:33 PM, Dan Ellis notifications@github.com<javascript:_e(%7B%7D,'cvml','notifications@github.com'); wrote:

I bet someone with music theory could come up with the right ordering. But I think it should be something like manhattan distance to the relevant major triad. I'm just not sure how to compare chords with more than 3 notes - maybe just extend the root major triad to further octaves?

Oh, but that doesn't work because it makes, say, an augmented triad "tie" with a minor triad, which is absurd.

Instead, the score of a chord could be the per-note average of the note's value on the Krumhansl/Kessler Major Key Profile (fig 2 in http://psycnet.apa.org/journals/rev/89/4/334.pdf ). Then there are no ties. Interestingly, however, it scores unisons and 5ths (diads) above major triads.

DAn.

On Wed, Feb 19, 2014 at 9:06 PM, Brian McFee < notifications@github.comjavascript:_e(%7B%7D,'cvml','notifications@github.com');

wrote:

The chord module does reduction to a specific alphabet, but there doesn't seem to be a way to ask for a list of the chords in the chosen alphabet.

I'm thinking the following:

alphabet = mir_eval.chords.alphabet('minmaj') print alphabet ['N', 'A:maj', 'A:min', 'A#:maj', 'A#:min', ... ]

and so on for all of the other supported alphabets. That way, it will be simple to construct and label the states of a chord model.

Ideally, the ordering of the chord alphabet should be well-defined, eg:

no-chord symbol always comes first maj/min in alphabetical order then remaining subsets (triads, 7ths, etc) each in alphabetical order

I'm not married to that exact ordering, but we should try and keep things consistent.

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35626510> .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.comjavascript:_e(%7B%7D,'cvml','mattjamesmcvicar@gmail.com');(personal), matt.mcvicar@aist.go.jpjavascript:_e(%7B%7D,'cvml','matt.mcvicar@aist.go.jp'); (professional)

blog/website: www.mattmcvicar.com

Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35788336> .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.comjavascript:_e(%7B%7D,'cvml','mattjamesmcvicar@gmail.com');(personal), matt.mcvicar@aist.go.jpjavascript:_e(%7B%7D,'cvml','matt.mcvicar@aist.go.jp'); (professional) blog/website: www.mattmcvicar.com

— Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35788584 .

craffel commented 10 years ago

I've said this before, but the only way I can think of this without going insane is to use 12-bit binary vectors instead of chord labels. The sorting is implicit then (just cast to int) even if it doesn't make musicological sense. You also throw away which note is the root, but I feel like that is implicit in the chroma-wrapping assumption. The only way to deal with the root/inversion/chroma-wrapping problem (like I actually know what those words mean) would be, I think, to use a 36-dimensional vector.

craffel commented 10 years ago

I'm getting a little off-topic, but Avi Fox-Rosen, a monthly music hackathon attendee, just shared this nice example with me of the chroma-wrapping problem. If you play, for example, a C4, D4, G4, and then play either a D3, C4, G4 or a G3, C4, D4, these would all be equivalent in a 12-bit encoding but they have different names (which I don't know) and definitely sound perceptually like different chords. So I think you have to go to at least a 24 dimensional, if not 36 or even 128 dimensional (transcription) representation. I'm sure you all have thought of this before but yeah.

I started my last comment with "the only way I can think of this without going insane", and unfortunately I have still gone insane thinking about this.

dpwe commented 10 years ago

I'm not as familiar with the prior work as I would wish, but the 'canonical' description of a chord that makes sense to me is as a sequence of interval as semitone counts. So a major triad is (4,3), a minor triad is (3,4), a dominant 7th is ( 3,4,3).

It has no octave equivalence, but that's what we want. Triads and quads are different lengths, but there's not going to be an easy solution for that.

DAn.

On Saturday, February 22, 2014, craffel notifications@github.com wrote:

I'm getting a little off-topic, but Avi Fox-Rosen, a monthly music hackathon attendee, just shared this nice example with me of the chroma-wrapping problem. If you play, for example, a C4, D4, G4, and then play either a D3, C4, G4 or a G3, C4, D4, these would all be equivalent in a 12-bit encoding but they have different names (which I don't know) and definitely sound perceptually like different chords. So I think you have to go to at least a 24 dimensional, if not 36 or even 128 dimensional (transcription) representation. I'm sure you all have thought of this before but yeah.

I started my last comment with "the only way I can think of this without going insane", and unfortunately I have still gone insane thinking about this.

— Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35810986 .

mattmcvicar commented 10 years ago

Indeed, many chords share the same pitch classes but are different chords, depending on the note ordering and musical context.

Colin, the example you gave of (C,D,G) / (G,C,D) is Csus2 / Gsus4. A more troublesome example is (C,E,G,A) / (A,C,E,G) or Cmaj6 / Amin7, as both of these are common chords. In terms of syntax, I dealt with this in my thesis by extracting the 'bass note' for each chord (C and A in my example). So you don't actually need 2 * 12 dimensions, just 12 + 1. In modelling, I use a bass node in my DBN (as per previous work) to distinguish them.

Dan's suggestion would unfortunately also require this distinction.

On Sun, Feb 23, 2014 at 5:49 AM, Dan Ellis notifications@github.com wrote:

I'm not as familiar with the prior work as I would wish, but the 'canonical' description of a chord that makes sense to me is as a sequence of interval as semitone counts. So a major triad is (4,3), a minor triad is (3,4), a dominant 7th is ( 3,4,3).

It has no octave equivalence, but that's what we want. Triads and quads are different lengths, but there's not going to be an easy solution for that.

DAn.

On Saturday, February 22, 2014, craffel notifications@github.com wrote:

I'm getting a little off-topic, but Avi Fox-Rosen, a monthly music hackathon attendee, just shared this nice example with me of the chroma-wrapping problem. If you play, for example, a C4, D4, G4, and then play either a D3, C4, G4 or a G3, C4, D4, these would all be equivalent in a 12-bit encoding but they have different names (which I don't know) and definitely sound perceptually like different chords. So I think you have to go to at least a 24 dimensional, if not 36 or even 128 dimensional (transcription) representation. I'm sure you all have thought of this before but yeah.

I started my last comment with "the only way I can think of this without going insane", and unfortunately I have still gone insane thinking about this.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35810986> .

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35814211 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

mattmcvicar commented 10 years ago

Perhaps I should offer a solution instead of just shooting down everyone else's ideas?

I think I mentioned at some point that the representation I would opt for would be a 12-dimensional binary vector representing pitch class membership, and an additional 13th bin which gives the bass pitch class. This won't be able to handle chords above the octave, but then again no-one even tries to recognise these at the moment. If needed it could be 24 + 1 to handle this.

Evaluation of two chord symbols would be hamming distance, or f-measure, or some perceptual weighting on this (root note is most important, etc). Plus some 'bonus' for getting the order of the notes right (ie the 13th bin).

On Sun, Feb 23, 2014 at 9:07 AM, Matt McVicar mattjamesmcvicar@gmail.comwrote:

Indeed, many chords share the same pitch classes but are different chords, depending on the note ordering and musical context.

Colin, the example you gave of (C,D,G) / (G,C,D) is Csus2 / Gsus4. A more troublesome example is (C,E,G,A) / (A,C,E,G) or Cmaj6 / Amin7, as both of these are common chords. In terms of syntax, I dealt with this in my thesis by extracting the 'bass note' for each chord (C and A in my example). So you don't actually need 2 * 12 dimensions, just 12 + 1. In modelling, I use a bass node in my DBN (as per previous work) to distinguish them.

Dan's suggestion would unfortunately also require this distinction.

On Sun, Feb 23, 2014 at 5:49 AM, Dan Ellis notifications@github.comwrote:

I'm not as familiar with the prior work as I would wish, but the 'canonical' description of a chord that makes sense to me is as a sequence of interval as semitone counts. So a major triad is (4,3), a minor triad is (3,4), a dominant 7th is ( 3,4,3).

It has no octave equivalence, but that's what we want. Triads and quads are different lengths, but there's not going to be an easy solution for that.

DAn.

On Saturday, February 22, 2014, craffel notifications@github.com wrote:

I'm getting a little off-topic, but Avi Fox-Rosen, a monthly music hackathon attendee, just shared this nice example with me of the chroma-wrapping problem. If you play, for example, a C4, D4, G4, and then play either a D3, C4, G4 or a G3, C4, D4, these would all be equivalent in a 12-bit encoding but they have different names (which I don't know) and definitely sound perceptually like different chords. So I think you have to go to at least a 24 dimensional, if not 36 or even 128 dimensional (transcription) representation. I'm sure you all have thought of this before but yeah.

I started my last comment with "the only way I can think of this without going insane", and unfortunately I have still gone insane thinking about this.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35810986> .

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35814211 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

dpwe commented 10 years ago

Dan's suggestion would unfortunately also require this distinction.

Not the interval version. Maybe I'm being piano-centric, but maj6 quad is (4,3,2) and a min7 is (3,4,3).

DAn.

On Sun, Feb 23, 2014 at 5:49 AM, Dan Ellis notifications@github.com<javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

I'm not as familiar with the prior work as I would wish, but the 'canonical' description of a chord that makes sense to me is as a sequence of interval as semitone counts. So a major triad is (4,3), a minor triad is (3,4), a dominant 7th is ( 3,4,3).

It has no octave equivalence, but that's what we want. Triads and quads are different lengths, but there's not going to be an easy solution for that.

DAn.

On Saturday, February 22, 2014, craffel notifications@github.com<javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

I'm getting a little off-topic, but Avi Fox-Rosen, a monthly music hackathon attendee, just shared this nice example with me of the chroma-wrapping problem. If you play, for example, a C4, D4, G4, and then play either a D3, C4, G4 or a G3, C4, D4, these would all be equivalent in a 12-bit encoding but they have different names (which I don't know) and definitely sound perceptually like different chords. So I think you have to go to at least a 24 dimensional, if not 36 or even 128 dimensional (transcription) representation. I'm sure you all have thought of this before but yeah.

I started my last comment with "the only way I can think of this without going insane", and unfortunately I have still gone insane thinking about this.

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35810986> .

Reply to this email directly or view it on GitHub< https://github.com/craffel/mir_eval/issues/22#issuecomment-35814211> .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.comjavascript:_e(%7B%7D,'cvml','mattjamesmcvicar@gmail.com');(personal), matt.mcvicar@aist.go.jpjavascript:_e(%7B%7D,'cvml','matt.mcvicar@aist.go.jp'); (professional) blog/website: www.mattmcvicar.com

— Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35819502 .

craffel commented 10 years ago

So you're saying if I specify the root and any additional notes up to two octaves above the root note, I've covered every possible chord? I don't know enough about music theory to know when this isn't true. How does DAn's solution not cover this? e.g. C(3, 5, 5) would be some chord that I don't know, which covers two octaves. C(3, 5, 15) would cover three octaves!

craffel commented 10 years ago

I just discovered, thanks to E.J. Humphrey, that you can get chord names in music21.

import music21
import librosa
bass = 36
chord = [bass, bass + 3, bass + 3 + 5, bass + 3 + 5 + 15]
music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName

returns 'G#3-major-minor tetramirror'. I love it.

mattmcvicar commented 10 years ago

Chords are entirely contained within 2 octaves. I think. Actually somewhat less than this: a 13 chord is the 'largest', with example notes:

C, E, G, Bb, D, F, A

ie a C7 chord (C,E,G,Bb) and then a ninth, 11th, 13th. Notice this is every note in an F major scale! So if you go any higher, you'll just end up repeating yourself.

On Sun, Feb 23, 2014 at 9:24 AM, craffel notifications@github.com wrote:

So you're saying if I specify the root and any additional notes up to two octaves above the root note, I've covered every possible chord? I don't know enough about music theory to know when this isn't true. How does DAn's solution not cover this? e.g. C(3, 5, 5) would be some chord that I don't know, which covers two octaves. C(3, 5, 15) would cover three octaves!

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35819824 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

craffel commented 10 years ago

So it's a music theory thing that adding an octave of a note which is already in a chord doesn't change the chord name? E.g. C3, E3, G3 and E1, C3, E3, G3 have the same name, always, no matter what?

mattmcvicar commented 10 years ago

no, the first is C, the second is C/E.

On Sun, Feb 23, 2014 at 10:05 AM, craffel notifications@github.com wrote:

So it's a music theory thing that adding an octave of a note which is already in a chord doesn't change the chord name? E.g. C3, E3, G3 and E1, C3, E3, G3 have the same name, always, no matter what?

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35820528 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

mattmcvicar commented 10 years ago

root notes (chord inversions, or voicings) are important.

but (C3,E3,G3) == (C3, E3, G5) == C

On Sun, Feb 23, 2014 at 10:07 AM, Matt McVicar mattjamesmcvicar@gmail.comwrote:

no, the first is C, the second is C/E.

On Sun, Feb 23, 2014 at 10:05 AM, craffel notifications@github.comwrote:

So it's a music theory thing that adding an octave of a note which is already in a chord doesn't change the chord name? E.g. C3, E3, G3 and E1, C3, E3, G3 have the same name, always, no matter what?

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35820528 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

craffel commented 10 years ago

OK, I think I have figured out the best way to ask this question.

To construct every nameable chord, I am going to start with a bag which contains every semitone over an n_octave range (so, n_octave = 2 octaves would be 24 notes starting from C extending two octaves). I'm going to pick any number between 1 and max_notes objects from the bag, where order matters.

In order to cover every possible nameable chord, what is n_octave and max_notes?

mattmcvicar commented 10 years ago

Not quite. order matters, but only for the first note you pick (assuming you pick the lowest not first).

On Sun, Feb 23, 2014 at 10:18 AM, craffel notifications@github.com wrote:

OK, I think I have figured out the best way to ask this question.

To construct every nameable chord, I am going to start with a bag which contains every semitone over an n_octave range (so, n_octave = 2 octaves would be 24 notes starting from C extending two octaves). I'm going to pick any number between 1 and max_notes objects from the bag, where order matters.

In order to cover every possible nameable chord, what is n_octave and max_notes?

Reply to this email directly or view it on GitHubhttps://github.com/craffel/mir_eval/issues/22#issuecomment-35820743 .

Matt McVicar Postdoctoral Researcher, National Institute of Advanced Industrial Science and Technology mattjamesmcvicar@gmail.com (personal), matt.mcvicar@aist.go.jp(professional) blog/website: www.mattmcvicar.com

craffel commented 10 years ago

OK, assume I always pick the lowest note first, after which point order doesn't matter. What is n_octave and max_notes?

craffel commented 10 years ago

Wait what's up with this

In [21]: chord = [36, 40, 43]

In [22]: music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName
'C3-major triad'

In [23]: chord = [28, 36, 43]

In [24]: music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName
'C3-major triad'
dpwe commented 10 years ago

I don't think it's entirely black-and-white. There's definitely something different about the two chords, which Matt denotes by recognizing that the lowest note is a G in the second. But it's also just the second inversion of a C major triad. Anyway, apparently music21 doesn't feel the need to specify the bass root or the inversion. It's not like there's a canonical set of right answers, this is music, not computer science. Different people will provide different amounts of detail.

What does music21 call [28, 48, 52, 55], a plain non-inverted Cmaj triad with a G in the bass?

DAn.

On Sat, Feb 22, 2014 at 8:35 PM, craffel notifications@github.com wrote:

Wait what's up with this

In [21]: chord = [36, 40, 43]

In [22]: music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName 'C3-major triad'

In [23]: chord = [28, 36, 43]

In [24]: music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName 'C3-major triad'

— Reply to this email directly or view it on GitHub.

craffel commented 10 years ago
In [2]: import music21; import librosa

In [3]: chord = [28, 48, 52, 55]

In [4]: music21.chord.Chord([librosa.midi_to_note(note) for note in chord]).pitchedCommonName
'C4-major triad'
craffel commented 10 years ago

So, this exists: https://github.com/cuthbertLab/music21/blob/master/music21/chordTables.py

ejhumphrey commented 10 years ago

I think the functionality I've added to chord.py addresses this enough to close this issue...?

craffel commented 10 years ago

I'm not sure if it does but we aren't going to explicitly add this functionality to mir_eval.