diff options
author | Bad Diode <bd@badd10de.dev> | 2023-08-22 17:44:01 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-08-22 17:44:01 +0200 |
commit | 5d86238b8cc3c6dba95e90eed9fb444bb276f02e (patch) | |
tree | d3b1d4c4509631a3dace28486b6887445298af1f /src/scale.c | |
parent | 9c0c004b78a12861ed03ce851d0885d68a25cb02 (diff) | |
download | stepper-5d86238b8cc3c6dba95e90eed9fb444bb276f02e.tar.gz stepper-5d86238b8cc3c6dba95e90eed9fb444bb276f02e.zip |
Added initial implementation of scale mode
Diffstat (limited to 'src/scale.c')
-rw-r--r-- | src/scale.c | 102 |
1 files changed, 102 insertions, 0 deletions
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 @@ | |||
1 | typedef enum Scales { | ||
2 | SCALE_CHRM, | ||
3 | SCALE_MAJR, | ||
4 | SCALE_MINR, | ||
5 | SCALE_PMAJ, | ||
6 | SCALE_PMIN, | ||
7 | SCALE_BLUE, | ||
8 | SCALE_DORI, | ||
9 | SCALE_PHYR, | ||
10 | SCALE_LYDI, | ||
11 | SCALE_MIXO, | ||
12 | SCALE_LOCR, | ||
13 | SCALE_PERS, | ||
14 | SCALE_HMIN, | ||
15 | SCALE_IWAT, | ||
16 | SCALE_INSN, | ||
17 | SCALE_HIRA, | ||
18 | SCALE_NUM, | ||
19 | } Scales; | ||
20 | |||
21 | char *scale_short[] = { | ||
22 | "CHRM", | ||
23 | "MAJR", | ||
24 | "MINR", | ||
25 | "PMAJ", | ||
26 | "PMIN", | ||
27 | "BLUE", | ||
28 | "DORI", | ||
29 | "PHYR", | ||
30 | "LYDI", | ||
31 | "MIXO", | ||
32 | "LOCR", | ||
33 | "PERS", | ||
34 | "HMIN", | ||
35 | "IWAT", | ||
36 | "INSN", | ||
37 | "HIRA", | ||
38 | }; | ||
39 | |||
40 | char *scale_long[] = { | ||
41 | "CHROMATIC", | ||
42 | "MAJOR", | ||
43 | "MINOR", | ||
44 | "PENTATONIC MAJOR", | ||
45 | "PENTATONIC MINOR", | ||
46 | "BLUES", | ||
47 | "DORIAN", | ||
48 | "PHYRGIAN", | ||
49 | "LYDIAN", | ||
50 | "MIXOLYDIAN", | ||
51 | "LOCRIAN", | ||
52 | "PERSIAN", | ||
53 | "HUNGARIAN MINOR", | ||
54 | "IWATO", | ||
55 | "IN-SEN", | ||
56 | "HIRAJOSHI", | ||
57 | }; | ||
58 | |||
59 | typedef u8 Scale[12]; | ||
60 | Scale scales[] = { | ||
61 | // 1 b2 2 b3 3 4 b5 5 b6 6 b7 7 <- Major | ||
62 | {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // CHRM | ||
63 | {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1}, // MAJR | ||
64 | {1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0}, // MINR | ||
65 | {1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0}, // PMAJ | ||
66 | {1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0}, // PMIN | ||
67 | {1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0}, // BLUE | ||
68 | {1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0}, // DORI | ||
69 | {1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0}, // PHYR | ||
70 | {1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1}, // LYDI | ||
71 | {1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0}, // MIXO | ||
72 | {1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0}, // LOCR | ||
73 | {1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1}, // PERS | ||
74 | {1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1}, // HMIN | ||
75 | {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0}, // IWAT | ||
76 | {1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0}, // INSN | ||
77 | {1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0}, // HIRA | ||
78 | }; | ||
79 | |||
80 | int current_scale = SCALE_CHRM; | ||
81 | int current_scale_root = 0; | ||
82 | |||
83 | s32 | ||
84 | scale_note(s32 current, s32 inc) { | ||
85 | if (inc > 1 || inc < -1) { | ||
86 | return CLAMP(current + inc, (s32)NOTE_C_2, (s32)NOTE_C_8 - 1); | ||
87 | } | ||
88 | s32 pos = current % 12; | ||
89 | s32 offset = 0; | ||
90 | for (int i = 1; i <= 12; i++) { | ||
91 | s32 k = (current_scale_root + pos + i * inc) % 12; | ||
92 | if (k < 0) { | ||
93 | k *= -1; | ||
94 | k = 12 - k; | ||
95 | } | ||
96 | offset += inc; | ||
97 | if (scales[current_scale][k] == 1) { | ||
98 | break; | ||
99 | } | ||
100 | } | ||
101 | return CLAMP(current + offset, (s32)NOTE_C_2, (s32)NOTE_C_8 - 1); | ||
102 | } | ||