X-Git-Url: https://git.cworth.org/git?p=scherzo;a=blobdiff_plain;f=scherzo-key.c;fp=scherzo-key.c;h=67d2c1e2875f7a2a4388b5726a338e38bf91ac43;hp=0000000000000000000000000000000000000000;hb=45d36bd8372f38186ceebf74b48f1a67bd67c573;hpb=b588ae80ff8009695f7ed299fd27e3f16de01e9e diff --git a/scherzo-key.c b/scherzo-key.c new file mode 100644 index 0000000..67d2c1e --- /dev/null +++ b/scherzo-key.c @@ -0,0 +1,137 @@ +/* scherzo - Music notation training + * + * key.c - Common structures and functions for keys + * + * Copyright © 2013 Carl Worth + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ . + */ + +#include + +#include "scherzo-key.h" + +#define ARRAY_SIZE(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) + +void +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), + PITCH_CLASS_LITERAL (B, FLAT), + PITCH_CLASS_LITERAL (E, FLAT), + PITCH_CLASS_LITERAL (A, FLAT), + PITCH_CLASS_LITERAL (D, FLAT), + PITCH_CLASS_LITERAL (G, FLAT), + PITCH_CLASS_LITERAL (C, FLAT) + }; + + key->pitch = PITCH_CLASS (PITCH_NAME (pitch), PITCH_ACCIDENTAL (pitch)); + + key->num_sharps = 0; + for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) + if (sharp_keys[i] == key->pitch) + key->num_sharps = i; + + key->num_flats = 0; + for (i = 0; i < ARRAY_SIZE (flat_keys); i++) + if (flat_keys[i] == key->pitch) + key->num_flats = i; +} + +bool +scherzo_key_contains_pitch (scherzo_key_t *key, pitch_t pitch) +{ + pitch_accidental_t accidental = PITCH_ACCIDENTAL (pitch); + int i; + + pitch_name_t sharps_order[] = { + PITCH_NAME_F, + PITCH_NAME_C, + PITCH_NAME_G, + PITCH_NAME_D, + PITCH_NAME_A, + PITCH_NAME_E, + PITCH_NAME_B + }; + + pitch_name_t flats_order[] = { + PITCH_NAME_B, + PITCH_NAME_E, + PITCH_NAME_A, + PITCH_NAME_D, + PITCH_NAME_G, + PITCH_NAME_C, + PITCH_NAME_F + }; + + if (accidental == PITCH_ACCIDENTAL_DOUBLE_SHARP || + accidental == PITCH_ACCIDENTAL_DOUBLE_FLAT) + { + return false; + } + + if (key->num_sharps) { + if (accidental == PITCH_ACCIDENTAL_FLAT) + return false; + for (i = 0; i < key->num_sharps; i++) { + if (sharps_order[i] == PITCH_NAME (pitch)) { + if (accidental == PITCH_ACCIDENTAL_SHARP) + return true; + else + return false; + } + } + if (accidental == PITCH_ACCIDENTAL_SHARP) + return false; + else + return true; + } + + if (key->num_flats) { + if (accidental == PITCH_ACCIDENTAL_SHARP) + return false; + for (i = 0; i < key->num_flats; i++) { + if (flats_order[i] == PITCH_NAME (pitch)) { + if (accidental == PITCH_ACCIDENTAL_FLAT) + return true; + else + return false; + } + } + if (accidental == PITCH_ACCIDENTAL_FLAT) + return false; + else + return true; + } + + if (accidental == PITCH_ACCIDENTAL_NATURAL) + return true; + else + return false; +}