X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=pitch.h;h=4467aa86a825c239faa6842819c21d85b58fb1e6;hb=54d2b1cb13bf52df22c93e58377a00b757644b94;hp=13c29057bf5d25272d438e427d5c0f2c3ca4223d;hpb=08ba627b61792c7d6e31d71831f062f5a8162248;p=scherzo diff --git a/pitch.h b/pitch.h index 13c2905..4467aa8 100644 --- a/pitch.h +++ b/pitch.h @@ -18,8 +18,47 @@ * along with this program. If not, see http://www.gnu.org/licenses/ . */ -#define PITCH_ACCIDENTAL_MASK 0x07 -#define PITCH_ACCIDENTAL_SHIFT 0 +#include + +#ifndef PITCH_H +#define PITCH_H + +typedef uint32_t pitch_t; + +#define PITCH_ACCIDENTAL_SHIFT (0) +#define PITCH_ACCIDENTAL_MASK (0x07 << PITCH_ACCIDENTAL_SHIFT) + +#define PITCH_NAME_SHIFT (3) +#define PITCH_NAME_MASK (0x07 << PITCH_NAME_SHIFT) + +#define PITCH_OCTAVE_SHIFT (6) +#define PITCH_OCTAVE_MASK (0x07 << PITCH_OCTAVE_SHIFT) + +#define PITCH_ACCIDENTAL(pitch) \ + (((pitch) & PITCH_ACCIDENTAL_MASK) >> PITCH_ACCIDENTAL_SHIFT) +#define PITCH_NAME(pitch) \ + (((pitch) & PITCH_NAME_MASK) >> PITCH_NAME_SHIFT) +#define PITCH_OCTAVE(pitch) \ + (((pitch) & PITCH_OCTAVE_MASK) >> PITCH_OCTAVE_SHIFT) + +#define PITCH(name, accidental, octave) \ + (((octave) << PITCH_OCTAVE_SHIFT) | \ + ((name) << PITCH_NAME_SHIFT) | \ + ((accidental) << PITCH_ACCIDENTAL_SHIFT)) + +#define PITCH_LITERAL(literal_name, literal_accidental, octave) \ + PITCH(PITCH_NAME_##literal_name, \ + PITCH_ACCIDENTAL_##literal_accidental, \ + octave) + +#define PITCH_NATURAL(literal_name, octave) \ + PITCH_LITERAL(literal_name, NATURAL, octave) + +/* PITCH_CLASS is useful for comparing pitches while ignoring any octave. */ +#define PITCH_CLASS(name, accidental) PITCH(name, accidental, 0) + +#define PITCH_CLASS_LITERAL(literal_name, literal_accidental) \ + PITCH_LITERAL(literal_name, literal_accidental, 0) typedef enum pitch_accidental { @@ -30,11 +69,6 @@ typedef enum pitch_accidental PITCH_ACCIDENTAL_DOUBLE_SHARP } pitch_accidental_t; -#define PITCH_ACCIDENTAL(pitch) (((pitch) & PITCH_ACCIDENTAL_MASK) >> PITCH_ACCIDENTAL_SHIFT) - -#define PITCH_NAME_MASK 0x38 -#define PITCH_NAME_SHIFT 3 - typedef enum pitch_name { PITCH_NAME_C, @@ -46,53 +80,32 @@ typedef enum pitch_name PITCH_NAME_B, } pitch_name_t; -#define PITCH_NAME(pitch) (((pitch) & PITCH_NAME_MASK) >> PITCH_NAME_SHIFT) +/* Octave numbers are ISO octave numbers [0:8], (so Octave 4 is from + * middle C to the B above middle C). + */ + +/* Get a string representation of a pitch_t value. + * + * Note: The returned value is static to the pithc_string function and + * may be modified by future calls to pitch_string. So the caller + * should copy the value if needed. */ +const char * +pitch_string (pitch_t pitch); -#define PITCH(name, accidental) (((name) << PITCH_NAME_SHIFT) | (accidental)) +/* Return a new pitch, a number of octaves above 'pitch' + * + * Note: Maximum octave value is 8. A pitch with octave 8 will not be + * raised. + */ +pitch_t +pitch_raise_by_octaves (pitch_t pitch, int octaves); -#define PITCH_LITERAL(literal_name, literal_accidental) PITCH(PITCH_NAME_##literal_name, PITCH_ACCIDENTAL_##literal_accidental) +/* Return a new pitch, a number of octaves below 'pitch' + * + * Note: Minimum octave value is 9. A pitch with octave 8 will not be + * lowered. + */ +pitch_t +pitch_lower_by_octaves (pitch_t pitch, int octaves); -typedef enum pitch -{ - PITCH_Cff = PITCH_LITERAL (C, DOUBLE_FLAT), - PITCH_Cf = PITCH_LITERAL (C, FLAT), - PITCH_C = PITCH_LITERAL (C, NATURAL), - PITCH_Cs = PITCH_LITERAL (C, SHARP), - PITCH_Css = PITCH_LITERAL (C, DOUBLE_SHARP), - - PITCH_Dff = PITCH_LITERAL (D, DOUBLE_FLAT), - PITCH_Df = PITCH_LITERAL (D, FLAT), - PITCH_D = PITCH_LITERAL (D, NATURAL), - PITCH_Ds = PITCH_LITERAL (D, SHARP), - PITCH_Dss = PITCH_LITERAL (D, DOUBLE_SHARP), - - PITCH_Eff = PITCH_LITERAL (E, DOUBLE_FLAT), - PITCH_Ef = PITCH_LITERAL (E, FLAT), - PITCH_E = PITCH_LITERAL (E, NATURAL), - PITCH_Es = PITCH_LITERAL (E, SHARP), - PITCH_Ess = PITCH_LITERAL (E, DOUBLE_SHARP), - - PITCH_Fff = PITCH_LITERAL (F, DOUBLE_FLAT), - PITCH_Ff = PITCH_LITERAL (F, FLAT), - PITCH_F = PITCH_LITERAL (F, NATURAL), - PITCH_Fs = PITCH_LITERAL (F, SHARP), - PITCH_Fss = PITCH_LITERAL (F, DOUBLE_SHARP), - - PITCH_Gff = PITCH_LITERAL (G, DOUBLE_FLAT), - PITCH_Gf = PITCH_LITERAL (G, FLAT), - PITCH_G = PITCH_LITERAL (G, NATURAL), - PITCH_Gs = PITCH_LITERAL (G, SHARP), - PITCH_Gss = PITCH_LITERAL (G, DOUBLE_SHARP), - - PITCH_Aff = PITCH_LITERAL (A, DOUBLE_FLAT), - PITCH_Af = PITCH_LITERAL (A, FLAT), - PITCH_A = PITCH_LITERAL (A, NATURAL), - PITCH_As = PITCH_LITERAL (A, SHARP), - PITCH_Ass = PITCH_LITERAL (A, DOUBLE_SHARP), - - PITCH_Bff = PITCH_LITERAL (B, DOUBLE_FLAT), - PITCH_Bf = PITCH_LITERAL (B, FLAT), - PITCH_B = PITCH_LITERAL (B, NATURAL), - PITCH_Bs = PITCH_LITERAL (B, SHARP), - PITCH_Bss = PITCH_LITERAL (B, DOUBLE_SHARP) -} pitch_t; +#endif /* PITCH_H */