From 99dc6bdb0dba7a014e41783da6e83046a2f2973e Mon Sep 17 00:00:00 2001
From: Carl Worth <cworth@cworth.org>
Date: Wed, 25 Sep 2013 19:49:35 -0700
Subject: [PATCH] Add ninth chords.

I worked from the list in this table:

http://en.wikipedia.org/wiki/Chord_notation#9ths

and included some generalizations, (including the voicings without the
5th as mentioned on the page above).

I did not yet add any "sus" variations. I'm not sure how useful those
are.
---
 scherzo.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 4 deletions(-)

diff --git a/scherzo.c b/scherzo.c
index a1ed6e3..89a9301 100644
--- a/scherzo.c
+++ b/scherzo.c
@@ -450,10 +450,15 @@ static int
 _modified_degree_to_half_steps (const modified_degree_t *degree)
 {
     int half_steps;
+    int scale_degree = degree->degree;
+
+    /* Restrict to actual degrees within a scale. */
+    if (scale_degree > 7)
+	scale_degree = (scale_degree % 8) + 1;
 
     /* Number of half steps from root to specified degree within a
      * diatonic scaled. */
-    switch (degree->degree) {
+    switch (scale_degree) {
     case 1:
 	half_steps = 0;
 	break;
@@ -492,7 +497,7 @@ _chord_signature_matches (analyzed_note_t *notes,
 			  int inversion,
 			  score_pitch_t *root)
 {
-#define MAX_DEGREES 4
+#define MAX_DEGREES 5
     int relative_pitches[MAX_DEGREES];
     int i, root_index;
 
@@ -693,7 +698,35 @@ scherzo_analyze_chord (scherzo_t *scherzo)
 	{ {{1, 0}, {2,  0}, {5,  0}, {7, -1}}, "msus2" SUP "7" PUS },
 	{ {{1, 0}, {2,  0}, {5, -1}, {7,  0}}, "msus2°" SUP "M7" PUS },
 	{ {{1, 0}, {2,  0}, {5, -1}, {7, -1}}, "msus2𝆩" SUP "7" PUS },
-	{ {{1, 0}, {2,  0}, {5, -1}, {7, -2}}, "msus2°" SUP "7" PUS }
+	{ {{1, 0}, {2,  0}, {5, -1}, {7, -2}}, "msus2°" SUP "7" PUS },
+	/* Ninth chords voiced with no 5th */
+	{ {{1, 0}, {9,  0}, {3,  0}, {7,  0}}, "M9" },
+	{ {{1, 0}, {9,  0}, {3,  0}, {7, -1}}, "9" },
+	{ {{1, 0}, {9,  0}, {3, -1}, {7,  0}}, "m" SUP "M9" PUS },
+	{ {{1, 0}, {9,  0}, {3, -1}, {7, -1}}, "m9" },
+	{ {{1, 0}, {9, -1}, {3, -1}, {7, -1}}, "m♭9" },
+    };
+
+    /* The sorting here is funny to keep the array in degree order
+     * after reducing each degree to an actual scale degree, (9 -> 2,
+     * 11 -> 4, 13 -> 6) */
+    struct { modified_degree_t degrees[5]; const char *name; } pentachords[] = {
+	{ {{1, 0}, {9,  0}, {3,  0}, {5, +1}, {7,  0}}, SUP "+M9" PUS },
+	{ {{1, 0}, {9,  0}, {3,  0}, {5, +1}, {7, -1}}, SUP "+9" PUS },
+	{ {{1, 0}, {9,  0}, {3,  0}, {5,  0}, {7,  0}}, "M9" },
+	{ {{1, 0}, {9,  0}, {3,  0}, {5,  0}, {7, -1}}, "9" },
+	{ {{1, 0}, {9,  0}, {3, -1}, {5,  0}, {7,  0}}, "m" SUP "M9" PUS },
+	{ {{1, 0}, {9,  0}, {3, -1}, {5,  0}, {7, -1}}, "m9" },
+	{ {{1, 0}, {9, -1}, {3, -1}, {5,  0}, {7, -1}}, "m♭9" },
+	{ {{1, 0}, {9,  0}, {3, -1}, {5, -1}, {7, -1}}, "𝆩" SUP "9" PUS },
+
+	/* FIXME: I don't have names for these last three after
+	 * dropping the 5th from the voicing. That suggests to me that
+	 * I'm missing names for these with a perfect 5th in the list
+	 * above. */
+	{ {{1, 0}, {9, -1}, {3, -1}, {5, -1}, {7, -1}}, "𝆩" SUP "♭9" PUS },
+	{ {{1, 0}, {9,  0}, {3, -1}, {5, -1}, {7, -2}}, "°" SUP "9" PUS },
+	{ {{1, 0}, {9, -1}, {3, -1}, {5, -1}, {7, -2}}, "°" SUP "♭9" PUS },
     };
 
     if (scherzo->chord) {
@@ -794,7 +827,7 @@ scherzo_analyze_chord (scherzo_t *scherzo)
 	    }
 	    break;
 	case 4:
-	    for (i = 0; i < ARRAY_SIZE(tetrachords); i++) {
+	    for (i = 0; i < ARRAY_SIZE (tetrachords); i++) {
 		if (_chord_signature_matches (notes, num_notes,
 					      tetrachords[i].degrees, 4,
 					      inversion, &root))
@@ -804,6 +837,17 @@ scherzo_analyze_chord (scherzo_t *scherzo)
 		}
 	    }
 	    break;
+	case 5:
+	    for (i = 0; i < ARRAY_SIZE (pentachords); i++) {
+		if (_chord_signature_matches (notes, num_notes,
+					      pentachords[i].degrees, 5,
+					      inversion, &root))
+		{
+		    chord_name = pentachords[i].name;
+		    goto CHORD_NAME_KNOWN;
+		}
+	    }
+	    break;
 	}
     }
     CHORD_NAME_KNOWN:
-- 
2.45.2