From c2edce15ca79b8a841c187fcacd184ee6c713b82 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 30 Apr 2021 11:56:31 +0200 Subject: Add fixed rates for all notes in the sound range From C2 to C8 --- src/common.h | 64 +++++++++++++++++++++++++++++++++++------------------ src/main.c | 72 ++++++++++++++++++------------------------------------------ 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) { #define SOUND_SQUARE_RESET (1 << 0xF) typedef enum { - NOTE_C, - NOTE_C_SHARP, - NOTE_D, - NOTE_D_SHARP, - NOTE_E, - NOTE_F, - NOTE_F_SHARP, - NOTE_G, - NOTE_G_SHARP, - NOTE_A, - NOTE_A_SHARP, - NOTE_B, + NOTE_C_2 , NOTE_C_SHARP_2 , NOTE_D_2 , NOTE_D_SHARP_2 , + NOTE_E_2 , NOTE_F_2 , NOTE_F_SHARP_2 , NOTE_G_2 , + NOTE_G_SHARP_2 , NOTE_A_2 , NOTE_A_SHARP_2 , NOTE_B_2 , + NOTE_C_3 , NOTE_C_SHARP_3 , NOTE_D_3 , NOTE_D_SHARP_3 , + NOTE_E_3 , NOTE_F_3 , NOTE_F_SHARP_3 , NOTE_G_3 , + NOTE_G_SHARP_3 , NOTE_A_3 , NOTE_A_SHARP_3 , NOTE_B_3 , + NOTE_C_4 , NOTE_C_SHARP_4 , NOTE_D_4 , NOTE_D_SHARP_4 , + NOTE_E_4 , NOTE_F_4 , NOTE_F_SHARP_4 , NOTE_G_4 , + NOTE_G_SHARP_4 , NOTE_A_4 , NOTE_A_SHARP_4 , NOTE_B_4 , + NOTE_C_5 , NOTE_C_SHARP_5 , NOTE_D_5 , NOTE_D_SHARP_5 , + NOTE_E_5 , NOTE_F_5 , NOTE_F_SHARP_5 , NOTE_G_5 , + NOTE_G_SHARP_5 , NOTE_A_5 , NOTE_A_SHARP_5 , NOTE_B_5 , + NOTE_C_6 , NOTE_C_SHARP_6 , NOTE_D_6 , NOTE_D_SHARP_6 , + NOTE_E_6 , NOTE_F_6 , NOTE_F_SHARP_6 , NOTE_G_6 , + NOTE_G_SHARP_6 , NOTE_A_6 , NOTE_A_SHARP_6 , NOTE_B_6 , + NOTE_C_7 , NOTE_C_SHARP_7 , NOTE_D_7 , NOTE_D_SHARP_7 , + NOTE_E_7 , NOTE_F_7 , NOTE_F_SHARP_7 , NOTE_G_7 , + NOTE_G_SHARP_7 , NOTE_A_7 , NOTE_A_SHARP_7 , NOTE_B_7 , + NOTE_C_8 } Note; -u32 -sound_rate(Note note, u32 octave) { - const u32 base_rate[12] = { - 8013, 7566, 7144, 6742, // C , C#, D , D# - 6362, 6005, 5666, 5346, // E , F , F#, G - 5048, 4766, 4499, 4246 // G#, A , A#, B - }; - return 2048 - (base_rate[note] >> (4 + octave)); -} +static char * note_names[] = { + "C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2", + "C3", "C#3", "D3", "D#3", "E3", "F3", "F#3", "G3", "G#3", "A3", "A#3", "B3", + "C4", "C#4", "D4", "D#4", "E4", "F4", "F#4", "G4", "G#4", "A4", "A#4", "B4", + "C5", "C#5", "D5", "D#5", "E5", "F5", "F#5", "G5", "G#5", "A5", "A#5", "B5", + "C6", "C#6", "D6", "D#6", "E6", "F6", "F#6", "G6", "G#6", "A6", "A#6", "B6", + "C7", "C#7", "D7", "D#7", "E7", "F7", "F#7", "G7", "G#7", "A7", "A#7", "B7", + "C8" +}; + +const u32 sound_rates[] = { + 44 , 156 , 262 , 363 , 457 , 547 , 631 , 710 , 785 , 856 , 923 , 986 , + 1046, 1102, 1155, 1205, 1252, 1297, 1339, 1379, 1416, 1452, 1485, 1517, + 1547, 1575, 1601, 1626, 1650, 1672, 1693, 1713, 1732, 1750, 1766, 1782, + 1797, 1811, 1824, 1837, 1849, 1860, 1870, 1880, 1890, 1899, 1907, 1915, + 1922, 1929, 1936, 1942, 1948, 1954, 1959, 1964, 1969, 1973, 1977, 1981, + 1985, 1988, 1992, 1995, 1998, 2001, 2003, 2006, 2008, 2010, 2012, 2014, + 2016, +}; // // Misc. @@ -638,4 +655,9 @@ wait_vsync(void) { while(DISP_VCOUNT < 160); } +// General utility functions. Min/Max/Clamp +#define MIN(A, B) ((A) <= (B) ? (A) : (B)) +#define MAX(A, B) ((A) >= (B) ? (A) : (B)) +#define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) + #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 @@ // TODO: Cleanup OBJ/OAM memory copying and access. // -// -// BIOS calls -// - -int hblank_counter = 0; - -void -irs_hblank_func() { - hblank_counter++; - if (DISP_VCOUNT >= 160) { - PAL_BUFFER_BG[0] = rgb15(0, 0, 0); - } else { - u16 clr = (DISP_VCOUNT / 8); - PAL_BUFFER_BG[0] = rgb15(clr, 0, 31 - clr); - } -} - int main(void) { // Configure the display in mode 0 to show OBJs, where tile memory is // sequential. @@ -46,24 +29,18 @@ int main(void) { // Register interrupts. irq_init(); irs_set(IRQ_VBLANK, irs_stub); - irs_set(IRQ_HBLANK, irs_hblank_func); // turn sound on SOUND_STATUS = SOUND_ENABLE; SOUND_DMG_MASTER = sound_volume(SOUND_SQUARE1 | SOUND_SQUARE2, 7); SOUND_DSOUND_MASTER = SOUND_DMG100; - char *note_names[] = { - "C" , "C#" , "D" , "D#" , - "E" , "F" , "F#" , "G" , - "G#" , "A" , "A#" , "B" - }; int frame_counter = 0; - Note active_note = NOTE_C; - u8 octave = 0; + Note active_note = NOTE_C_4; + int octave_diff = 0; bool playing = false; bool new_note = false; - u8 interval = 1; + u8 interval = 4; while(true) { bios_vblank_wait(); poll_keys(); @@ -72,49 +49,39 @@ int main(void) { txt_clear_line(); if (key_pressed(KEY_B)) { - active_note = NOTE_C; + active_note = NOTE_C_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_A)) { - active_note = NOTE_D; + active_note = NOTE_D_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_LEFT)) { - active_note = NOTE_E; + active_note = NOTE_E_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_DOWN)) { - active_note = NOTE_F; + active_note = NOTE_F_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_RIGHT)) { - active_note = NOTE_G; + active_note = NOTE_G_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_UP)) { - active_note = NOTE_A; + active_note = NOTE_A_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_L)) { - active_note = NOTE_B; + active_note = NOTE_B_4 + 12 * octave_diff; new_note = true; - octave = 0; } else if (key_pressed(KEY_R)) { - active_note = NOTE_C; + active_note = NOTE_C_5 + 12 * octave_diff; new_note = true; - octave = 1; } if (key_pressed(KEY_START)) { - interval++; + octave_diff = CLAMP(octave_diff + 1, -2, 3); } if (key_pressed(KEY_SELECT)) { - interval--; + octave_diff = CLAMP(octave_diff - 1, -2, 3); } if (key_curr > 0) { - txt_printf(" Playing: %s + %s\n", - note_names[active_note], - (note_names[(active_note + interval) % 12])); + txt_printf(" Playing: %s\n", note_names[active_note]); playing = true; } else { playing = false; @@ -122,10 +89,13 @@ int main(void) { if (playing) { if (new_note) { - SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(4) | SOUND_SQUARE_ENV_TIME(0); - SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(4) | SOUND_SQUARE_ENV_TIME(0); - SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rate(active_note, octave); - SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | sound_rate((active_note + interval) % 12, octave); + // SOUND_SQUARE1_SWEEP = 3 | (1 << 3) | (2 << 4); + // SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(0x7); + // SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(0); + SOUND_SQUARE1_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_ENV_INC | SOUND_SQUARE_DUTY(3); + // SOUND_SQUARE2_CTRL = SOUND_SQUARE_ENV_VOL(15) | SOUND_SQUARE_ENV_TIME(4) | SOUND_SQUARE_ENV_INC; + SOUND_SQUARE1_FREQ = SOUND_SQUARE_RESET | sound_rates[active_note]; + // SOUND_SQUARE2_FREQ = SOUND_SQUARE_RESET | sound_rate((active_note + interval) % 12, octave); } new_note = false; } else { -- cgit v1.2.1