summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-04-30 11:56:31 +0200
committerBad Diode <bd@badd10de.dev>2021-04-30 11:56:31 +0200
commitc2edce15ca79b8a841c187fcacd184ee6c713b82 (patch)
tree6bf0e6c7f7c993fb494ad7489f527c52db3ce821
parent3ec91ad217fb77ae1980b0b935e76307edf63ae1 (diff)
downloadgba-experiments-c2edce15ca79b8a841c187fcacd184ee6c713b82.tar.gz
gba-experiments-c2edce15ca79b8a841c187fcacd184ee6c713b82.zip
Add fixed rates for all notes in the sound range
From C2 to C8
-rw-r--r--src/common.h64
-rw-r--r--src/main.c72
2 files changed, 64 insertions, 72 deletions
diff --git a/src/common.h b/src/common.h
index 7a0c50c..e864a71 100644
--- a/src/common.h
+++ b/src/common.h
@@ -601,29 +601,46 @@ sound_volume(SoundChannel channels, u8 volume) {
601#define SOUND_SQUARE_RESET (1 << 0xF) 601#define SOUND_SQUARE_RESET (1 << 0xF)
602 602
603typedef enum { 603typedef enum {
604 NOTE_C, 604 NOTE_C_2 , NOTE_C_SHARP_2 , NOTE_D_2 , NOTE_D_SHARP_2 ,
605 NOTE_C_SHARP, 605 NOTE_E_2 , NOTE_F_2 , NOTE_F_SHARP_2 , NOTE_G_2 ,
606 NOTE_D, 606 NOTE_G_SHARP_2 , NOTE_A_2 , NOTE_A_SHARP_2 , NOTE_B_2 ,
607 NOTE_D_SHARP, 607 NOTE_C_3 , NOTE_C_SHARP_3 , NOTE_D_3 , NOTE_D_SHARP_3 ,
608 NOTE_E, 608 NOTE_E_3 , NOTE_F_3 , NOTE_F_SHARP_3 , NOTE_G_3 ,
609 NOTE_F, 609 NOTE_G_SHARP_3 , NOTE_A_3 , NOTE_A_SHARP_3 , NOTE_B_3 ,
610 NOTE_F_SHARP, 610 NOTE_C_4 , NOTE_C_SHARP_4 , NOTE_D_4 , NOTE_D_SHARP_4 ,
611 NOTE_G, 611 NOTE_E_4 , NOTE_F_4 , NOTE_F_SHARP_4 , NOTE_G_4 ,
612 NOTE_G_SHARP, 612 NOTE_G_SHARP_4 , NOTE_A_4 , NOTE_A_SHARP_4 , NOTE_B_4 ,
613 NOTE_A, 613 NOTE_C_5 , NOTE_C_SHARP_5 , NOTE_D_5 , NOTE_D_SHARP_5 ,
614 NOTE_A_SHARP, 614 NOTE_E_5 , NOTE_F_5 , NOTE_F_SHARP_5 , NOTE_G_5 ,
615 NOTE_B, 615 NOTE_G_SHARP_5 , NOTE_A_5 , NOTE_A_SHARP_5 , NOTE_B_5 ,
616 NOTE_C_6 , NOTE_C_SHARP_6 , NOTE_D_6 , NOTE_D_SHARP_6 ,
617 NOTE_E_6 , NOTE_F_6 , NOTE_F_SHARP_6 , NOTE_G_6 ,
618 NOTE_G_SHARP_6 , NOTE_A_6 , NOTE_A_SHARP_6 , NOTE_B_6 ,
619 NOTE_C_7 , NOTE_C_SHARP_7 , NOTE_D_7 , NOTE_D_SHARP_7 ,
620 NOTE_E_7 , NOTE_F_7 , NOTE_F_SHARP_7 , NOTE_G_7 ,
621 NOTE_G_SHARP_7 , NOTE_A_7 , NOTE_A_SHARP_7 , NOTE_B_7 ,
622 NOTE_C_8
616} Note; 623} Note;
617 624
618u32 625static char * note_names[] = {
619sound_rate(Note note, u32 octave) { 626 "C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2",
620 const u32 base_rate[12] = { 627 "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3",
621 8013, 7566, 7144, 6742, // C , C#, D , D# 628 "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4",
622 6362, 6005, 5666, 5346, // E , F , F#, G 629 "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5",
623 5048, 4766, 4499, 4246 // G#, A , A#, B 630 "C6", "C#6", "D6", "D#6", "E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6",
624 }; 631 "C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7", "G#7", "A7", "A#7", "B7",
625 return 2048 - (base_rate[note] >> (4 + octave)); 632 "C8"
626} 633};
634
635const u32 sound_rates[] = {
636 44 , 156 , 262 , 363 , 457 , 547 , 631 , 710 , 785 , 856 , 923 , 986 ,
637 1046, 1102, 1155, 1205, 1252, 1297, 1339, 1379, 1416, 1452, 1485, 1517,
638 1547, 1575, 1601, 1626, 1650, 1672, 1693, 1713, 1732, 1750, 1766, 1782,
639 1797, 1811, 1824, 1837, 1849, 1860, 1870, 1880, 1890, 1899, 1907, 1915,
640 1922, 1929, 1936, 1942, 1948, 1954, 1959, 1964, 1969, 1973, 1977, 1981,
641 1985, 1988, 1992, 1995, 1998, 2001, 2003, 2006, 2008, 2010, 2012, 2014,
642 2016,
643};
627 644
628// 645//
629// Misc. 646// Misc.
@@ -638,4 +655,9 @@ wait_vsync(void) {
638 while(DISP_VCOUNT < 160); 655 while(DISP_VCOUNT < 160);
639} 656}
640 657
658// General utility functions. Min/Max/Clamp
659#define MIN(A, B) ((A) <= (B) ? (A) : (B))
660#define MAX(A, B) ((A) >= (B) ? (A) : (B))
661#define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X))
662
641#endif // GBAEXP_COMMON_H 663#endif // GBAEXP_COMMON_H
diff --git a/src/main.c b/src/main.c
index 30452e1..8b36226 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,23 +13,6 @@
13// TODO: Cleanup OBJ/OAM memory copying and access. 13// TODO: Cleanup OBJ/OAM memory copying and access.
14// 14//
15 15
16//
17// BIOS calls
18//
19
20int hblank_counter = 0;
21
22void
23irs_hblank_func() {
24 hblank_counter++;
25 if (DISP_VCOUNT >= 160) {
26 PAL_BUFFER_BG[0] = rgb15(0, 0, 0);
27 } else {
28 u16 clr = (DISP_VCOUNT / 8);
29 PAL_BUFFER_BG[0] = rgb15(clr, 0, 31 - clr);
30 }
31}
32
33int main(void) { 16int main(void) {
34 // Configure the display in mode 0 to show OBJs, where tile memory is 17 // Configure the display in mode 0 to show OBJs, where tile memory is
35 // sequential. 18 // sequential.
@@ -46,24 +29,18 @@ int main(void) {
46 // Register interrupts. 29 // Register interrupts.
47 irq_init(); 30 irq_init();
48 irs_set(IRQ_VBLANK, irs_stub); 31 irs_set(IRQ_VBLANK, irs_stub);
49 irs_set(IRQ_HBLANK, irs_hblank_func);
50 32
51 // turn sound on 33 // turn sound on
52 SOUND_STATUS = SOUND_ENABLE; 34 SOUND_STATUS = SOUND_ENABLE;
53 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2, 7); 35 SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2, 7);
54 SOUND_DSOUND_MASTER = SOUND_DMG100; 36 SOUND_DSOUND_MASTER = SOUND_DMG100;
55 37
56 char *note_names[] = {
57 "C" , "C#" , "D" , "D#" ,
58 "E" , "F" , "F#" , "G" ,
59 "G#" , "A" , "A#" , "B"
60 };
61 int frame_counter = 0; 38 int frame_counter = 0;
62 Note active_note = NOTE_C; 39 Note active_note = NOTE_C_4;
63 u8 octave = 0; 40 int octave_diff = 0;
64 bool playing = false; 41 bool playing = false;
65 bool new_note = false; 42 bool new_note = false;
66 u8 interval = 1; 43 u8 interval = 4;
67 while(true) { 44 while(true) {
68 bios_vblank_wait(); 45 bios_vblank_wait();
69 poll_keys(); 46 poll_keys();
@@ -72,49 +49,39 @@ int main(void) {
72 txt_clear_line(); 49 txt_clear_line();
73 50
74 if (key_pressed(KEY_B)) { 51 if (key_pressed(KEY_B)) {
75 active_note = NOTE_C; 52 active_note = NOTE_C_4 + 12 * octave_diff;
76 new_note = true; 53 new_note = true;
77 octave = 0;
78 } else if (key_pressed(KEY_A)) { 54 } else if (key_pressed(KEY_A)) {
79 active_note = NOTE_D; 55 active_note = NOTE_D_4 + 12 * octave_diff;
80 new_note = true; 56 new_note = true;
81 octave = 0;
82 } else if (key_pressed(KEY_LEFT)) { 57 } else if (key_pressed(KEY_LEFT)) {
83 active_note = NOTE_E; 58 active_note = NOTE_E_4 + 12 * octave_diff;
84 new_note = true; 59 new_note = true;
85 octave = 0;
86 } else if (key_pressed(KEY_DOWN)) { 60 } else if (key_pressed(KEY_DOWN)) {
87 active_note = NOTE_F; 61 active_note = NOTE_F_4 + 12 * octave_diff;
88 new_note = true; 62 new_note = true;
89 octave = 0;
90 } else if (key_pressed(KEY_RIGHT)) { 63 } else if (key_pressed(KEY_RIGHT)) {
91 active_note = NOTE_G; 64 active_note = NOTE_G_4 + 12 * octave_diff;
92 new_note = true; 65 new_note = true;
93 octave = 0;
94 } else if (key_pressed(KEY_UP)) { 66 } else if (key_pressed(KEY_UP)) {
95 active_note = NOTE_A; 67 active_note = NOTE_A_4 + 12 * octave_diff;
96 new_note = true; 68 new_note = true;
97 octave = 0;
98 } else if (key_pressed(KEY_L)) { 69 } else if (key_pressed(KEY_L)) {
99 active_note = NOTE_B; 70 active_note = NOTE_B_4 + 12 * octave_diff;
100 new_note = true; 71 new_note = true;
101 octave = 0;
102 } else if (key_pressed(KEY_R)) { 72 } else if (key_pressed(KEY_R)) {
103 active_note = NOTE_C; 73 active_note = NOTE_C_5 + 12 * octave_diff;
104 new_note = true; 74 new_note = true;
105 octave = 1;
106 } 75 }
107 if (key_pressed(KEY_START)) { 76 if (key_pressed(KEY_START)) {
108 interval++; 77 octave_diff = CLAMP(octave_diff + 1, -2, 3);
109 } 78 }
110 if (key_pressed(KEY_SELECT)) { 79 if (key_pressed(KEY_SELECT)) {
111 interval--; 80 octave_diff = CLAMP(octave_diff - 1, -2, 3);
112 } 81 }
113 82
114 if (key_curr > 0) { 83 if (key_curr > 0) {
115 txt_printf(" Playing: %s + %s\n", 84 txt_printf(" Playing: %s\n", note_names[active_note]);
116 note_names[active_note],
117 (note_names[(active_note + interval) % 12]));
118 playing = true; 85 playing = true;
119 } else { 86 } else {
120 playing = false; 87 playing = false;
@@ -122,10 +89,13 @@ int main(void) {
122 89
123 if (playing) { 90 if (playing) {
124 if (new_note) { 91 if (new_note) {
125 SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(4) | SOUND_SQUARE_ENV_TIME(0); 92 // SOUND_SQUARE1_SWEEP = 3 | (1 << 3) | (2 << 4);
126 SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(4) | SOUND_SQUARE_ENV_TIME(0); 93 // SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(0x7);
127 SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rate(active_note, octave); 94 // SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(0);
128 SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | sound_rate((active_note + interval) % 12, octave); 95 SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_ENV_INC | SOUND_SQUARE_DUTY(3);
96 // SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_ENV_INC;
97 SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note];
98 // SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | sound_rate((active_note + interval) % 12, octave);
129 } 99 }
130 new_note = false; 100 new_note = false;
131 } else { 101 } else {