aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-04-25 16:29:44 +0200
committerBad Diode <bd@badd10de.dev>2024-04-25 16:29:44 +0200
commit901ba917a3b4812f7eacf93d55389978a907a44d (patch)
tree40848dc90600f928ae981636190ce19498ba3516
parentc9a48c8cbea8718181632c461a7ed9abae9988e3 (diff)
downloadstepper-lsdjsync.tar.gz
stepper-lsdjsync.zip
Staging some testing samples for backuplsdjsync
-rw-r--r--Makefile2
-rw-r--r--src/main.c2
-rw-r--r--src/sequencer.c253
3 files changed, 219 insertions, 38 deletions
diff --git a/Makefile b/Makefile
index e464b75..abaa008 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS))
27INC_FLAGS += -I$(LIBGBA_SRC) 27INC_FLAGS += -I$(LIBGBA_SRC)
28 28
29# Output library names and executables. 29# Output library names and executables.
30TARGET := STEPPER-v1.8 30TARGET := STEPPER-v1.8-dev-lsdj
31ELF := $(BUILD_DIR)/$(TARGET).elf 31ELF := $(BUILD_DIR)/$(TARGET).elf
32BIN := $(BUILD_DIR)/$(TARGET).gba 32BIN := $(BUILD_DIR)/$(TARGET).gba
33 33
diff --git a/src/main.c b/src/main.c
index 170e0e0..81e47a1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -255,7 +255,7 @@ main(void) {
255 255
256 // Register interrupts. 256 // Register interrupts.
257 irq_init(); 257 irq_init();
258 irs_set(IRQ_VBLANK, sound_vsync); 258 irs_set(IRQ_VBLANK, irs_stub);
259 259
260 // Initialize sequencer. 260 // Initialize sequencer.
261 sequencer_init(); 261 sequencer_init();
diff --git a/src/sequencer.c b/src/sequencer.c
index 9efd506..d2a0054 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -25,32 +25,185 @@ clear_pattern(size_t idx) {
25 25
26void 26void
27gate_off(void) { 27gate_off(void) {
28 SIO_MODE = SIO_MODE_GP 28 // SIO_MODE = SIO_MODE_GP
29 | SIO_SC_OUT(1) 29 // | SIO_SC_OUT(1)
30 | SIO_SD_OUT(1) 30 // | SIO_SD_OUT(0)
31 | SIO_SI_OUT(0) 31 // | SIO_SI_OUT(0)
32 | SIO_SO_OUT(1) 32 // | SIO_SO_OUT(0)
33 | SIO_SC(0) 33 // | SIO_SI(0)
34 | SIO_SD(0) 34 // | SIO_SC(0)
35 | SIO_SO(0); 35 // | SIO_SD(0)
36 TIMER_CTRL_3 = 0; 36 // | SIO_SO(0);
37 // TIMER_CTRL_3 = 0;
38}
39
40int pulses_sent = 0;
41int gate_status = 0;
42
43void
44gate_lsdj(void) {
45 gate_status ^= 1;
46 if (pulses_sent >= 7) {
47 gate_off();
48 return;
49 }
50 if (gate_status == 1) {
51 gate_off();
52 } else {
53 pulses_sent++;
54 SIO_MODE = SIO_MODE_GP
55 | SIO_SC_OUT(1)
56 | SIO_SD_OUT(0)
57 | SIO_SI_OUT(0)
58 | SIO_SO_OUT(0)
59 | SIO_SI(0)
60 | SIO_SC(1)
61 | SIO_SD(0)
62 | SIO_SO(0);
63 }
64 int n_ticks = -80 / 8 / 2; // 5ms
65 irs_set(IRQ_TIMER_3, gate_lsdj);
66 TIMER_DATA_3 = n_ticks;
67 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
37} 68}
38 69
70// TODO: LSDJ sync pulse?
71
39void 72void
40gate_on(void) { 73gate_on(void) {
41 gate_off(); 74 // SYNC24 NOTES
75 // (from https://e-rm.de/data/E-RM_report_HowToDinSync_10_14_EN.pdf)
76 //
77 // "Moreover, a duty cycle of 50% doesn’t seem to be nescessary, all tested
78 // machines were able to sync properly to clock ticks with a positive width
79 // of 5 ms to up to 300 BPM" @ 24bpq
80 //
81 // int bpm = 100;
82 // if (settings.global_bpm) {
83 // bpm = settings.bpm;
84 // } else {
85 // bpm patterns[current_pattern].bpm;
86 // }
87 // gate_off();
88 // pulses_sent = 0;
89 // gate_status = 0;
90 // SIO_MODE = SIO_MODE_GP
91 // | SIO_SC_OUT(1)
92 // | SIO_SD_OUT(0)
93 // | SIO_SI_OUT(0)
94 // | SIO_SO_OUT(0)
95 // | SIO_SI(0)
96 // | SIO_SC(1)
97 // | SIO_SD(0)
98 // | SIO_SO(0);
99 // // int n_ticks = -80; // 5ms
100 // // irs_set(IRQ_TIMER_3, gate_off);
101 // // TIMER_DATA_3 = n_ticks;
102 // // TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
103 // int n_ticks = -80 / 8 / 2; // 5ms
104 // irs_set(IRQ_TIMER_3, gate_lsdj);
105 // TIMER_DATA_3 = n_ticks;
106 // TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
107 // int n_ticks = -79; // 5ms
108 // TIMER_DATA_3 = n_ticks;
109 // TIMER_CTRL_3 = TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
110 // while (1) {
111 // int cnt = TIMER_DATA_3;
112 // if (cnt >= 80) {
113 // gate_off();
114 // break;
115 // }
116 // }
117}
118
119bool first_pulse = true;
120int so_status = 1;
121
122void
123lsdj_toggle(void) {
124 gate_status ^= 1;
125 if (pulses_sent >= 7) {
126 TIMER_CTRL_3 = 0;
127 SIO_MODE = SIO_MODE_GP
128 | SIO_SI_OUT(0)
129 | SIO_SC_OUT(1)
130 | SIO_SD_OUT(0)
131 | SIO_SO_OUT(1)
132 | SIO_SI(0)
133 | SIO_SC(1)
134 | SIO_SD(0)
135 | SIO_SO(so_status);
136 return;
137 }
138 if (gate_status == 1) {
139 SIO_MODE = SIO_MODE_GP
140 | SIO_SI_OUT(0)
141 | SIO_SC_OUT(1)
142 | SIO_SD_OUT(0)
143 | SIO_SO_OUT(1)
144 | SIO_SI(0)
145 | SIO_SC(1)
146 | SIO_SD(0)
147 | SIO_SO(so_status);
148 } else {
149 pulses_sent++;
150 SIO_MODE = SIO_MODE_GP
151 | SIO_SI_OUT(0)
152 | SIO_SC_OUT(1)
153 | SIO_SD_OUT(0)
154 | SIO_SO_OUT(1)
155 | SIO_SI(0)
156 | SIO_SC(0)
157 | SIO_SD(0)
158 | SIO_SO(so_status);
159 }
160 TIMER_CTRL_3 = 0;
161 // int n_ticks = -80 / 8 / 2; // 5ms
162 // irs_set(IRQ_TIMER_3, lsdj_toggle);
163 // TIMER_DATA_3 = n_ticks;
164 // TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
165 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16
166 irs_set(IRQ_TIMER_3, lsdj_toggle);
167 TIMER_DATA_3 = n_ticks;
168 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1;
169}
170
171void
172lsdj_pulse(void) {
173 // LSDJ expects a pulse train on the SC pin (active low?). For the song
174 // start, the first pulse and until the start of the second one it should
175 // set SO to low as follows:
176 //
177 // CLK (SC) --_-_-_-_-_-_-_-_----------------_-_-_-_-_-_-_-_----------------
178 // OUT (SO) --_______________________________-------------------------------
179 //
180 // Additionally, in LSDJ sync mode, SO will go low at the start of each bar.
181 //
182 // The width of the pulse is approximately 915-916us (122us per pulse at 50%
183 // duty cycle of 61us). This sync method is based on sync24, so it should
184 // receive 6 pulses each 1/16th step (96 pulses in a 16 step sequence).
185 if (first_pulse) {
186 first_pulse = false;
187 so_status = 0;
188 } else {
189 so_status = 1;
190 }
191 TIMER_DATA_3 = 0;
192 pulses_sent = 0;
193 gate_status = 0;
42 SIO_MODE = SIO_MODE_GP 194 SIO_MODE = SIO_MODE_GP
43 | SIO_SC_OUT(1) 195 | SIO_SC_OUT(1)
44 | SIO_SD_OUT(1) 196 | SIO_SD_OUT(0)
45 | SIO_SI_OUT(0) 197 | SIO_SI_OUT(0)
46 | SIO_SO_OUT(1) 198 | SIO_SO_OUT(1)
47 | SIO_SC(1) 199 | SIO_SI(0)
200 | SIO_SC(0)
48 | SIO_SD(0) 201 | SIO_SD(0)
49 | SIO_SO(1); 202 | SIO_SO(so_status);
50 int n_ticks = -244181 / 600; 203 int n_ticks = -9; // 122/2 = 61us; 61 / 3.8 = 16
51 irs_set(IRQ_TIMER_3, gate_off); 204 irs_set(IRQ_TIMER_3, lsdj_toggle);
52 TIMER_DATA_3 = n_ticks; 205 TIMER_DATA_3 = n_ticks;
53 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; 206 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1;
54} 207}
55 208
56u8 209u8
@@ -475,31 +628,36 @@ env_start:
475 628
476void 629void
477sequencer_tick(void) { 630sequencer_tick(void) {
478 switch (settings.sync) { 631 // switch (settings.sync) {
479 case SYNC_OUT_LINK_96BPQ: { gate_on(); } break; 632 // case SYNC_OUT_LINK_96BPQ: { gate_on(); } break;
480 case SYNC_OUT_LINK_48BPQ: { if (sync_ticks++ % 2 == 0) { gate_on(); } } break; 633 // case SYNC_OUT_LINK_48BPQ: { if (sync_ticks++ % 2 == 0) { gate_on(); } } break;
481 case SYNC_OUT_LINK_24BPQ: { if (sync_ticks++ % 4 == 0) { gate_on(); } } break; 634 // case SYNC_OUT_LINK_24BPQ: { if (sync_ticks++ % 4 == 0) { gate_on(); } } break;
482 case SYNC_OUT_LINK_12BPQ: { if (sync_ticks++ % 8 == 0) { gate_on(); } } break; 635 // case SYNC_OUT_LINK_12BPQ: { if (sync_ticks++ % 8 == 0) { gate_on(); } } break;
483 case SYNC_OUT_LINK_6BPQ: { if (sync_ticks++ % 16 == 0) { gate_on(); } } break; 636 // case SYNC_OUT_LINK_6BPQ: { if (sync_ticks++ % 16 == 0) { gate_on(); } } break;
484 case SYNC_OUT_LINK_4BPQ: { if (sync_ticks++ % 24 == 0) { gate_on(); } } break; 637 // case SYNC_OUT_LINK_4BPQ: { if (sync_ticks++ % 24 == 0) { gate_on(); } } break;
485 case SYNC_OUT_LINK_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); } } break; 638 // case SYNC_OUT_LINK_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); } } break;
486 case SYNC_OUT_AUDIO_12BPQ: { if (sync_ticks++ % 8 == 0) { audio_sync_click = true; } } break; 639 // case SYNC_OUT_AUDIO_12BPQ: { if (sync_ticks++ % 8 == 0) { audio_sync_click = true; } } break;
487 case SYNC_OUT_AUDIO_6BPQ: { if (sync_ticks++ % 16 == 0) { audio_sync_click = true; } } break; 640 // case SYNC_OUT_AUDIO_6BPQ: { if (sync_ticks++ % 16 == 0) { audio_sync_click = true; } } break;
488 case SYNC_OUT_AUDIO_4BPQ: { if (sync_ticks++ % 24 == 0) { audio_sync_click = true; } } break; 641 // case SYNC_OUT_AUDIO_4BPQ: { if (sync_ticks++ % 24 == 0) { audio_sync_click = true; } } break;
489 case SYNC_OUT_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { audio_sync_click = true; } } break; 642 // case SYNC_OUT_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { audio_sync_click = true; } } break;
490 case SYNC_OUT_LINK_AUDIO_12BPQ: { if (sync_ticks++ % 8 == 0) { gate_on(); audio_sync_click = true; } } break; 643 // case SYNC_OUT_LINK_AUDIO_12BPQ: { if (sync_ticks++ % 8 == 0) { gate_on(); audio_sync_click = true; } } break;
491 case SYNC_OUT_LINK_AUDIO_6BPQ: { if (sync_ticks++ % 16 == 0) { gate_on(); audio_sync_click = true; } } break; 644 // case SYNC_OUT_LINK_AUDIO_6BPQ: { if (sync_ticks++ % 16 == 0) { gate_on(); audio_sync_click = true; } } break;
492 case SYNC_OUT_LINK_AUDIO_4BPQ: { if (sync_ticks++ % 24 == 0) { gate_on(); audio_sync_click = true; } } break; 645 // case SYNC_OUT_LINK_AUDIO_4BPQ: { if (sync_ticks++ % 24 == 0) { gate_on(); audio_sync_click = true; } } break;
493 case SYNC_OUT_LINK_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); audio_sync_click = true; } } break; 646 // case SYNC_OUT_LINK_AUDIO_2BPQ: { if (sync_ticks++ % 48 == 0) { gate_on(); audio_sync_click = true; } } break;
494 default: break; 647 // default: break;
495 } 648 // }
496 if (nseq_ticks++ == 0) { 649 if (nseq_ticks++ == 0) {
497 play_step(); 650 if (step_counter % 16 == 0) {
651 // first_pulse = true;
652 }
653 step_counter = (step_counter + 1) % 16;
654 // play_step();
498 } 655 }
656 if (sync_ticks++ % 4 == 0) { lsdj_pulse(); }
499 if (nseq_ticks == 24) { 657 if (nseq_ticks == 24) {
500 nseq_ticks = 0; 658 nseq_ticks = 0;
501 } 659 }
502 wave_ad_tick(); 660 // wave_ad_tick();
503} 661}
504 662
505void 663void
@@ -680,10 +838,23 @@ stop_sound(void) {
680 SOUND_NOISE_CTRL = 0; 838 SOUND_NOISE_CTRL = 0;
681 redraw_play_pause = true; 839 redraw_play_pause = true;
682 redraw_pattern_buttons = true; 840 redraw_pattern_buttons = true;
841 SIO_MODE = SIO_MODE_GP
842 | SIO_SI_OUT(0)
843 | SIO_SC_OUT(1)
844 | SIO_SD_OUT(0)
845 | SIO_SO_OUT(1)
846 | SIO_SI(0)
847 | SIO_SC(1)
848 | SIO_SD(0)
849 | SIO_SO(1);
683} 850}
684 851
685void 852void
686reset_sequencer(void) { 853reset_sequencer(void) {
854 first_pulse = true;
855 so_status = 1;
856 gate_status = 0;
857 pulses_sent = 0;
687 step_counter = 0; 858 step_counter = 0;
688 nseq_ticks = 0; 859 nseq_ticks = 0;
689 sync_ticks = 0; 860 sync_ticks = 0;
@@ -1984,4 +2155,14 @@ sequencer_init(void) {
1984 SOUND_STATUS = SOUND_ENABLE; 2155 SOUND_STATUS = SOUND_ENABLE;
1985 init_dsound(); 2156 init_dsound();
1986 set_audio_settings(); 2157 set_audio_settings();
2158 // gate_off();
2159 SIO_MODE = SIO_MODE_GP
2160 | SIO_SC_OUT(1)
2161 | SIO_SD_OUT(0)
2162 | SIO_SI_OUT(0)
2163 | SIO_SO_OUT(1)
2164 | SIO_SI(0)
2165 | SIO_SC(1)
2166 | SIO_SD(0)
2167 | SIO_SO(1);
1987} 2168}