summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-02 09:42:21 +0200
committerBad Diode <bd@badd10de.dev>2021-05-02 09:42:21 +0200
commit01e6349dfb76abaf9d87d94369b17c14b678e416 (patch)
tree8bd593c54cceab63cbb650647a982b4e596cc939
parent9c00fb0f37c20d61343bbfe9163530d458251545 (diff)
downloadgba-experiments-01e6349dfb76abaf9d87d94369b17c14b678e416.tar.gz
gba-experiments-01e6349dfb76abaf9d87d94369b17c14b678e416.zip
Update sequencer to use timers w/ different bpms
-rw-r--r--src/common.h1
-rw-r--r--src/main.c156
2 files changed, 82 insertions, 75 deletions
diff --git a/src/common.h b/src/common.h
index 4151d18..ece94cd 100644
--- a/src/common.h
+++ b/src/common.h
@@ -224,6 +224,7 @@ flip_page(void) {
224#define TIMER_CTRL_CASCADE (1 << 2) 224#define TIMER_CTRL_CASCADE (1 << 2)
225#define TIMER_CTRL_IRQ (1 << 6) 225#define TIMER_CTRL_IRQ (1 << 6)
226#define TIMER_CTRL_ENABLE (1 << 7) 226#define TIMER_CTRL_ENABLE (1 << 7)
227#define TIMER_CTRL_DISABLE (0 << 7)
227 228
228// We use timers 2 and 3 to count the number of cycles since the profile_start 229// We use timers 2 and 3 to count the number of cycles since the profile_start
229// functions is called. Don't use if the code we are trying to profile make use 230// functions is called. Don't use if the code we are trying to profile make use
diff --git a/src/main.c b/src/main.c
index ac6bf66..b2cd2d2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,6 +13,64 @@
13// TODO: Cleanup OBJ/OAM memory copying and access. 13// TODO: Cleanup OBJ/OAM memory copying and access.
14// 14//
15 15
16typedef struct SeqTrigger {
17 bool trigger;
18 Note note;
19 // TODO: ...
20} SeqTrigger;
21
22static SeqTrigger sequence_synth_1 [] = {
23 {true, NOTE_D_4},
24 {true, NOTE_F_4},
25 {true, NOTE_A_4},
26 {true, NOTE_C_5},
27
28 {true, NOTE_D_4},
29 {false, NOTE_D_4},
30 {false, NOTE_D_4},
31 {false, NOTE_D_4},
32
33 {true, NOTE_D_4},
34 {true, NOTE_F_4},
35 {true, NOTE_A_4},
36 {true, NOTE_C_5},
37
38 {true, NOTE_D_4},
39 {false, NOTE_D_4},
40 {true, NOTE_A_4},
41 {false, NOTE_A_5},
42};
43
44int step_counter = 0;
45Note active_note;
46void
47irq_timer_0(void) {
48 active_note = sequence_synth_1[step_counter].note;
49 if (sequence_synth_1[step_counter].trigger) {
50 SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(13) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_DUTY(2);
51 SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note];
52 }
53
54 step_counter = (step_counter + 1) % 16;
55}
56
57void
58set_time(int bpm) {
59 // TIMER_CTRL_0 = TIMER_CTRL_DISABLE;
60
61 // The number of ticks of a 1024 cycle clock in a step based on the BPM can
62 // be calculated as:
63 // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s
64 // Y ms -> Ye-3 / 59.99e-9 /1024 = Z ticks
65 // We have to operate on integer values, so the numbers have been
66 // precalculated to `n_ticks = 244181 / bmp`
67 int n_ticks = -244181 / bpm;
68
69 irs_set(IRQ_TIMER_0, irq_timer_0);
70 TIMER_DATA_0 = n_ticks;
71 TIMER_CTRL_0 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
72}
73
16int main(void) { 74int main(void) {
17 // Configure the display in mode 0 to show OBJs, where tile memory is 75 // Configure the display in mode 0 to show OBJs, where tile memory is
18 // sequential. 76 // sequential.
@@ -35,91 +93,39 @@ int main(void) {
35 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2, 7); 93 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2, 7);
36 SOUND_DSOUND_MASTER = SOUND_DMG100; 94 SOUND_DSOUND_MASTER = SOUND_DMG100;
37 95
38 Note active_note = NOTE_C_4; 96 // Initialize timer.
39 int octave_diff = 0; 97 int bpm = 120;
40 bool playing = false; 98
41 bool new_note = false;
42 u8 interval = 7;
43 u32 sound_sequence[16] = {
44 NOTE_C_4,
45 NOTE_A_4,
46 NOTE_D_5,
47 NOTE_D_4,
48 NOTE_F_4,
49 NOTE_G_4,
50 NOTE_C_4,
51 NOTE_A_4,
52 NOTE_D_5,
53 NOTE_D_4,
54 NOTE_F_4,
55 NOTE_G_4,
56 NOTE_A_4,
57 NOTE_G_4,
58 NOTE_A_4,
59 NOTE_F_4,
60 };
61 int step_counter = 0;
62 int step_counter_2 = 0;
63 int frame_counter = 0;
64 bool trigger_1 = true;
65 bool trigger_2 = true;
66 while(true) { 99 while(true) {
67 bios_vblank_wait(); 100 bios_vblank_wait();
68 poll_keys(); 101 poll_keys();
69 102 if (key_hold(KEY_UP)) {
70 txt_position(0, 1); 103 bpm += 1;
71 104 set_time(bpm);
72 if (frame_counter >= 7 * 4) {
73 if ((step_counter + 1) % 4 == 0) {
74 step_counter_2 = (step_counter_2 + 1) % 16;
75 trigger_2 = true;
76 }
77 trigger_1 = true;
78 frame_counter = 0;
79 step_counter = (step_counter + 1) % 16;
80 }
81
82 if (trigger_1 && playing) {
83 active_note = sound_sequence[step_counter];
84 txt_clear_line();
85 txt_printf("SYNTH 1\n\n");
86 txt_clear_line();
87 txt_printf("Step: %d\n", step_counter);
88 txt_clear_line();
89 txt_printf("Playing: %s\n\n\n\n", note_names[active_note]);
90 SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(13) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_DUTY(1);
91 SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note];
92 trigger_1 = false;
93 } 105 }
94 106 if (key_hold(KEY_DOWN)) {
95 if (trigger_2 && playing) { 107 bpm -= 1;
96 active_note = sound_sequence[step_counter_2]; 108 set_time(bpm);
97 txt_clear_line();
98 txt_printf("SYNTH 2\n\n");
99 txt_clear_line();
100 txt_printf("Step: %d\n", step_counter_2);
101 txt_clear_line();
102 txt_printf("Playing: %s\n", note_names[active_note]);
103 SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(12) | SOUND_SQUARE_ENV_TIME(3) | SOUND_SQUARE_DUTY(3);
104 SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note];
105 trigger_2 = false;
106 } 109 }
107 110
108 if (key_pressed(KEY_B)) { 111 if (key_pressed(KEY_START)) {
109 playing = true;
110 step_counter = 0; 112 step_counter = 0;
111 step_counter_2 = 8; 113 set_time(bpm);
112 frame_counter = 0;
113 trigger_1 = true;
114 trigger_2 = true;
115 } 114 }
116 115 if (key_pressed(KEY_SELECT)) {
117 if (key_pressed(KEY_A)) { 116 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
118 playing = false;
119 } 117 }
120 118
121 frame_counter++; 119 txt_position(1,6);
122 // update_button_sprites(); 120 txt_clear_line();
121 txt_printf(" BPM: %d\n\n", bpm);
122
123 txt_clear_line();
124 txt_printf(" Step: %d\n", step_counter);
125 txt_clear_line();
126 txt_printf(" Note: %s\n", note_names[active_note]);
127
128 update_button_sprites();
123 }; 129 };
124 130
125 return 0; 131 return 0;