]> git.cworth.org Git - scherzo/commitdiff
Simplify chord-signature matching by dropping duplicates first
authorCarl Worth <cworth@cworth.org>
Wed, 18 Sep 2013 18:21:34 +0000 (11:21 -0700)
committerCarl Worth <cworth@cworth.org>
Wed, 18 Sep 2013 18:21:34 +0000 (11:21 -0700)
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.

scherzo.c

index 3fcae5cfb9e3e291f367b9cac94726ad6c7f4b7a..ae95d647ff5f393769858b08455f495721afdc30 100644 (file)
--- 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 (&notes[i+1], &notes[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;