diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-02 09:42:21 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-02 09:42:21 +0200 |
commit | 01e6349dfb76abaf9d87d94369b17c14b678e416 (patch) | |
tree | 8bd593c54cceab63cbb650647a982b4e596cc939 /src/main.c | |
parent | 9c00fb0f37c20d61343bbfe9163530d458251545 (diff) | |
download | gba-experiments-01e6349dfb76abaf9d87d94369b17c14b678e416.tar.gz gba-experiments-01e6349dfb76abaf9d87d94369b17c14b678e416.zip |
Update sequencer to use timers w/ different bpms
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 156 |
1 files changed, 81 insertions, 75 deletions
@@ -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 | ||
16 | typedef struct SeqTrigger { | ||
17 | bool trigger; | ||
18 | Note note; | ||
19 | // TODO: ... | ||
20 | } SeqTrigger; | ||
21 | |||
22 | static 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 | |||
44 | int step_counter = 0; | ||
45 | Note active_note; | ||
46 | void | ||
47 | irq_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 | |||
57 | void | ||
58 | set_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 | |||
16 | int main(void) { | 74 | int 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; |