*/
#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "scherzo-key.h"
{
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),
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