From 5d86238b8cc3c6dba95e90eed9fb444bb276f02e Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 22 Aug 2023 17:44:01 +0200 Subject: Added initial implementation of scale mode --- src/scale.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/scale.c (limited to 'src/scale.c') diff --git a/src/scale.c b/src/scale.c new file mode 100644 index 0000000..51d46fe --- /dev/null +++ b/src/scale.c @@ -0,0 +1,102 @@ +typedef enum Scales { + SCALE_CHRM, + SCALE_MAJR, + SCALE_MINR, + SCALE_PMAJ, + SCALE_PMIN, + SCALE_BLUE, + SCALE_DORI, + SCALE_PHYR, + SCALE_LYDI, + SCALE_MIXO, + SCALE_LOCR, + SCALE_PERS, + SCALE_HMIN, + SCALE_IWAT, + SCALE_INSN, + SCALE_HIRA, + SCALE_NUM, +} Scales; + +char *scale_short[] = { + "CHRM", + "MAJR", + "MINR", + "PMAJ", + "PMIN", + "BLUE", + "DORI", + "PHYR", + "LYDI", + "MIXO", + "LOCR", + "PERS", + "HMIN", + "IWAT", + "INSN", + "HIRA", +}; + +char *scale_long[] = { + "CHROMATIC", + "MAJOR", + "MINOR", + "PENTATONIC MAJOR", + "PENTATONIC MINOR", + "BLUES", + "DORIAN", + "PHYRGIAN", + "LYDIAN", + "MIXOLYDIAN", + "LOCRIAN", + "PERSIAN", + "HUNGARIAN MINOR", + "IWATO", + "IN-SEN", + "HIRAJOSHI", +}; + +typedef u8 Scale[12]; +Scale scales[] = { +// 1 b2 2 b3 3 4 b5 5 b6 6 b7 7 <- Major + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // CHRM + {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1}, // MAJR + {1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0}, // MINR + {1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0}, // PMAJ + {1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0}, // PMIN + {1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0}, // BLUE + {1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}, // DORI + {1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0}, // PHYR + {1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1}, // LYDI + {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0}, // MIXO + {1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0}, // LOCR + {1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1}, // PERS + {1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1}, // HMIN + {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0}, // IWAT + {1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0}, // INSN + {1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0}, // HIRA +}; + +int current_scale = SCALE_CHRM; +int current_scale_root = 0; + +s32 +scale_note(s32 current, s32 inc) { + if (inc > 1 || inc < -1) { + return CLAMP(current + inc, (s32)NOTE_C_2, (s32)NOTE_C_8 - 1); + } + s32 pos = current % 12; + s32 offset = 0; + for (int i = 1; i <= 12; i++) { + s32 k = (current_scale_root + pos + i * inc) % 12; + if (k < 0) { + k *= -1; + k = 12 - k; + } + offset += inc; + if (scales[current_scale][k] == 1) { + break; + } + } + return CLAMP(current + offset, (s32)NOTE_C_2, (s32)NOTE_C_8 - 1); +} -- cgit v1.2.1