Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworking chord detection to be order independent. #214

Closed
wants to merge 1 commit into from

Conversation

jhmcstanton
Copy link
Contributor

Resolves #160.

Copy link
Collaborator

@danigb danigb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot!! I fully agree that C4 D3 F3 A3 should be a simple Dm7, but not convinced when using pitch classes C D F A for mi is Dm7/C.

Also I don't fully understand the alogrithm.

In any case, really happy about this and find a good solution 👍

@@ -33,12 +37,41 @@ export function detect(source: string[]): string[] {
.map((chord) => chord.name);
}

// Assumes that chord is presorted
function findRoot(chord: string[]): string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain me why this works? 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is shamelessly borrowed from this comment, which I think explains it better than I could.

Unfortunately this will only work on chords forming major or minor triads.

function findExactMatches(notes: string[], weight: number): FoundChord[] {
const tonic = notes[0];
const tonicChroma = note(tonic).chroma;
const root = findRoot(notes);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this name change on purpose? Can you elaborate the reasoning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was changed to root since it is looking for a root of a chord and not the tonic of a scale.

expect(detect(["E", "G#", "B", "C#"])).toEqual(["E6", "C#m7/E"]);
expect(detect(["D", "F#", "A", "C"])).toEqual(["D7/C"]);
expect(detect(["D3", "F#4", "A3", "C4"])).toEqual(["D7"]);
expect(detect(["F#4", "A3", "C4", "D3"])).toEqual(["D7"]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!! 👏

});

test("(regression) detect aug", () => {
expect(detect(["C", "E", "G#"])).toEqual(["Caug", "Eaug/C", "G#aug/C"]);
expect(detect(["E", "G#", "C"])).toEqual(["Caug", "Eaug/C", "G#aug/C"]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this change. For me E G# C is is Eaug (the base note is clearly E, not C)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case since every note is in the same octave, would C not be the bass note?

My goal with this change was to allow callers to pass an unordered list of notes to be detected, but that also requires that all notes be explicitly assigned an octave.

@danigb danigb closed this Nov 15, 2022
@manniL
Copy link
Contributor

manniL commented Nov 28, 2022

@danigb I saw you closed this PR but am not sure what was missing here to get merged (except being stale). Could you kindly elaborate on that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ChordDetect is incorrectly detecting chord inversions
3 participants