diff options
Diffstat (limited to 'src/sequencer.c')
-rw-r--r-- | src/sequencer.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/src/sequencer.c b/src/sequencer.c index f4006c4..1447056 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 | 13 | #define SEQ_DUTYCYCLE_POS_Y 10 - 8 |
14 | #define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST | 14 | #define SEQ_SWEEP_POS_X SEQ_DUTYCYCLE_POS_X + SEQ_ENV_DIST |
15 | #define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y | 15 | #define SEQ_SWEEP_POS_Y SEQ_ENV_POS_Y |
16 | #define SEQ_N_CHANNELS 2 | 16 | #define SEQ_N_CHANNELS 3 |
17 | 17 | ||
18 | u32 sprite_note_names[] = { | 18 | u32 sprite_note_names[] = { |
19 | 0x000000e0, 0x202020e0, 0x0000000e, 0x080e020e, | 19 | 0x000000e0, 0x202020e0, 0x0000000e, 0x080e020e, |
@@ -273,7 +273,7 @@ typedef struct SeqTrigger { | |||
273 | // TODO: Do we need other fields? | 273 | // TODO: Do we need other fields? |
274 | } SeqTrigger; | 274 | } SeqTrigger; |
275 | 275 | ||
276 | static SeqTrigger sequences[2][16] = { | 276 | static SeqTrigger sequences[3][16] = { |
277 | // Synth 1 | 277 | // Synth 1 |
278 | { | 278 | { |
279 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0}, | 279 | {true, NOTE_C_4, 8, 4, 0, 2, 0, 0, 0}, |
@@ -312,6 +312,25 @@ static SeqTrigger sequences[2][16] = { | |||
312 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | 312 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, |
313 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | 313 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, |
314 | }, | 314 | }, |
315 | // Synth 3 | ||
316 | { | ||
317 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
318 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
319 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
320 | {true, NOTE_C_5, 8, 4, 0, 2, 0, 0, 0}, | ||
321 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0}, | ||
322 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
323 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
324 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
325 | {true, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
326 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
327 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
328 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
329 | {true, NOTE_D_5, 8, 4, 0, 2, 0, 0, 0}, | ||
330 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
331 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
332 | {false, NOTE_G_5, 8, 4, 0, 2, 0, 0, 0}, | ||
333 | }, | ||
315 | }; | 334 | }; |
316 | 335 | ||
317 | // TODO: Support for copy paste anything, contextual. If we are on trigger | 336 | // TODO: Support for copy paste anything, contextual. If we are on trigger |
@@ -346,19 +365,31 @@ irq_timer_0(void) { | |||
346 | | SOUND_SQUARE_ENV_TIME(trig->env_time) | 365 | | SOUND_SQUARE_ENV_TIME(trig->env_time) |
347 | | SOUND_SQUARE_ENV_DIR(trig->env_direction) | 366 | | SOUND_SQUARE_ENV_DIR(trig->env_direction) |
348 | | SOUND_SQUARE_DUTY(trig->duty_cycle); | 367 | | SOUND_SQUARE_DUTY(trig->duty_cycle); |
349 | SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | 368 | SOUND_SQUARE1_FREQ = SOUND_FREQ_RESET |
350 | | sound_rates[active_note]; | 369 | | sound_rates[active_note]; |
351 | } | 370 | } |
352 | } | 371 | } |
353 | SeqTrigger *trig = &sequences[1][step_counter]; | ||
354 | { | 372 | { |
373 | SeqTrigger *trig = &sequences[1][step_counter]; | ||
355 | active_note = trig->note; | 374 | active_note = trig->note; |
356 | if (trig->trigger) { | 375 | if (trig->trigger) { |
357 | SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(trig->env_volume) | 376 | SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(trig->env_volume) |
358 | | SOUND_SQUARE_ENV_TIME(trig->env_time) | 377 | | SOUND_SQUARE_ENV_TIME(trig->env_time) |
359 | | SOUND_SQUARE_ENV_DIR(trig->env_direction) | 378 | | SOUND_SQUARE_ENV_DIR(trig->env_direction) |
360 | | SOUND_SQUARE_DUTY(trig->duty_cycle); | 379 | | SOUND_SQUARE_DUTY(trig->duty_cycle); |
361 | SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | 380 | SOUND_SQUARE2_FREQ = SOUND_FREQ_RESET |
381 | | sound_rates[active_note]; | ||
382 | } | ||
383 | } | ||
384 | { | ||
385 | SeqTrigger *trig = &sequences[2][step_counter]; | ||
386 | active_note = trig->note; | ||
387 | if (trig->trigger) { | ||
388 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | ||
389 | | SOUND_WAVE_BANK_SELECT(0) | ||
390 | | SOUND_WAVE_ENABLE; | ||
391 | SOUND_WAVE_CTRL = SOUND_WAVE_VOL_100; | ||
392 | SOUND_WAVE_FREQ = SOUND_FREQ_RESET | ||
362 | | sound_rates[active_note]; | 393 | | sound_rates[active_note]; |
363 | } | 394 | } |
364 | } | 395 | } |
@@ -752,7 +783,7 @@ init_sequencer_sprites(void) { | |||
752 | int base_tile = sprites[sprite_id].tile_start + 8; | 783 | int base_tile = sprites[sprite_id].tile_start + 8; |
753 | seq_sprites[53].id = obj_counter++; | 784 | seq_sprites[53].id = obj_counter++; |
754 | seq_sprites[53].base_tile = base_tile; | 785 | seq_sprites[53].base_tile = base_tile; |
755 | seq_sprites[53].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y) | OBJ_HIDDEN; | 786 | seq_sprites[53].obj_attr_0 = OBJ_SHAPE_WIDE | OBJ_Y_COORD(y); |
756 | seq_sprites[53].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); | 787 | seq_sprites[53].obj_attr_1 = OBJ_SIZE_MID | OBJ_X_COORD(x); |
757 | seq_sprites[53].obj_attr_2 = base_tile | OBJ_PAL_BANK(0); | 788 | seq_sprites[53].obj_attr_2 = base_tile | OBJ_PAL_BANK(0); |
758 | } | 789 | } |
@@ -1084,11 +1115,15 @@ handle_sequencer_input(void) { | |||
1084 | } else { | 1115 | } else { |
1085 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | 1116 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; |
1086 | SOUND_SQUARE1_CTRL = 0; | 1117 | SOUND_SQUARE1_CTRL = 0; |
1118 | SOUND_SQUARE2_CTRL = 0; | ||
1119 | SOUND_WAVE_CTRL = 0; | ||
1087 | } | 1120 | } |
1088 | } | 1121 | } |
1089 | if (key_pressed(KEY_SELECT)) { | 1122 | if (key_pressed(KEY_SELECT)) { |
1090 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; | 1123 | TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; |
1091 | SOUND_SQUARE1_CTRL = 0; | 1124 | SOUND_SQUARE1_CTRL = 0; |
1125 | SOUND_SQUARE2_CTRL = 0; | ||
1126 | SOUND_WAVE_CTRL = 0; | ||
1092 | } | 1127 | } |
1093 | } | 1128 | } |
1094 | 1129 | ||
@@ -1102,3 +1137,29 @@ render_sequencer_sprites(void) { | |||
1102 | OBJ_ATTR_2(id) = seq_sprites[i].obj_attr_2; | 1137 | OBJ_ATTR_2(id) = seq_sprites[i].obj_attr_2; |
1103 | } | 1138 | } |
1104 | } | 1139 | } |
1140 | |||
1141 | void init_sequencer() { | ||
1142 | init_sequencer_sprites(); | ||
1143 | SOUND_STATUS = SOUND_ENABLE; | ||
1144 | SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2 | SOUND_WAVE, 3); | ||
1145 | SOUND_DSOUND_MASTER = SOUND_DMG100; | ||
1146 | |||
1147 | // TODO: Currently static, need to figure out a way of controlling these | ||
1148 | // parameters. | ||
1149 | // Select bank 0 for writing (bank 1 playing). | ||
1150 | SOUND_WAVE_RAM_0 = 0xEFDEBC89; | ||
1151 | SOUND_WAVE_RAM_1 = 0x98CBEDFE; | ||
1152 | SOUND_WAVE_RAM_2 = 0x10214376; | ||
1153 | SOUND_WAVE_RAM_3 = 0x67341201; | ||
1154 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(1) | SOUND_WAVE_BANK_SELECT(1); | ||
1155 | |||
1156 | // SINE WAVE | ||
1157 | SOUND_WAVE_RAM_0 = 0xEFDEBC89; | ||
1158 | SOUND_WAVE_RAM_1 = 0x98CBEDFE; | ||
1159 | SOUND_WAVE_RAM_2 = 0x10214376; | ||
1160 | SOUND_WAVE_RAM_3 = 0x67341201; | ||
1161 | |||
1162 | // Select bank 0 for playing. | ||
1163 | SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | SOUND_WAVE_BANK_SELECT(0); | ||
1164 | SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE; | ||
1165 | } | ||