Chord detection inconsistency
this-fifo opened this issue · 2 comments
Hey @danigb, I am really thankful to you for this incredible project!
I would like your help understanding what is the expected notation for Chord.get
, there are many ways to write chords and it seems like some works but others don't.
Additionally, it looks like there are cases where it will behave inconsistently — as in, it works through one API but not through the other.
Here's a simple example to illustrate my point:
import * as Tonal from '@tonaljs/tonal'
console.log(Tonal.Chord.getChord('maj9', 'G', 'F#'))
console.log(Tonal.Chord.get('Gmaj9/F#'))
console.log(Tonal.Chord.getChord('maj9', 'E', 'F#'))
console.log(Tonal.Chord.get('Emaj9/F#'))
That will output the following:
{
empty: false,
name: 'G major ninth over F#',
setNum: 2705,
chroma: '101010010001',
normalized: '100011010100',
intervals: [ '7M', '9M', '8P', '10M', '12P' ],
quality: 'Major',
aliases: [ 'maj9', 'Δ9', '^9' ],
symbol: 'Gmaj9/F#',
type: 'major ninth',
root: 'F#',
rootDegree: 4,
tonic: 'G',
notes: [ 'F#', 'A', 'G', 'B', 'D' ]
}, // <— That makes sense 👍
{
empty: true,
name: '',
symbol: '',
root: '',
rootDegree: 0,
type: '',
tonic: null,
setNum: NaN,
quality: 'Unknown',
chroma: '',
normalized: '',
aliases: [],
notes: [],
intervals: []
}, // <— This is literally the symbol given from the previous output, 'Gmaj9/F#' that is. Seems like the parser may not work well here? 🤔
{
empty: true,
name: '',
symbol: '',
root: '',
rootDegree: 0,
type: '',
tonic: null,
setNum: NaN,
quality: 'Unknown',
chroma: '',
normalized: '',
aliases: [],
notes: [],
intervals: []
}, // <— This is just a different tonic 'E' instead of 'G'. For some reason it doesn't like this? 🤔
{
empty: true,
name: '',
symbol: '',
root: '',
rootDegree: 0,
type: '',
tonic: null,
setNum: NaN,
quality: 'Unknown',
chroma: '',
normalized: '',
aliases: [],
notes: [],
intervals: []
} // <— Same as previous but through the `get` API. 🤔
What's also interesting, is that if I try to detect the chord from its notes then it is able to construct it correctly.
Tonal.Chord.detect(['F#', 'B', 'D#', 'G#', 'B', 'E']) // Outputs —> [ 'Emaj9/F#' ]
I noticed the issue goes away if I import from tonal
instead of @tonaljs/tonal
— I may have imported the package dependencies incorrectly by importing the package directly as opposed to the library as a whole.
This now works
import * as Tonal from 'tonal'
console.log(Tonal.Chord.getChord('maj9', 'G', 'F#'))
console.log(Tonal.Chord.get('Gmaj9/F#'))
console.log(Tonal.Chord.getChord('maj9', 'E', 'F#'))
console.log(Tonal.Chord.get('Emaj9/F#'))
Outputs
{
empty: false,
name: 'G major ninth over F#',
setNum: 2705,
chroma: '101010010001',
normalized: '100011010100',
intervals: [ '7M', '9M', '8P', '10M', '12P' ],
quality: 'Major',
aliases: [ 'maj9', 'Δ9', '^9' ],
symbol: 'Gmaj9/F#',
tonic: 'G',
type: 'major ninth',
root: 'F#',
bass: 'F#',
rootDegree: 4,
notes: [ 'F#', 'A', 'G', 'B', 'D' ]
}
{
empty: false,
name: 'G major ninth over F#',
setNum: 2705,
chroma: '101010010001',
normalized: '100011010100',
intervals: [ '7M', '9M', '8P', '10M', '12P' ],
quality: 'Major',
aliases: [ 'maj9', 'Δ9', '^9' ],
symbol: 'Gmaj9/F#',
tonic: 'G',
type: 'major ninth',
root: 'F#',
bass: 'F#',
rootDegree: 4,
notes: [ 'F#', 'A', 'G', 'B', 'D' ]
}
{
empty: false,
name: 'E major ninth over F#',
setNum: 2705,
chroma: '101010010001',
normalized: '100011010100',
intervals: [ '-7m', '1P', '3M', '5P', '7M', '9M' ],
quality: 'Major',
aliases: [ 'maj9', 'Δ9', '^9' ],
symbol: 'Emaj9/F#',
tonic: 'E',
type: 'major ninth',
root: '',
bass: 'F#',
rootDegree: NaN,
notes: [ 'F#', 'E', 'G#', 'B', 'D#', 'F#' ]
}
{
empty: false,
name: 'E major ninth over F#',
setNum: 2705,
chroma: '101010010001',
normalized: '100011010100',
intervals: [ '-7m', '1P', '3M', '5P', '7M', '9M' ],
quality: 'Major',
aliases: [ 'maj9', 'Δ9', '^9' ],
symbol: 'Emaj9/F#',
tonic: 'E',
type: 'major ninth',
root: '',
bass: 'F#',
rootDegree: NaN,
notes: [ 'F#', 'E', 'G#', 'B', 'D#', 'F#' ]
}