From 45d36bd8372f38186ceebf74b48f1a67bd67c573 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 1 Oct 2013 09:54:44 -0700 Subject: [PATCH] Move key-signature code to new scherzo-key.c and scherzo-key.h This will facilitate sharing of this code between score.c and scherzo.c. --- Makefile | 1 + scherzo-key.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ scherzo-key.h | 44 ++++++++++++++++ score.c | 121 ++------------------------------------------ score.h | 2 +- 5 files changed, 186 insertions(+), 119 deletions(-) create mode 100644 scherzo-key.c create mode 100644 scherzo-key.h diff --git a/Makefile b/Makefile index b1a4d34..841b1a1 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ scherzo_srcs := \ mnemon/mnemon.c \ pitch.c \ scherzo.c \ + scherzo-key.c \ score.c scherzo_modules = $(scherzo_srcs:.c=.o) 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; +} diff --git a/scherzo-key.h b/scherzo-key.h new file mode 100644 index 0000000..07cdd70 --- /dev/null +++ b/scherzo-key.h @@ -0,0 +1,44 @@ +/* scherzo - Music notation training + * + * key.h - 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 + +#ifndef SCHERZO_KEY_H +#define SCHERZO_KEY_H + +#include "pitch.h" + +typedef struct scherzo_key +{ + /* Pitch class (diatonic) */ + pitch_t pitch; + + /* Number of sharps/flats in key (if any) */ + int num_sharps; + int num_flats; +} scherzo_key_t; + +void +scherzo_key_init (scherzo_key_t *key, pitch_t pitch); + +bool +scherzo_key_contains_pitch (scherzo_key_t *key, pitch_t pitch); + +#endif /* KEY_H */ diff --git a/score.c b/score.c index e93042a..690a9d2 100644 --- a/score.c +++ b/score.c @@ -64,16 +64,6 @@ typedef struct score_brace int num_staves; } score_brace_t; -typedef struct score_key -{ - /* Pitch class (diatonic) */ - pitch_t pitch; - - /* Number of sharps/flats in key (if any) */ - int num_sharps; - int num_flats; -} score_key_t; - struct score { /* Nominal height of a single staff (ledger lines may make it larger) */ @@ -89,7 +79,7 @@ struct score int width; /* Current (diatonic) key */ - score_key_t key; + scherzo_key_t key; score_brace_t **braces; int num_braces; @@ -150,114 +140,9 @@ score_set_width (score_t *score, int width) void score_set_key (score_t *score, pitch_t key) { - 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) - }; - - score->key.pitch = PITCH_CLASS (PITCH_NAME (key), PITCH_ACCIDENTAL (key)); - - score->key.num_sharps = 0; - for (i = 0; i < ARRAY_SIZE (sharp_keys); i++) - if (sharp_keys[i] == score->key.pitch) - score->key.num_sharps = i; - - score->key.num_flats = 0; - for (i = 0; i < ARRAY_SIZE (flat_keys); i++) - if (flat_keys[i] == score->key.pitch) - score->key.num_flats = i; + scherzo_key_init (&score->key, key); } -static int -score_key_contains_pitch (score_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 0; - } - - if (key->num_sharps) { - if (accidental == PITCH_ACCIDENTAL_FLAT) - return 0; - for (i = 0; i < key->num_sharps; i++) { - if (sharps_order[i] == PITCH_NAME (pitch)) { - if (accidental == PITCH_ACCIDENTAL_SHARP) - return 1; - else - return 0; - } - } - if (accidental == PITCH_ACCIDENTAL_SHARP) - return 0; - else - return 1; - } - - if (key->num_flats) { - if (accidental == PITCH_ACCIDENTAL_SHARP) - return 0; - for (i = 0; i < key->num_flats; i++) { - if (flats_order[i] == PITCH_NAME (pitch)) { - if (accidental == PITCH_ACCIDENTAL_FLAT) - return 1; - else - return 0; - } - } - if (accidental == PITCH_ACCIDENTAL_FLAT) - return 0; - else - return 1; - } - - if (accidental == PITCH_ACCIDENTAL_NATURAL) - return 1; - else - return 0; -} /* Returns in brace_width the width of the brace */ static void @@ -452,7 +337,7 @@ _draw_note (score_t *score, cairo_t *cr, } if (note->duration == 0 || - ! score_key_contains_pitch (&score->key, note->pitch)) + ! scherzo_key_contains_pitch (&score->key, note->pitch)) { note_glyph[num_glyphs].x = 0; diff --git a/score.h b/score.h index e96052a..d2de109 100644 --- a/score.h +++ b/score.h @@ -24,7 +24,7 @@ #include #include -#include "pitch.h" +#include "scherzo-key.h" typedef enum score_duration { -- 2.43.0