int num_notes,
modified_degree_t *degrees,
int num_degrees,
- int *inversion_ret,
+ int inversion,
score_pitch_t *root)
{
#define MAX_DEGREES 4
int relative_pitches[MAX_DEGREES];
- int inversion, max_inversions;
int i, root_index;
assert (num_degrees <= MAX_DEGREES);
if (num_notes != num_degrees)
- return 0;
+ return 0;
- max_inversions = num_degrees;
+ if (inversion >= num_degrees)
+ return 0;
/* We never spell simple intervals as inversions. */
- if (num_degrees == 2)
- max_inversions = 1;
-
- for (inversion = 0; inversion < max_inversions; inversion++) {
- for (i = 0; i < num_degrees; i++) {
- /* The num_degrees is in the addition just to ensure all
- * inputs to the modulus operator remain positive. */
- int index = (i + num_degrees - inversion) % num_degrees;
-
- /* Again, adding a 12 to keep things positive. */
- relative_pitches[index] =
- (12 +
- _modified_degree_to_half_steps (°rees[i]) -
- _modified_degree_to_half_steps (°rees[inversion])) % 12;
+ if (num_degrees == 2 && inversion > 0)
+ return 0;
+
+ for (i = 0; i < num_degrees; i++) {
+ /* The num_degrees is in the addition just to ensure all
+ * inputs to the modulus operator remain positive. */
+ int index = (i + num_degrees - inversion) % num_degrees;
+
+ /* Again, adding a 12 to keep things positive. */
+ relative_pitches[index] =
+ (12 +
+ _modified_degree_to_half_steps (°rees[i]) -
+ _modified_degree_to_half_steps (°rees[inversion])) % 12;
- }
-
- for (i = 0; i < num_notes; i++)
- if (notes[i].relative_pitch != relative_pitches[i])
- goto NEXT_INVERSION;
-
- root_index = (num_notes - inversion) % num_notes;
- *root = notes[root_index].note->pitch;
+ }
- *inversion_ret = inversion;
+ for (i = 0; i < num_notes; i++)
+ if (notes[i].relative_pitch != relative_pitches[i])
+ return 0;
- return 1;
+ root_index = (num_notes - inversion) % num_notes;
+ *root = notes[root_index].note->pitch;
- NEXT_INVERSION:
- ;
- }
-
- return 0;
+ return 1;
}
static const char *
{ {{1, 0}, {3, -1}, {5, -1}}, "°" }
};
- struct { modified_degree_t degrees[4]; const char *name; } sevenths[] = {
+ struct { modified_degree_t degrees[4]; const char *name; } tetrachords[] = {
+ /* Sixth chords */
+ { {{1, 0}, {3, 0}, {5, 0}, {6, 0}}, "6" },
+ { {{1, 0}, {3, -1}, {5, 0}, {6, 0}}, "m6" },
+ /* Seventh chords */
{ {{1, 0}, {3, 0}, {5, +1}, {7, 0}}, SUP "+M7" PUS },
{ {{1, 0}, {3, 0}, {5, +1}, {7, -1}}, SUP "+7" PUS },
{ {{1, 0}, {3, 0}, {5, 0}, {7, 0}}, "M7" },
{ {{1, 0}, {3, 0}, {5, 0}, {7, -1}}, "7" },
+ { {{1, 0}, {3, 0}, {5, -1}, {7, -1}}, SUP "7♭5" PUS },
{ {{1, 0}, {3, -1}, {5, 0}, {7, 0}}, "m" SUP "M7" PUS },
{ {{1, 0}, {3, -1}, {5, 0}, {7, -1}}, "m7" },
{ {{1, 0}, {3, -1}, {5, -1}, {7, 0}}, "°" SUP "M7" PUS },
}
}
- switch (num_notes) {
- case 1:
- for (i = 0; i < ARRAY_SIZE (octaves); i++) {
- if (_chord_signature_matches (notes, num_notes,
- octaves[i].degrees, 1,
- &inversion, &root))
- {
- chord_name = octaves[i].name;
- break;
+ for (inversion = 0; inversion < 4; inversion++) {
+ switch (num_notes) {
+ case 1:
+ for (i = 0; i < ARRAY_SIZE (octaves); i++) {
+ if (_chord_signature_matches (notes, num_notes,
+ octaves[i].degrees, 1,
+ inversion, &root))
+ {
+ chord_name = octaves[i].name;
+ goto CHORD_NAME_KNOWN;
+ }
}
- }
- break;
- case 2:
- for (i = 0; i < ARRAY_SIZE (intervals); i++) {
- if (_chord_signature_matches (notes, num_notes,
- intervals[i].degrees, 2,
- &inversion, &root))
- {
- chord_name = intervals[i].name;
- break;
+ break;
+ case 2:
+ for (i = 0; i < ARRAY_SIZE (intervals); i++) {
+ if (_chord_signature_matches (notes, num_notes,
+ intervals[i].degrees, 2,
+ inversion, &root))
+ {
+ chord_name = intervals[i].name;
+ goto CHORD_NAME_KNOWN;
+ }
}
- }
- break;
- case 3:
- for (i = 0; i < ARRAY_SIZE (triads); i++) {
- if (_chord_signature_matches (notes, num_notes,
- triads[i].degrees, 3,
- &inversion, &root))
- {
- chord_name = triads[i].name;
- break;
+ break;
+ case 3:
+ for (i = 0; i < ARRAY_SIZE (triads); i++) {
+ if (_chord_signature_matches (notes, num_notes,
+ triads[i].degrees, 3,
+ inversion, &root))
+ {
+ chord_name = triads[i].name;
+ goto CHORD_NAME_KNOWN;
+ }
}
- }
- break;
- case 4:
- for (i = 0; i < ARRAY_SIZE(sevenths); i++) {
- if (_chord_signature_matches (notes, num_notes,
- sevenths[i].degrees, 4,
- &inversion, &root))
- {
- chord_name = sevenths[i].name;
- break;
+ break;
+ case 4:
+ for (i = 0; i < ARRAY_SIZE(tetrachords); i++) {
+ if (_chord_signature_matches (notes, num_notes,
+ tetrachords[i].degrees, 4,
+ inversion, &root))
+ {
+ chord_name = tetrachords[i].name;
+ goto CHORD_NAME_KNOWN;
+ }
}
+ break;
}
- break;
}
+ CHORD_NAME_KNOWN:
if (chord_name) {
if (inversion) {