From: Carl Worth Date: Wed, 18 Sep 2013 18:21:34 +0000 (-0700) Subject: Simplify chord-signature matching by dropping duplicates first X-Git-Url: https://git.cworth.org/git?p=scherzo;a=commitdiff_plain;h=265293b2749e886423099c3ead8825464bcd759a Simplify chord-signature matching by dropping duplicates first Previously, all the duplicate notes were still present in the chord while trying to determine if the duplicate matched. Now, we cull out the duplicates before looking for a match, which makes the matching code much simpler. --- diff --git a/scherzo.c b/scherzo.c index 3fcae5c..ae95d64 100644 --- a/scherzo.c +++ b/scherzo.c @@ -428,25 +428,13 @@ _chord_signature_matches (analyzed_note_t *notes, int *signature_pitches, int num_signature_pitches) { - int n, s; + int i; - for (n = 0, s = 0; s < num_signature_pitches; s++) { - if (n >= num_notes) - return 0; - if (notes[n].relative_pitch != signature_pitches[s]) + if (num_notes != num_signature_pitches) return 0; - n++; - /* Skip repeated notes in chord being tested. */ - while (n < num_notes && - notes[n].relative_pitch == signature_pitches[s]) - { - n++; - } - } - /* If there are fewer notes in the signature than in the chord, - * then there is no match. */ - if (n < num_notes) + for (i = 0; i < num_notes; i++) + if (notes[i].relative_pitch != signature_pitches[i]) return 0; return 1; @@ -458,7 +446,7 @@ scherzo_analyze_chord (scherzo_t *scherzo) void *local = talloc_new (NULL); analyzed_note_t *notes; note_group_t *note_group; - unsigned i, num_notes; + unsigned i, j, num_notes; int bass_pitch; const char *chord_name = NULL; @@ -544,6 +532,30 @@ scherzo_analyze_chord (scherzo_t *scherzo) qsort (notes, num_notes, sizeof (analyzed_note_t), _compare_analyzed_note_by_relative_pitch); + /* Finally, eliminate all duplicate notes. */ + for (i = 0; i < num_notes - 1; i++) { + if (notes[i+1].relative_pitch == notes[i].relative_pitch) { + j = i+1; + while (j < num_notes && + notes[j].relative_pitch == notes[i].relative_pitch) + { + j++; + } + /* The loop incremented j one past the last + * duplicate. Decrement so that it points to the + * last duplicate (and is guaranteed to not exceed + * the array bounds).*/ + j--; + + if (j < num_notes - 1) { + memmove (¬es[i+1], ¬es[j+1], + (num_notes - j) * sizeof (analyzed_note_t)); + } + + num_notes -= (j - i); + } + } + for (i = 0; i < ARRAY_SIZE (octaves); i++) { if (_chord_signature_matches (notes, num_notes, octaves[i].pitches, 1)) chord_name = octaves[i].name;