aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-03 12:29:48 +0200
committerBad Diode <bd@badd10de.dev>2023-04-03 12:29:48 +0200
commitd96f6da677bc319f7868e832f09948c94ee6a148 (patch)
treed22dc99df5a1fb4f4b9c24b9d43aeb85fef4a283
parent4a4e0f5d55caa5c56929f8505a6722eb1423e73f (diff)
downloadstepper-d96f6da677bc319f7868e832f09948c94ee6a148.tar.gz
stepper-d96f6da677bc319f7868e832f09948c94ee6a148.zip
Add noise channel with note support
-rw-r--r--src/gba/gba.h14
-rw-r--r--src/sequencer.c395
2 files changed, 395 insertions, 14 deletions
diff --git a/src/gba/gba.h b/src/gba/gba.h
index cdb3b31..b02d745 100644
--- a/src/gba/gba.h
+++ b/src/gba/gba.h
@@ -558,7 +558,7 @@ sound_volume(SoundChannel channels, u8 volume) {
558#define SOUND_SWEEP_DIR(N) ((N) << 0x3) 558#define SOUND_SWEEP_DIR(N) ((N) << 0x3)
559#define SOUND_SWEEP_TIME(N) ((N) << 0x4) 559#define SOUND_SWEEP_TIME(N) ((N) << 0x4)
560 560
561// DMG frequency bits (Square/Wave). 561// DMG frequency bits (Square/Wave/NOISE).
562#define SOUND_FREQ_TIMED (1 << 0xE) 562#define SOUND_FREQ_TIMED (1 << 0xE)
563#define SOUND_FREQ_RESET (1 << 0xF) 563#define SOUND_FREQ_RESET (1 << 0xF)
564 564
@@ -585,6 +585,18 @@ typedef u8 WaveBank[32];
585 585
586#define SOUND_WAVE_RAM ((WaveBank*)(MEM_IO + 0x90)) 586#define SOUND_WAVE_RAM ((WaveBank*)(MEM_IO + 0x90))
587 587
588// DMG noise control bits.
589#define SOUND_NOISE_LENGTH(N) (((N) & 0x3F) << 0)
590#define SOUND_NOISE_ENV_TIME(N) (((N) & 0x07) << 0x8)
591#define SOUND_NOISE_ENV_DIR(N) (((N) & 0x01) << 0xB)
592#define SOUND_NOISE_ENV_VOL(N) (((N) & 0x0F) << 0xC)
593
594// DMG noise freq bits.
595#define SOUND_NOISE_DIV_FREQ(N) (((N) & 0x07) << 0)
596#define SOUND_NOISE_COUNTER_STAGE(N) (((N) & 0x01) << 0x3)
597#define SOUND_NOISE_PRESTEP_FREQ(N) (((N) & 0x0F) << 0x4)
598#define SOUND_NOISE_TIMED_MODE(N) (((N) & 0x01) << 0xe)
599
588typedef enum { 600typedef enum {
589 NOTE_C_2 , NOTE_C_SHARP_2 , NOTE_D_2 , NOTE_D_SHARP_2 , 601 NOTE_C_2 , NOTE_C_SHARP_2 , NOTE_D_2 , NOTE_D_SHARP_2 ,
590 NOTE_E_2 , NOTE_F_2 , NOTE_F_SHARP_2 , NOTE_G_2 , 602 NOTE_E_2 , NOTE_F_2 , NOTE_F_SHARP_2 , NOTE_G_2 ,
diff --git a/src/sequencer.c b/src/sequencer.c
index 856d579..8c3f89a 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -1,6 +1,15 @@
1#include "rng.c" 1#include "rng.c"
2#include "text.h" 2#include "text.h"
3 3
4// TODO
5// - Preview sound keys
6// - Copy paste trigs/notes/params
7// - Different banks for storing patterns
8// - Buttons on the left side for selecting different patterns
9// - Pattern chaining or song mode
10// - Allow control BPM
11// - Finish noise channel
12
4// 13//
5// Color indexes. 14// Color indexes.
6// 15//
@@ -150,7 +159,7 @@ static int bpm = 115;
150static int step_counter = 0; 159static int step_counter = 0;
151int trig_selection_loc = 0; 160int trig_selection_loc = 0;
152int param_selection_loc = 0; 161int param_selection_loc = 0;
153int channel_selection_loc = 0; 162int channel_selection_loc = 3;
154 163
155typedef struct TriggerNote { 164typedef struct TriggerNote {
156 bool active; 165 bool active;
@@ -186,6 +195,11 @@ typedef struct ChannelWave {
186 ChannelWaveParams params[16]; 195 ChannelWaveParams params[16];
187} ChannelWave; 196} ChannelWave;
188 197
198typedef struct ChannelNoise {
199 bool active;
200 TriggerNote notes[16];
201} ChannelNoise;
202
189static ChannelSquare ch1 = { 203static ChannelSquare ch1 = {
190 .notes = { 204 .notes = {
191 {true, NOTE_C_4}, 205 {true, NOTE_C_4},
@@ -223,7 +237,7 @@ static ChannelSquare ch1 = {
223 {8, 4, 0, 2, 0, 0, 0}, 237 {8, 4, 0, 2, 0, 0, 0},
224 {8, 4, 0, 2, 0, 0, 0}, 238 {8, 4, 0, 2, 0, 0, 0},
225 }, 239 },
226 .active = true, 240 .active = false,
227}; 241};
228 242
229static ChannelSquare ch2 = { 243static ChannelSquare ch2 = {
@@ -263,7 +277,7 @@ static ChannelSquare ch2 = {
263 {8, 4, 0, 2, 0, 0, 0}, 277 {8, 4, 0, 2, 0, 0, 0},
264 {8, 4, 0, 2, 0, 0, 0}, 278 {8, 4, 0, 2, 0, 0, 0},
265 }, 279 },
266 .active = true, 280 .active = false,
267}; 281};
268 282
269static ChannelWave ch3 = { 283static ChannelWave ch3 = {
@@ -303,6 +317,29 @@ static ChannelWave ch3 = {
303 {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, 317 {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}},
304 {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}}, 318 {3, 0, {0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000},{0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, 0x00000000}},
305 }, 319 },
320 .active = false,
321};
322
323// TODO: Add default noise parameters data.
324static ChannelNoise ch4 = {
325 .notes = {
326 {true, 0},
327 {false, NOTE_D_4},
328 {false, NOTE_E_4},
329 {false, NOTE_F_4},
330 {false, NOTE_G_4},
331 {false, NOTE_A_4},
332 {false, NOTE_B_4},
333 {false, NOTE_C_5},
334 {false, NOTE_C_4},
335 {false, NOTE_C_4},
336 {false, NOTE_C_4},
337 {false, NOTE_C_4},
338 {false, NOTE_C_4},
339 {false, NOTE_C_4},
340 {false, NOTE_C_4},
341 {false, NOTE_C_4},
342 },
306 .active = true, 343 .active = true,
307}; 344};
308 345
@@ -313,7 +350,7 @@ static ChannelWave ch3 = {
313#define TRIG_W 15 350#define TRIG_W 15
314#define TRIG_H 24 351#define TRIG_H 24
315#define TRIG_START_X 64 352#define TRIG_START_X 64
316#define TRIG_START_Y 97 353#define TRIG_START_Y 92
317#define TRIG_OFFSET_X (TRIG_W + 3) 354#define TRIG_OFFSET_X (TRIG_W + 3)
318#define TRIG_OFFSET_Y (TRIG_H + 7) 355#define TRIG_OFFSET_Y (TRIG_H + 7)
319 356
@@ -341,6 +378,9 @@ draw_trigger(size_t chan, size_t i) {
341 case 2: { 378 case 2: {
342 trig = ch3.notes[i]; 379 trig = ch3.notes[i];
343 } break; 380 } break;
381 case 3: {
382 trig = ch4.notes[i];
383 } break;
344 } 384 }
345 if (trig.active) { 385 if (trig.active) {
346 size_t offset_x = TRIG_OFFSET_X * (i % 8); 386 size_t offset_x = TRIG_OFFSET_X * (i % 8);
@@ -388,7 +428,7 @@ draw_triggers(void) {
388#define CHAN_W 19 428#define CHAN_W 19
389#define CHAN_H 8 429#define CHAN_H 8
390#define CHAN_START_X 35 430#define CHAN_START_X 35
391#define CHAN_START_Y 97 431#define CHAN_START_Y 92
392#define CHAN_OFFSET_Y 12 432#define CHAN_OFFSET_Y 12
393 433
394void 434void
@@ -409,6 +449,9 @@ draw_channels(void) {
409 case 2: { 449 case 2: {
410 active = ch3.active; 450 active = ch3.active;
411 } break; 451 } break;
452 case 3: {
453 active = ch4.active;
454 } break;
412 } 455 }
413 u8 clr = active ? COL_FG : COL_GREY; 456 u8 clr = active ? COL_FG : COL_GREY;
414 size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y; 457 size_t y = CHAN_START_Y + i * CHAN_OFFSET_Y;
@@ -431,7 +474,7 @@ draw_channel_cursor(size_t i, u8 clr) {
431#define PIANO_W 170 474#define PIANO_W 170
432#define PIANO_H 20 475#define PIANO_H 20
433#define PIANO_START_X 35 476#define PIANO_START_X 35
434#define PIANO_START_Y 72 477#define PIANO_START_Y 65
435#define PIANO_NOTE_W 2 478#define PIANO_NOTE_W 2
436 479
437void 480void
@@ -571,7 +614,7 @@ draw_piano(void) {
571#define PARAMS_W 170 614#define PARAMS_W 170
572#define PARAMS_H 64 615#define PARAMS_H 64
573#define PARAMS_START_X 35 616#define PARAMS_START_X 35
574#define PARAMS_START_Y 8 617#define PARAMS_START_Y 1
575 618
576void 619void
577draw_params_cursor_wave(size_t i, u8 clr) { 620draw_params_cursor_wave(size_t i, u8 clr) {
@@ -629,6 +672,61 @@ draw_params_cursor_wave(size_t i, u8 clr) {
629} 672}
630 673
631void 674void
675draw_params_cursor_noise(size_t i, u8 clr) {
676 // u8 x_positions[] = {
677 // // 32 half bytes (Wave A).
678 // 0, 4, 8, 12, 16, 20, 24, 28,
679 // 34, 38, 42, 46, 50, 54, 58, 62,
680 // 0, 4, 8, 12, 16, 20, 24, 28,
681 // 34, 38, 42, 46, 50, 54, 58, 62,
682 // // 32 half bytes (Wave B).
683 // 70, 74, 78, 82, 86, 90, 94, 98,
684 // 104, 108, 112, 116, 120, 124, 128, 132,
685 // 70, 74, 78, 82, 86, 90, 94, 98,
686 // 104, 108, 112, 116, 120, 124, 128, 132,
687 // // Default wave A.
688 // 1, 18, 35, 52,
689 // // Default wave B.
690 // 71, 88, 105, 122,
691 // // Mode selection.
692 // 141,
693 // // Volume selection.
694 // 141,
695 // };
696 // u8 y_positions[] = {
697 // // 32 half bytes (Wave A)
698 // 0, 0, 0, 0, 0, 0, 0, 0,
699 // 0, 0, 0, 0, 0, 0, 0, 0,
700 // 8, 8, 8, 8, 8, 8, 8, 8,
701 // 8, 8, 8, 8, 8, 8, 8, 8,
702 // // 32 half bytes (Wave B)
703 // 0, 0, 0, 0, 0, 0, 0, 0,
704 // 0, 0, 0, 0, 0, 0, 0, 0,
705 // 8, 8, 8, 8, 8, 8, 8, 8,
706 // 8, 8, 8, 8, 8, 8, 8, 8,
707 // // Default wave A.
708 // 20, 20, 20, 20,
709 // // Default wave B.
710 // 20, 20, 20, 20,
711 // // Mode selection.
712 // 20,
713 // // Volume selection.
714 // 0,
715 // };
716 // size_t cursor_length = 0;
717 // if (i < 64) {
718 // cursor_length = 4;
719 // } else if (i < 72) {
720 // cursor_length = 13;
721 // } else {
722 // cursor_length = 30;
723 // }
724 // size_t x = PARAMS_START_X + x_positions[i] - 1;
725 // size_t y = PARAMS_START_Y + PARAMS_H - 23 + y_positions[i];
726 // draw_line(x, y, x + cursor_length, y, clr);
727}
728
729void
632draw_params_cursor_square(size_t i, u8 clr, bool sweep) { 730draw_params_cursor_square(size_t i, u8 clr, bool sweep) {
633 size_t x_offset = sweep ? 0 : 30; 731 size_t x_offset = sweep ? 0 : 30;
634 u8 x_positions[] = { 732 u8 x_positions[] = {
@@ -668,6 +766,7 @@ draw_params_cursor(size_t i, u8 clr) {
668 draw_params_cursor_wave(i, clr); 766 draw_params_cursor_wave(i, clr);
669 } break; 767 } break;
670 case 3: { 768 case 3: {
769 draw_params_cursor_noise(i, clr);
671 } break; 770 } break;
672 } 771 }
673} 772}
@@ -814,7 +913,7 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep) {
814 // Shape drawing. 913 // Shape drawing.
815 { 914 {
816 size_t x = PARAMS_START_X + x_offset; 915 size_t x = PARAMS_START_X + x_offset;
817 size_t y = PARAMS_START_Y + PARAMS_H - 43; 916 size_t y = PARAMS_START_Y + PARAMS_H - 44;
818 917
819 size_t x0 = x + 2; 918 size_t x0 = x + 2;
820 size_t x1 = x0; 919 size_t x1 = x0;
@@ -904,14 +1003,14 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep) {
904 // Bounding box. 1003 // Bounding box.
905 { 1004 {
906 size_t x0 = PARAMS_START_X + 31 + x_offset; 1005 size_t x0 = PARAMS_START_X + 31 + x_offset;
907 size_t y0 = PARAMS_START_Y + PARAMS_H - 46; 1006 size_t y0 = PARAMS_START_Y + PARAMS_H - 47;
908 size_t x1 = x0 + 79; 1007 size_t x1 = x0 + 79;
909 size_t y1 = y0 + 21; 1008 size_t y1 = y0 + 21;
910 draw_rect(x0, y0, x1, y1, COL_CYAN); 1009 draw_rect(x0, y0, x1, y1, COL_CYAN);
911 } 1010 }
912 1011
913 size_t x = PARAMS_START_X + 42 + x_offset; 1012 size_t x = PARAMS_START_X + 42 + x_offset;
914 size_t y = PARAMS_START_Y + PARAMS_H - 43; 1013 size_t y = PARAMS_START_Y + PARAMS_H - 44;
915 size_t x0 = x; 1014 size_t x0 = x;
916 size_t y0 = y + 15 - params->env_volume; 1015 size_t y0 = y + 15 - params->env_volume;
917 size_t x1 = x + 8 * params->env_time; 1016 size_t x1 = x + 8 * params->env_time;
@@ -1158,7 +1257,7 @@ draw_parameters_square(ChannelSquareParams *params, bool sweep) {
1158 // Labels. 1257 // Labels.
1159 { 1258 {
1160 size_t x = PARAMS_START_X + x_offset; 1259 size_t x = PARAMS_START_X + x_offset;
1161 size_t y = PARAMS_START_Y + PARAMS_H - 43; 1260 size_t y = PARAMS_START_Y + PARAMS_H - 45;
1162 txt_drawf_small("shape", x + 1, y - 12, 4, COL_FG); 1261 txt_drawf_small("shape", x + 1, y - 12, 4, COL_FG);
1163 txt_drawf_small("envelope", x + 54, y - 12, 4, COL_FG); 1262 txt_drawf_small("envelope", x + 54, y - 12, 4, COL_FG);
1164 if (sweep) { 1263 if (sweep) {
@@ -1272,6 +1371,83 @@ irq_timer(void) {
1272 SOUND_WAVE_CTRL = 0; 1371 SOUND_WAVE_CTRL = 0;
1273 SOUND_WAVE_FREQ = 0; 1372 SOUND_WAVE_FREQ = 0;
1274 } 1373 }
1374 if (ch4.active) {
1375 TriggerNote *trig = &ch4.notes[step_counter];
1376 // ChannelNoiseParams *params = &ch4.params[step_counter];
1377 if (trig->active) {
1378 // switch (params->wave_mode) {
1379 // case 0: {
1380 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1);
1381 // memcpy32(SOUND_WAVE_RAM, params->wave_a, 16);
1382 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0)
1383 // | SOUND_WAVE_BANK_SELECT(0);
1384 // } break;
1385 // case 1: {
1386 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
1387 // memcpy32(SOUND_WAVE_RAM, params->wave_b, 16);
1388 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0)
1389 // | SOUND_WAVE_BANK_SELECT(1);
1390 // } break;
1391 // case 2: {
1392 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
1393 // memcpy32(SOUND_WAVE_RAM, params->wave_b, 16);
1394 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1);
1395 // memcpy32(SOUND_WAVE_RAM, params->wave_a, 16);
1396 // SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(1)
1397 // | SOUND_WAVE_BANK_SELECT(0);
1398 // } break;
1399 // }
1400 // SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE;
1401
1402 // switch (params->wave_volume) {
1403 // case 0: {
1404 // SOUND_WAVE_CTRL = SOUND_WAVE_MUTE;
1405 // } break;
1406 // case 1: {
1407 // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_25;
1408 // } break;
1409 // case 2: {
1410 // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_50;
1411 // } break;
1412 // case 3: {
1413 // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_75;
1414 // } break;
1415 // case 4: {
1416 // SOUND_WAVE_CTRL = SOUND_WAVE_VOL_100;
1417 // } break;
1418 // }
1419 static const u8 div_freq[] = {
1420 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
1421 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
1422 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
1423 7, 6, 5, 4, 7, 6, 5, 4, 7, 6, 5, 4,
1424 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0,
1425 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1426 };
1427 static const u8 pre_freq[] = {
1428 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11,
1429 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8,
1430 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5,
1431 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2,
1432 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1433 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1434 };
1435 SOUND_NOISE_CTRL = SOUND_NOISE_ENV_VOL(0xF)
1436 | SOUND_NOISE_ENV_TIME(0x2)
1437 | SOUND_NOISE_ENV_DIR(0)
1438 | SOUND_NOISE_LENGTH(50);
1439 SOUND_NOISE_FREQ = SOUND_FREQ_RESET
1440 | SOUND_NOISE_PRESTEP_FREQ(pre_freq[trig->note])
1441 | SOUND_NOISE_DIV_FREQ(div_freq[trig->note])
1442 | SOUND_NOISE_COUNTER_STAGE(0)
1443 | SOUND_NOISE_TIMED_MODE(0);
1444 } else {
1445 SOUND_NOISE_FREQ = 0;
1446 }
1447 } else {
1448 SOUND_NOISE_CTRL = 0;
1449 SOUND_NOISE_FREQ = 0;
1450 }
1275 step_counter = (step_counter + 1) % 16; 1451 step_counter = (step_counter + 1) % 16;
1276} 1452}
1277 1453
@@ -1301,6 +1477,9 @@ get_current_trig(void) {
1301 case 2: { 1477 case 2: {
1302 return &ch3.notes[trig_selection_loc]; 1478 return &ch3.notes[trig_selection_loc];
1303 } break; 1479 } break;
1480 case 3: {
1481 return &ch4.notes[trig_selection_loc];
1482 } break;
1304 } 1483 }
1305 return NULL; 1484 return NULL;
1306} 1485}
@@ -1310,13 +1489,14 @@ get_current_trig(void) {
1310// selection. 1489// selection.
1311void (*input_handler)(void); 1490void (*input_handler)(void);
1312 1491
1313#define SEQ_N_CHANNELS 3 1492#define SEQ_N_CHANNELS 4
1314 1493
1315void handle_trigger_selection(void); 1494void handle_trigger_selection(void);
1316void handle_channel_selection(void); 1495void handle_channel_selection(void);
1317void handle_param_selection_sq1(void); 1496void handle_param_selection_sq1(void);
1318void handle_param_selection_sq2(void); 1497void handle_param_selection_sq2(void);
1319void handle_param_selection_wave(void); 1498void handle_param_selection_wave(void);
1499void handle_param_selection_noise(void);
1320 1500
1321void 1501void
1322handle_channel_selection(void) { 1502handle_channel_selection(void) {
@@ -1331,6 +1511,9 @@ handle_channel_selection(void) {
1331 case 2: { 1511 case 2: {
1332 ch3.active ^= 1; 1512 ch3.active ^= 1;
1333 } break; 1513 } break;
1514 case 3: {
1515 ch4.active ^= 1;
1516 } break;
1334 } 1517 }
1335 draw_channels(); 1518 draw_channels();
1336 } 1519 }
@@ -1683,6 +1866,181 @@ handle_param_selection_wave(void) {
1683} 1866}
1684 1867
1685void 1868void
1869handle_param_selection_noise(void) {
1870 // Go back to trigger selection.
1871 // if (key_tap(KEY_A)) {
1872 // draw_params_cursor(param_selection_loc, COL_BG);
1873 // input_handler = handle_trigger_selection;
1874 // draw_trig_cursor(trig_selection_loc, COL_CURSOR);
1875 // }
1876
1877 // // Cursor movement.
1878 // if (key_tap(KEY_LEFT) || key_tap(KEY_RIGHT)) {
1879 // int inc = 0;
1880 // int loc = param_selection_loc;
1881 // if (key_tap(KEY_RIGHT)) {
1882 // if (loc == 15 || loc == 31) {
1883 // inc = 17;
1884 // } else if (loc == 47) {
1885 // inc = 26;
1886 // } else if (loc == 63) {
1887 // inc = 9;
1888 // } else if (loc != 47 && loc != 63 && loc < 72) {
1889 // inc = 1;
1890 // }
1891 // } else {
1892 // if (loc == 32 || loc == 48) {
1893 // inc = -17;
1894 // } else if (loc == 73) {
1895 // inc = -26;
1896 // } else if (loc != 16 && loc != 64) {
1897 // inc = -1;
1898 // }
1899 // }
1900 // draw_params_cursor(param_selection_loc, COL_BG);
1901 // param_selection_loc = CLAMP(loc + inc, 0, 73);
1902 // draw_params_cursor(param_selection_loc, COL_CURSOR);
1903 // }
1904 // if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) {
1905 // int inc = 0;
1906 // int loc = param_selection_loc;
1907 // if (key_tap(KEY_UP)) {
1908 // if ((loc >= 16 && loc < 32) || (loc >= 48 && loc < 64)) {
1909 // inc = -16;
1910 // } else if (loc == 64) {
1911 // inc = -48;
1912 // } else if (loc == 65) {
1913 // inc = -45;
1914 // } else if (loc == 66) {
1915 // inc = -42;
1916 // } else if (loc == 67) {
1917 // inc = -39;
1918 // } else if (loc == 68) {
1919 // inc = -20;
1920 // } else if (loc == 69) {
1921 // inc = -17;
1922 // } else if (loc == 70) {
1923 // inc = -14;
1924 // } else if (loc == 71) {
1925 // inc = -11;
1926 // } else if (loc == 72) {
1927 // inc = 1;
1928 // } else if (loc == 73) {
1929 // inc = -1;
1930 // }
1931 // } else {
1932 // if (loc < 16 || (loc >= 32 && loc < 48)) {
1933 // inc = 16;
1934 // } else if (loc >= 16 && loc <= 19) {
1935 // inc = 48 - (loc - 16);
1936 // } else if (loc >= 20 && loc <= 23) {
1937 // inc = 45 - (loc - 20);
1938 // } else if (loc >= 24 && loc <= 27) {
1939 // inc = 42 - (loc - 24);
1940 // } else if (loc >= 28 && loc <= 31) {
1941 // inc = 39 - (loc - 28);
1942 // } else if (loc >= 48 && loc <= 51) {
1943 // inc = 20 - (loc - 48);
1944 // } else if (loc >= 52 && loc <= 55) {
1945 // inc = 17 - (loc - 52);
1946 // } else if (loc >= 56 && loc <= 59) {
1947 // inc = 14 - (loc - 56);
1948 // } else if (loc >= 60 && loc <= 63) {
1949 // inc = 11 - (loc - 60);
1950 // } else if (loc == 72) {
1951 // inc = 1;
1952 // } else if (loc == 73) {
1953 // inc = -1;
1954 // }
1955 // }
1956 // draw_params_cursor(param_selection_loc, COL_BG);
1957 // param_selection_loc = CLAMP(loc + inc, 0, 73);
1958 // draw_params_cursor(param_selection_loc, COL_CURSOR);
1959 // }
1960
1961 // // Adjust parameter.
1962 // if (key_tap(KEY_R) || key_tap(KEY_L)) {
1963 // int odd = param_selection_loc & 0x1;
1964 // int inc;
1965 // if (key_tap(KEY_R)) {
1966 // inc = 1;
1967 // } else {
1968 // inc = -1;
1969 // }
1970
1971 // // Wave: AA BB CC DD ...
1972 // // ^^
1973 // // |`- odd
1974 // // `-- even
1975 // if (param_selection_loc < 32) {
1976 // // Draw on wave a.
1977 // u8 byte_number = param_selection_loc / 2;
1978 // u8 *byte = &ch3.params[trig_selection_loc].wave_a;
1979 // byte += byte_number;
1980 // if (odd) {
1981 // *byte = (~0xF & *byte) | ((*byte + inc) & 0xF);
1982 // } else {
1983 // *byte = (0xF & *byte) | (((*byte >> 4) + inc) & 0xF) << 4;
1984 // }
1985 // } else if (param_selection_loc < 64){
1986 // // Draw on wave b.
1987 // u8 byte_number = (param_selection_loc - 32) / 2;
1988 // u8 *byte = &ch3.params[trig_selection_loc].wave_b;
1989 // byte += byte_number;
1990 // if (odd) {
1991 // *byte = (~0xF & *byte) | ((*byte + inc) & 0xF);
1992 // } else {
1993 // *byte = (0xF & *byte) | (((*byte >> 4) + inc) & 0xF) << 4;
1994 // }
1995 // } else if (param_selection_loc < 72) {
1996 // // Copy default waves.
1997 // u32 *wave_a = &ch3.params[trig_selection_loc].wave_a;
1998 // u32 *wave_b = &ch3.params[trig_selection_loc].wave_b;
1999 // switch (param_selection_loc) {
2000 // case 64: {
2001 // memcpy32(wave_a, sine_wave, 16);
2002 // } break;
2003 // case 65: {
2004 // memcpy32(wave_a, saw_wave, 16);
2005 // } break;
2006 // case 66: {
2007 // memcpy32(wave_a, square_wave, 16);
2008 // } break;
2009 // case 67: {
2010 // u32 rand_wave[4] = {
2011 // rng32(), rng32(), rng32(), rng32(),
2012 // };
2013 // memcpy32(wave_a, rand_wave, 16);
2014 // } break;
2015 // case 68: {
2016 // memcpy32(wave_b, sine_wave, 16);
2017 // } break;
2018 // case 69: {
2019 // memcpy32(wave_b, saw_wave, 16);
2020 // } break;
2021 // case 70: {
2022 // memcpy32(wave_b, square_wave, 16);
2023 // } break;
2024 // case 71: {
2025 // u32 rand_wave[4] = {
2026 // rng32(), rng32(), rng32(), rng32(),
2027 // };
2028 // memcpy32(wave_b, rand_wave, 16);
2029 // } break;
2030 // }
2031 // } else if (param_selection_loc == 72) {
2032 // u8 *wave_mode = &ch3.params[trig_selection_loc].wave_mode;
2033 // *wave_mode = CLAMP(*wave_mode + inc, 0, 2);
2034 // } else if (param_selection_loc == 73) {
2035 // u8 *wave_volume = &ch3.params[trig_selection_loc].wave_volume;
2036 // *wave_volume = CLAMP(*wave_volume + inc, 0, 4);
2037 // }
2038 // draw_parameters();
2039 // draw_params_cursor(param_selection_loc, COL_CURSOR);
2040 // }
2041}
2042
2043void
1686handle_trigger_selection(void) { 2044handle_trigger_selection(void) {
1687 TriggerNote *trig = get_current_trig(); 2045 TriggerNote *trig = get_current_trig();
1688 2046
@@ -1758,6 +2116,9 @@ handle_trigger_selection(void) {
1758 case 2: { 2116 case 2: {
1759 input_handler = handle_param_selection_wave; 2117 input_handler = handle_param_selection_wave;
1760 } break; 2118 } break;
2119 case 3: {
2120 input_handler = handle_param_selection_noise;
2121 } break;
1761 } 2122 }
1762 draw_params_cursor(param_selection_loc, COL_CURSOR); 2123 draw_params_cursor(param_selection_loc, COL_CURSOR);
1763 draw_trig_cursor(trig_selection_loc, COL_CURRENT_TRIG); 2124 draw_trig_cursor(trig_selection_loc, COL_CURRENT_TRIG);
@@ -1779,6 +2140,7 @@ handle_sequencer_input(void) {
1779 SOUND_SQUARE1_CTRL = 0; 2140 SOUND_SQUARE1_CTRL = 0;
1780 SOUND_SQUARE2_CTRL = 0; 2141 SOUND_SQUARE2_CTRL = 0;
1781 SOUND_WAVE_CTRL = 0; 2142 SOUND_WAVE_CTRL = 0;
2143 SOUND_NOISE_CTRL = 0;
1782 } 2144 }
1783 } else if (key_tap(KEY_SELECT)) { 2145 } else if (key_tap(KEY_SELECT)) {
1784 // Play/pause. 2146 // Play/pause.
@@ -1786,6 +2148,7 @@ handle_sequencer_input(void) {
1786 SOUND_SQUARE1_CTRL = 0; 2148 SOUND_SQUARE1_CTRL = 0;
1787 SOUND_SQUARE2_CTRL = 0; 2149 SOUND_SQUARE2_CTRL = 0;
1788 SOUND_WAVE_CTRL = 0; 2150 SOUND_WAVE_CTRL = 0;
2151 SOUND_NOISE_CTRL = 0;
1789 } 2152 }
1790} 2153}
1791 2154
@@ -1808,6 +2171,9 @@ sequencer_init(void) {
1808 TriggerNote *trig = get_current_trig(); 2171 TriggerNote *trig = get_current_trig();
1809 draw_note(trig->note, COL_NOTE_PRESSED); 2172 draw_note(trig->note, COL_NOTE_PRESSED);
1810 2173
2174 // Draw screen border frame.
2175 draw_rect(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 1);
2176
1811 // Initialize input handler. 2177 // Initialize input handler.
1812 input_handler = handle_trigger_selection; 2178 input_handler = handle_trigger_selection;
1813 draw_trig_cursor(trig_selection_loc, COL_CURSOR); 2179 draw_trig_cursor(trig_selection_loc, COL_CURSOR);
@@ -1818,6 +2184,9 @@ sequencer_init(void) {
1818 SOUND_STATUS = SOUND_ENABLE; 2184 SOUND_STATUS = SOUND_ENABLE;
1819 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 2185 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1
1820 | SOUND_SQUARE2 2186 | SOUND_SQUARE2
1821 | SOUND_WAVE, 3); 2187 | SOUND_WAVE
2188 | SOUND_NOISE, 3);
1822 SOUND_DSOUND_MASTER = SOUND_DMG25; 2189 SOUND_DSOUND_MASTER = SOUND_DMG25;
2190 // SOUND_NOISE_CTRL = SOUND_NOISE_ENV_VOL(0x8) | SOUND_NOISE_ENV_TIME(0) | SOUND_NOISE_ENV_DIR(1) | 0x4;
2191 // SOUND_NOISE_FREQ = SOUND_FREQ_RESET | SOUND_NOISE_PRESTEP_FREQ(0x7) | SOUND_NOISE_DIV_FREQ(2) | SOUND_NOISE_COUNTER_STAGE(1);
1823} 2192}