aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-05-30 21:30:44 +0200
committerBad Diode <bd@badd10de.dev>2023-05-30 21:30:44 +0200
commitdc53af3f01c0cbaefe4b330e2dcc2396b5afde47 (patch)
tree474daea389f65f82458097fe8d7871dfaf3901f7
parent9b510f2346d41a7d110334d1ca752fd3a81a3fc6 (diff)
downloadstepper-dc53af3f01c0cbaefe4b330e2dcc2396b5afde47.tar.gz
stepper-dc53af3f01c0cbaefe4b330e2dcc2396b5afde47.zip
Add initial audio sync
-rw-r--r--src/gba/gba.h8
-rw-r--r--src/main.c27
-rw-r--r--src/sequencer.c37
3 files changed, 38 insertions, 34 deletions
diff --git a/src/gba/gba.h b/src/gba/gba.h
index f726b72..2b28295 100644
--- a/src/gba/gba.h
+++ b/src/gba/gba.h
@@ -522,12 +522,12 @@ sound_volume(SoundChannel channels, u8 volume) {
522#define SOUND_DMG100 0x2 522#define SOUND_DMG100 0x2
523#define SOUND_DSOUND_RATIO_A (1 << 0x2) 523#define SOUND_DSOUND_RATIO_A (1 << 0x2)
524#define SOUND_DSOUND_RATIO_B (1 << 0x3) 524#define SOUND_DSOUND_RATIO_B (1 << 0x3)
525#define SOUND_DSOUND_LEFT_A (1 << 0x8) 525#define SOUND_DSOUND_RIGHT_A (1 << 0x8)
526#define SOUND_DSOUND_RIGHT_A (1 << 0x9) 526#define SOUND_DSOUND_LEFT_A (1 << 0x9)
527#define SOUND_DSOUND_TIMER_A (1 << 0xA) 527#define SOUND_DSOUND_TIMER_A (1 << 0xA)
528#define SOUND_DSOUND_RESET_A (1 << 0xB) 528#define SOUND_DSOUND_RESET_A (1 << 0xB)
529#define SOUND_DSOUND_LEFT_B (1 << 0xC) 529#define SOUND_DSOUND_RIGHT_B (1 << 0xC)
530#define SOUND_DSOUND_RIGHT_B (1 << 0xD) 530#define SOUND_DSOUND_LEFT_B (1 << 0xD)
531#define SOUND_DSOUND_TIMER_B (1 << 0xE) 531#define SOUND_DSOUND_TIMER_B (1 << 0xE)
532#define SOUND_DSOUND_RESET_B (1 << 0xF) 532#define SOUND_DSOUND_RESET_B (1 << 0xF)
533 533
diff --git a/src/main.c b/src/main.c
index f0fc7c3..0d4056a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,7 +13,7 @@ WITH REGARD TO THIS SOFTWARE.
13// 13//
14// UI tweaks. 14// UI tweaks.
15// + Theming support, with a number of pre-configured themes and custom colors. 15// + Theming support, with a number of pre-configured themes and custom colors.
16// - Add more default themes 16// + Add more default themes
17// - Add custom user themes 17// - Add custom user themes
18// - Notification support for feedback when doing some operations 18// - Notification support for feedback when doing some operations
19// (copying/pasting) 19// (copying/pasting)
@@ -23,7 +23,7 @@ WITH REGARD TO THIS SOFTWARE.
23// 23//
24// Quality of life improvements. 24// Quality of life improvements.
25// + Add a settings page to change some configuration parameters. 25// + Add a settings page to change some configuration parameters.
26// - Change the cursor, the line is difficult to see. 26// + Change the cursor, the line is difficult to see. (Option to thick cursor)
27// - When not on play mode, adjusting a note or a parameter triggers the sound. 27// - When not on play mode, adjusting a note or a parameter triggers the sound.
28// This could get annoying, so maybe it should be a configuration option to 28// This could get annoying, so maybe it should be a configuration option to
29// enable it? 29// enable it?
@@ -33,25 +33,24 @@ WITH REGARD TO THIS SOFTWARE.
33// 33//
34// Advanced 34// Advanced
35// + Sync via CV by using the link cable. 35// + Sync via CV by using the link cable.
36// - Audio sync by panning left the sound and using right as a click (or 36// + Audio sync by panning left the sound and using right as a click (or
37// viceversa, needs to check the standard.) 37// viceversa, needs to check the standard.)
38// - Sync via MIDI via arduinoboy or something similar. 38// - Allow "marking" several trigs to be able to copy/paste them and/or adjust
39// - Add an FM channel using Direct Sound. 39// their parameters.
40// - Per trig note probability. 40// - Per trig note probability.
41// - Add an envelope to ch3, would need to work with a timer in order to make 41// - Add an envelope to ch3, would need to work with a timer in order to make
42// it work I think. 42// it work I think.
43// - Allow "marking" several trigs to be able to copy/paste them and/or adjust 43// - Sync via MIDI via arduinoboy or something similar.
44// their parameters.
45// 44//
46// Bugfixes 45// Bugfixes
46// + Pattern chaining seems off, it plays the first note of the pattern before
47// switching
48// + Memory corruption when trying to load a save file. Regression due to
49// removal of filesystem.c
47// - Sound can get hung up sometimes, but I can't reproduce when this happens. 50// - Sound can get hung up sometimes, but I can't reproduce when this happens.
48// Not sure if this is an emulator thing or happens also in hardware. 51// Not sure if this is an emulator thing or happens also in hardware.
49// - Cursor can stay in position instead of dissapering, again I can't 52// - Cursor can stay in position instead of dissapering, again I can't
50// reproduce this right now, just happened randomly. Needs investigation. 53// reproduce this right now, just happened randomly. Needs investigation.
51// + Pattern chaining seems off, it plays the first note of the pattern before
52// switching
53// + Memory corruption when trying to load a save file. Regression due to
54// removal of filesystem.c
55// 54//
56 55
57#include "gba/gba.h" 56#include "gba/gba.h"
@@ -59,6 +58,7 @@ WITH REGARD TO THIS SOFTWARE.
59#include "renderer_m0.c" 58#include "renderer_m0.c"
60#include "globals.c" 59#include "globals.c"
61#include "settings.c" 60#include "settings.c"
61#include "dsound.c"
62#include "sequencer.c" 62#include "sequencer.c"
63 63
64#define PROF_ENABLE 0 64#define PROF_ENABLE 0
@@ -166,6 +166,9 @@ update(void) {
166 set_time(patterns[current_pattern].bpm); 166 set_time(patterns[current_pattern].bpm);
167 update_bpm = false; 167 update_bpm = false;
168 } 168 }
169 if (audio_sync_click) {
170 play_click();
171 }
169} 172}
170 173
171int 174int
@@ -178,7 +181,7 @@ main(void) {
178 181
179 // Register interrupts. 182 // Register interrupts.
180 irq_init(); 183 irq_init();
181 irs_set(IRQ_VBLANK, irs_stub); 184 irs_set(IRQ_VBLANK, sound_vsync);
182 185
183 // Initialize sequencer. 186 // Initialize sequencer.
184 sequencer_init(); 187 sequencer_init();
diff --git a/src/sequencer.c b/src/sequencer.c
index b295730..d8c5f3f 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -26,9 +26,9 @@ gate_off(void) {
26 | SIO_SI_OUT(0) 26 | SIO_SI_OUT(0)
27 | SIO_SO_OUT(1) 27 | SIO_SO_OUT(1)
28 | SIO_SC(0) 28 | SIO_SC(0)
29 | SIO_SD(1) 29 | SIO_SD(0)
30 | SIO_SO(0); 30 | SIO_SO(0);
31 TIMER_CTRL_1 = 0; 31 TIMER_CTRL_3 = 0;
32} 32}
33 33
34void 34void
@@ -39,12 +39,13 @@ gate_on(void) {
39 | SIO_SI_OUT(0) 39 | SIO_SI_OUT(0)
40 | SIO_SO_OUT(1) 40 | SIO_SO_OUT(1)
41 | SIO_SC(1) 41 | SIO_SC(1)
42 | SIO_SD(1) 42 | SIO_SD(0)
43 | SIO_SO(0); 43 | SIO_SO(1);
44 int n_ticks = -244181 / 600; 44 int n_ticks = -244181 / 600;
45 irs_set(IRQ_TIMER_1, gate_off); 45 irs_set(IRQ_TIMER_3, gate_off);
46 TIMER_DATA_1 = n_ticks; 46 TIMER_DATA_3 = n_ticks;
47 TIMER_CTRL_1 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; 47 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
48 audio_sync_click = true;
48} 49}
49 50
50void 51void
@@ -183,9 +184,9 @@ set_time(int bpm) {
183 // We have to operate on integer values, so the numbers have been 184 // We have to operate on integer values, so the numbers have been
184 // precalculated to `n_ticks = 244181 / bmp` 185 // precalculated to `n_ticks = 244181 / bmp`
185 int n_ticks = -244181 / bpm; 186 int n_ticks = -244181 / bpm;
186 irs_set(IRQ_TIMER_0, play_step); 187 irs_set(IRQ_TIMER_2, play_step);
187 TIMER_DATA_0 = n_ticks; 188 TIMER_DATA_2 = n_ticks;
188 TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; 189 TIMER_CTRL_2 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
189} 190}
190 191
191TriggerNote * 192TriggerNote *
@@ -296,7 +297,7 @@ void
296stop_playing(void) { 297stop_playing(void) {
297 play_status = 0; 298 play_status = 0;
298 step_counter = 0; 299 step_counter = 0;
299 TIMER_CTRL_0 = 0; 300 TIMER_CTRL_2 = 0;
300 SOUND_SQUARE1_CTRL = 0; 301 SOUND_SQUARE1_CTRL = 0;
301 SOUND_SQUARE2_CTRL = 0; 302 SOUND_SQUARE2_CTRL = 0;
302 SOUND_WAVE_CTRL = 0; 303 SOUND_WAVE_CTRL = 0;
@@ -308,7 +309,7 @@ void
308toggle_playing(void) { 309toggle_playing(void) {
309 play_status ^= 1; 310 play_status ^= 1;
310 step_counter = 0; 311 step_counter = 0;
311 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { 312 if ((TIMER_CTRL_2 & TIMER_CTRL_ENABLE) == 0) {
312 if (current_pattern != next_pattern) { 313 if (current_pattern != next_pattern) {
313 current_pattern = next_pattern; 314 current_pattern = next_pattern;
314 redraw_pattern_buttons = true; 315 redraw_pattern_buttons = true;
@@ -316,7 +317,7 @@ toggle_playing(void) {
316 set_time(patterns[current_pattern].bpm); 317 set_time(patterns[current_pattern].bpm);
317 play_step(); 318 play_step();
318 } else { 319 } else {
319 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; 320 TIMER_CTRL_2 ^= TIMER_CTRL_ENABLE;
320 SOUND_SQUARE1_CTRL = 0; 321 SOUND_SQUARE1_CTRL = 0;
321 SOUND_SQUARE2_CTRL = 0; 322 SOUND_SQUARE2_CTRL = 0;
322 SOUND_WAVE_CTRL = 0; 323 SOUND_WAVE_CTRL = 0;
@@ -328,7 +329,7 @@ toggle_playing(void) {
328void 329void
329pause_playing(void) { 330pause_playing(void) {
330 play_status ^= 1; 331 play_status ^= 1;
331 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { 332 if ((TIMER_CTRL_2 & TIMER_CTRL_ENABLE) == 0) {
332 if (current_pattern != next_pattern && step_counter == 0) { 333 if (current_pattern != next_pattern && step_counter == 0) {
333 current_pattern = next_pattern; 334 current_pattern = next_pattern;
334 redraw_pattern_buttons = true; 335 redraw_pattern_buttons = true;
@@ -336,7 +337,7 @@ pause_playing(void) {
336 set_time(patterns[current_pattern].bpm); 337 set_time(patterns[current_pattern].bpm);
337 play_step(); 338 play_step();
338 } else { 339 } else {
339 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; 340 TIMER_CTRL_2 ^= TIMER_CTRL_ENABLE;
340 SOUND_SQUARE1_CTRL = 0; 341 SOUND_SQUARE1_CTRL = 0;
341 SOUND_SQUARE2_CTRL = 0; 342 SOUND_SQUARE2_CTRL = 0;
342 SOUND_WAVE_CTRL = 0; 343 SOUND_WAVE_CTRL = 0;
@@ -414,7 +415,7 @@ handle_right_col_selection(void) {
414 patterns[pattern_selection_loc].bpm + bpm_inc, 415 patterns[pattern_selection_loc].bpm + bpm_inc,
415 10, 416 10,
416 300); 417 300);
417 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) != 0 418 if ((TIMER_CTRL_2 & TIMER_CTRL_ENABLE) != 0
418 && current_pattern == pattern_selection_loc) { 419 && current_pattern == pattern_selection_loc) {
419 set_time(patterns[current_pattern].bpm); 420 set_time(patterns[current_pattern].bpm);
420 } 421 }
@@ -432,7 +433,7 @@ handle_right_col_selection(void) {
432 patterns[pattern_selection_loc].bpm + bpm_inc, 433 patterns[pattern_selection_loc].bpm + bpm_inc,
433 10, 434 10,
434 300); 435 300);
435 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) != 0 436 if ((TIMER_CTRL_2 & TIMER_CTRL_ENABLE) != 0
436 && current_pattern == pattern_selection_loc) { 437 && current_pattern == pattern_selection_loc) {
437 set_time(patterns[current_pattern].bpm); 438 set_time(patterns[current_pattern].bpm);
438 } 439 }
@@ -1036,5 +1037,5 @@ sequencer_init(void) {
1036 | SOUND_SQUARE2 1037 | SOUND_SQUARE2
1037 | SOUND_WAVE 1038 | SOUND_WAVE
1038 | SOUND_NOISE, 3); 1039 | SOUND_NOISE, 3);
1039 SOUND_DSOUND_MASTER = SOUND_DMG100; 1040 init_dsound();
1040} 1041}