From: Carl Worth Date: Tue, 1 Oct 2013 18:14:41 +0000 (-0700) Subject: Automatically change key whenever user plays a major scale. X-Git-Url: https://git.cworth.org/git?p=scherzo;a=commitdiff_plain;h=e61e2b33d79fd2c55521ef46432ef3c40f3efc5b Automatically change key whenever user plays a major scale. This is a very convenient way to access this functionality directly from the piano keyboard, without having to use the computer keyboard at all. --- diff --git a/scherzo.c b/scherzo.c index 95bab27..6657959 100644 --- a/scherzo.c +++ b/scherzo.c @@ -971,11 +971,52 @@ scherzo_update_notes_and_chord (scherzo_t *scherzo) talloc_free (local); } +static void +scherzo_set_key (scherzo_t *scherzo, pitch_t pitch) +{ + scherzo_key_init (&scherzo->key, pitch); + score_set_key (scherzo->score, pitch); +} + +static bool +pitches_are_diatonic_scale (pitch_t *pitches, int num_pitches) +{ + int diatonic_half_steps[7] = { + 0, 2, 4, 5, 7, 9, 11 + }; + int half_steps; + pitch_t root; + int i; + + if (num_pitches < 7) + return 0; + + root = pitches[0]; + + for (i = 0; i < 7; i++) { + half_steps = pitch_from_root_in_half_steps (pitches[i], root); + if (half_steps != diatonic_half_steps[i]) + return false; + } + + return true; +} + static void scherzo_press_note (scherzo_t *scherzo, pitch_t pitch) { int i; +#define NUM_RECENT_PITCHES 7 + static pitch_t recent_pitches[NUM_RECENT_PITCHES]; + + memmove (recent_pitches, recent_pitches + 1, + (NUM_RECENT_PITCHES - 1) * sizeof (pitch_t)); + recent_pitches[NUM_RECENT_PITCHES - 1] = pitch; + + if (pitches_are_diatonic_scale (recent_pitches, NUM_RECENT_PITCHES)) + scherzo_set_key (scherzo, recent_pitches[0]); + /* Do nothing if this note is already pressed. */ for (i = 0; i < scherzo->notes_pressed.num_pitches; i++) if (scherzo->notes_pressed.pitches[i] == pitch) @@ -1246,8 +1287,7 @@ main (int argc, char *argv[]) scherzo.pedal_pressed = 0; /* Default to key of C Major, naturally. */ - scherzo_key_init (&scherzo.key, PITCH_CLASS_LITERAL (C, NATURAL)); - score_set_key (scherzo.score, scherzo.key.pitch); + scherzo_set_key (&scherzo, PITCH_CLASS_LITERAL (C, NATURAL)); mnemon_init (&scherzo.mnemon); /* XXX: Should create a default file if one cannot be loaded. */