aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-08-22 17:44:01 +0200
committerBad Diode <bd@badd10de.dev>2023-08-22 17:44:01 +0200
commit5d86238b8cc3c6dba95e90eed9fb444bb276f02e (patch)
treed3b1d4c4509631a3dace28486b6887445298af1f
parent9c0c004b78a12861ed03ce851d0885d68a25cb02 (diff)
downloadstepper-5d86238b8cc3c6dba95e90eed9fb444bb276f02e.tar.gz
stepper-5d86238b8cc3c6dba95e90eed9fb444bb276f02e.zip
Added initial implementation of scale mode
-rw-r--r--src/globals.c60
-rw-r--r--src/main.c8
-rw-r--r--src/scale.c102
-rw-r--r--src/sequencer.c8
4 files changed, 111 insertions, 67 deletions
diff --git a/src/globals.c b/src/globals.c
index a971120..23012c8 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -189,63 +189,3 @@ typedef enum Prob {
189 PROB_20, 189 PROB_20,
190 PROB_NUM, 190 PROB_NUM,
191} Prob; 191} Prob;
192
193typedef enum Scales {
194 SCALE_CHRM,
195 SCALE_MAJR,
196 SCALE_MINR,
197 SCALE_PMAJ,
198 SCALE_PMIN,
199 SCALE_BLUE,
200 SCALE_DORI,
201 SCALE_PHYR,
202 SCALE_LYDI,
203 SCALE_MIXO,
204 SCALE_LOCR,
205 SCALE_PERS,
206 SCALE_HMIN,
207 SCALE_IWAT,
208 SCALE_INSN,
209 SCALE_HIRA,
210 SCALE_NUM,
211} Scales;
212
213char *scale_short[] = {
214 "CHRM",
215 "MAJR",
216 "MINR",
217 "PMAJ",
218 "PMIN",
219 "BLUE",
220 "DORI",
221 "PHYR",
222 "LYDI",
223 "MIXO",
224 "LOCR",
225 "PERS",
226 "HMIN",
227 "IWAT",
228 "INSN",
229 "HIRA",
230};
231
232char *scale_long[] = {
233 "CHROMATIC",
234 "MAJOR",
235 "MINOR",
236 "PENTATONIC MAJOR",
237 "PENTATONIC MINOR",
238 "BLUES",
239 "DORIAN",
240 "PHYRGIAN",
241 "LYDIAN",
242 "MIXOLYDIAN",
243 "LOCRIAN",
244 "PERSIAN",
245 "HUNGARIAN MINOR",
246 "IWATO",
247 "IN-SEN",
248 "HIRAJOSHI",
249};
250
251int current_scale = SCALE_CHRM;
diff --git a/src/main.c b/src/main.c
index 6bc3578..fe3dba0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -49,13 +49,14 @@ WITH REGARD TO THIS SOFTWARE.
49// that it's clear it's affecting all triggers. 49// that it's clear it's affecting all triggers.
50// + Fix keyboard note drawing bugs. 50// + Fix keyboard note drawing bugs.
51// + Fix stop button behaviour. 51// + Fix stop button behaviour.
52// + Scale mode for entering notes.
53// - Shortcut to quickly exit/enter chain mode.
54// - Make sure bank switching is queued like patterns.
55//
52// - Improve SRAM saving to make room for longer patterns and/or more banks. 56// - Improve SRAM saving to make room for longer patterns and/or more banks.
53// - Scale mode for entering notes.
54// - Higher resolution clock to allow for microtiming and more accurate tempo. 57// - Higher resolution clock to allow for microtiming and more accurate tempo.
55// - Multiple pattern chains per bank that we can toggle between, gotta study 58// - Multiple pattern chains per bank that we can toggle between, gotta study
56// if they fit in the SRAM. 59// if they fit in the SRAM.
57// - Shortcut to quickly exit/enter chain mode.
58// - Make sure bank switching is queued like patterns.
59// - Add settings for "performance mode" in which banks are not saved by 60// - Add settings for "performance mode" in which banks are not saved by
60// default while changing patterns. 61// default while changing patterns.
61// - Make sure sync works with the same cable for in/out. 62// - Make sure sync works with the same cable for in/out.
@@ -72,6 +73,7 @@ WITH REGARD TO THIS SOFTWARE.
72#include "globals.c" 73#include "globals.c"
73#include "settings.c" 74#include "settings.c"
74#include "dsound.c" 75#include "dsound.c"
76#include "scale.c"
75#include "sequencer.c" 77#include "sequencer.c"
76 78
77#define PROF_ENABLE 0 79#define PROF_ENABLE 0
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 @@
1typedef 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
21char *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
40char *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
59typedef u8 Scale[12];
60Scale 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
80int current_scale = SCALE_CHRM;
81int current_scale_root = 0;
82
83s32
84scale_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}
diff --git a/src/sequencer.c b/src/sequencer.c
index ce09658..609ccee 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -406,7 +406,7 @@ handle_channel_selection(void) {
406 case 3: { trig = &pat->ch4.notes[i]; } break; 406 case 3: { trig = &pat->ch4.notes[i]; } break;
407 default: {trig = &pat->ch1.notes[i]; } break; 407 default: {trig = &pat->ch1.notes[i]; } break;
408 } 408 }
409 trig->note = MAX((s32)trig->note + inc, (s32)NOTE_C_2); 409 trig->note = scale_note(trig->note, inc);
410 } 410 }
411 redraw_trigs = true; 411 redraw_trigs = true;
412 } else if (key_tap(KEY_R)) { 412 } else if (key_tap(KEY_R)) {
@@ -423,7 +423,7 @@ handle_channel_selection(void) {
423 case 3: { trig = &pat->ch4.notes[i]; } break; 423 case 3: { trig = &pat->ch4.notes[i]; } break;
424 default: {trig = &pat->ch1.notes[i]; } break; 424 default: {trig = &pat->ch1.notes[i]; } break;
425 } 425 }
426 trig->note = MIN((s32)trig->note + inc, (s32)NOTE_C_8 - 1); 426 trig->note = scale_note(trig->note, inc);
427 } 427 }
428 redraw_trigs = true; 428 redraw_trigs = true;
429 } 429 }
@@ -1292,7 +1292,7 @@ handle_trigger_selection(void) {
1292 } 1292 }
1293 // Decrease note. 1293 // Decrease note.
1294 if (trig->active && !empty) { 1294 if (trig->active && !empty) {
1295 trig->note = MAX((s32)trig->note + inc, (s32)NOTE_C_2); 1295 trig->note = scale_note(trig->note, inc);
1296 } 1296 }
1297 redraw_trigs = true; 1297 redraw_trigs = true;
1298 redraw_piano_note = true; 1298 redraw_piano_note = true;
@@ -1303,7 +1303,7 @@ handle_trigger_selection(void) {
1303 } 1303 }
1304 // Increase note. 1304 // Increase note.
1305 if (trig->active && !empty) { 1305 if (trig->active && !empty) {
1306 trig->note = MIN((s32)trig->note + inc, (s32)NOTE_C_8 - 1); 1306 trig->note = scale_note(trig->note, inc);
1307 } 1307 }
1308 redraw_trigs = true; 1308 redraw_trigs = true;
1309 redraw_piano_note = true; 1309 redraw_piano_note = true;