X-Git-Url: https://git.cworth.org/git?p=scherzo;a=blobdiff_plain;f=scherzo-key.c;fp=scherzo-key.c;h=8fea502de8044cc8b6fad289f3838c5b29260b78;hp=18cd261f6d5823e6727978b19397a415af23c592;hb=ff7437e171dab5bc3868ce65ecacf8e77c6e8df3;hpb=f492c33c1fd33c1dc0a2c892753300c7225dbd51 diff --git a/scherzo-key.c b/scherzo-key.c index 18cd261..8fea502 100644 --- a/scherzo-key.c +++ b/scherzo-key.c @@ -19,6 +19,8 @@ */ #include +#include +#include #include "scherzo-key.h" @@ -29,17 +31,6 @@ scherzo_key_init (scherzo_key_t *key, pitch_t pitch) { int i; - pitch_t sharp_keys[] = { - PITCH_CLASS_LITERAL (C, NATURAL), - PITCH_CLASS_LITERAL (G, NATURAL), - PITCH_CLASS_LITERAL (D, NATURAL), - PITCH_CLASS_LITERAL (A, NATURAL), - PITCH_CLASS_LITERAL (E, NATURAL), - PITCH_CLASS_LITERAL (B, NATURAL), - PITCH_CLASS_LITERAL (F, SHARP), - PITCH_CLASS_LITERAL (C, SHARP), - }; - pitch_t flat_keys[] = { PITCH_CLASS_LITERAL (C, NATURAL), PITCH_CLASS_LITERAL (F, NATURAL), @@ -51,17 +42,66 @@ scherzo_key_init (scherzo_key_t *key, pitch_t pitch) PITCH_CLASS_LITERAL (C, FLAT) }; - key->pitch = PITCH_CLASS (PITCH_NAME (pitch), PITCH_ACCIDENTAL (pitch)); + pitch_t sharp_keys[] = { + PITCH_CLASS_LITERAL (C, NATURAL), + PITCH_CLASS_LITERAL (G, NATURAL), + PITCH_CLASS_LITERAL (D, NATURAL), + PITCH_CLASS_LITERAL (A, NATURAL), + PITCH_CLASS_LITERAL (E, NATURAL), + PITCH_CLASS_LITERAL (B, NATURAL), + PITCH_CLASS_LITERAL (F, SHARP), + PITCH_CLASS_LITERAL (C, SHARP), + }; + + /* Remove octave from 'pitch' */ + pitch = PITCH_CLASS (pitch); key->num_sharps = 0; - for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) - if (sharp_keys[i] == key->pitch) + key->num_flats = 0; + + /* First, look for a key that exactly matches the specified pitch. */ + for (i = 0; i < ARRAY_SIZE (flat_keys); i++) { + if (flat_keys[i] == pitch) { + key->pitch = flat_keys[i]; + key->num_flats = i; + return; + } + } + + for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) { + if (sharp_keys[i] == pitch) { + key->pitch = sharp_keys[i]; key->num_sharps = i; + return; + } + } - key->num_flats = 0; - for (i = 0; i < ARRAY_SIZE (flat_keys); i++) - if (flat_keys[i] == key->pitch) + /* Second, if we haven't found a key, look for something enharmonic. */ + for (i = 0; i < ARRAY_SIZE (flat_keys); i++) { + if (pitch_enharmonic_to (flat_keys[i], pitch)) { + key->pitch = flat_keys[i]; key->num_flats = i; + return; + } + } + + for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) { + if (pitch_enharmonic_to (sharp_keys[i], pitch)) { + key->pitch = sharp_keys[i]; + key->num_sharps = i; + return; + } + } + + /* The pitch_enharmonic_to function won't catch this wraparound. */ + if (pitch == PITCH_CLASS_LITERAL (B, SHARP)) { + key->pitch = PITCH_CLASS_LITERAL (C, NATURAL); + return; + } + + fprintf (stderr, "Interal error: Failed to find a key for %s.\n", + pitch_string (pitch)); + exit (1); } bool