From 1cfc79bb867bfa72e9982b79a65bd353bd120ee9 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 17 Sep 2013 20:41:32 -0700 Subject: [PATCH] Fix bugs in analysis for out-of-order chords When the various notes of a chord were in different octaves, scherzo was sometimes getting confused and was unable to match the chord to its known signatures. We fix this by adding a secondary sort, (first sort by absolute pitch to find bass note so to compute relative pitch, and then second sort by relative pitch). --- scherzo.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scherzo.c b/scherzo.c index 7f6d5e9..0b0a97f 100644 --- a/scherzo.c +++ b/scherzo.c @@ -407,13 +407,21 @@ typedef struct analyzed_note { } analyzed_note_t; static int -_compare_analyzed_note (const void *va, const void *vb) +_compare_analyzed_note_by_midi_pitch (const void *va, const void *vb) { const analyzed_note_t *a = va, *b = vb; return a->midi_pitch - b->midi_pitch; } +static int +_compare_analyzed_note_by_relative_pitch (const void *va, const void *vb) +{ + const analyzed_note_t *a = va, *b = vb; + + return a->relative_pitch - b->relative_pitch; +} + static int _chord_signature_matches (analyzed_note_t *notes, int num_notes, @@ -519,16 +527,23 @@ scherzo_analyze_chord (scherzo_t *scherzo) notes[i].relative_pitch = 0; } - qsort (notes, num_notes, sizeof (analyzed_note_t), _compare_analyzed_note); + /* First, sort by midi pitch to find the bass note. */ + qsort (notes, num_notes, sizeof (analyzed_note_t), + _compare_analyzed_note_by_midi_pitch); bass_pitch = notes[0].midi_pitch; + /* With the bass note identified, we can find all relative pitches. */ for (i = 0; i < num_notes; i++) { notes[i].relative_pitch = notes[i].midi_pitch - bass_pitch; while (notes[i].relative_pitch >= 12) notes[i].relative_pitch -= 12; } + /* Now, sort again by relative pitch. */ + qsort (notes, num_notes, sizeof (analyzed_note_t), + _compare_analyzed_note_by_relative_pitch); + for (i = 0; i < ARRAY_SIZE (octaves); i++) { if (_chord_signature_matches (notes, num_notes, octaves[i].pitches, 1)) chord_name = octaves[i].name; -- 2.43.0