X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=scherzo.c;h=a1ed6e3794ff09a182c55f3c355bae8826497ea5;hb=39a9e8b1d8548408fcdfe63922b93b4776237944;hp=098008930e4d4d77b4dd21ec82ad40ca52d19554;hpb=fc6b1da08cd8552050d2669363a85e405f19736d;p=scherzo diff --git a/scherzo.c b/scherzo.c index 0980089..a1ed6e3 100644 --- a/scherzo.c +++ b/scherzo.c @@ -489,55 +489,46 @@ _chord_signature_matches (analyzed_note_t *notes, 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 * @@ -670,22 +661,39 @@ scherzo_analyze_chord (scherzo_t *scherzo) #define PUS "" struct { modified_degree_t degrees[3]; const char *name; } triads[] = { + { {{1, 0}, {3, +1}, {5, 0}}, "sus" }, { {{1, 0}, {3, 0}, {5, +1}}, SUP "+" PUS }, { {{1, 0}, {3, 0}, {5, 0}}, "" }, { {{1, 0}, {3, -1}, {5, 0}}, "m" }, - { {{1, 0}, {3, -1}, {5, -1}}, "°" } + { {{1, 0}, {3, -1}, {5, -1}}, "°" }, + { {{1, 0}, {2, 0}, {5, 0}}, "msus2" } }; - 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, +1}, {5, 0}, {6, 0}}, "sus" SUP "6" PUS }, + { {{1, 0}, {3, 0}, {5, 0}, {6, 0}}, "6" }, + { {{1, 0}, {3, -1}, {5, 0}, {6, 0}}, "m6" }, + { {{1, 0}, {2, 0}, {5, 0}, {6, 0}}, "msus2" SUP "6" PUS }, + /* Seventh chords */ + { {{1, 0}, {3, +1}, {5, 0}, {7, 0}}, "sus" SUP "M7" PUS }, + { {{1, 0}, {3, +1}, {5, 0}, {7, -1}}, "sus" SUP "7" PUS }, + { {{1, 0}, {3, +1}, {5, -1}, {7, -1}}, "sus" SUP "7♭5" PUS }, { {{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 }, { {{1, 0}, {3, -1}, {5, -1}, {7, -1}}, "𝆩" SUP "7" PUS }, - { {{1, 0}, {3, -1}, {5, -1}, {7, -2}}, "°" SUP "7" PUS } + { {{1, 0}, {3, -1}, {5, -1}, {7, -2}}, "°" SUP "7" PUS }, + { {{1, 0}, {2, 0}, {5, 0}, {7, 0}}, "msus2" SUP "M7" PUS }, + { {{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 } }; if (scherzo->chord) { @@ -750,52 +758,55 @@ scherzo_analyze_chord (scherzo_t *scherzo) } } - 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) {