From e0e6acfb7b88e48a749d28f2f8621675bfce7081 Mon Sep 17 00:00:00 2001 From: mesheets <16882600+mesheets@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:45:52 -0400 Subject: [PATCH] Sound and Music updates for Issue #6 --- demo/c/music.c | 81 ++++++++++++++++++++++++------------------------ demo/c/sound.c | 58 ++++++++++++++++++++++++++++++++++ include/dmusic.h | 4 +-- include/dsound.h | 2 +- kernel/dsound.c | 34 +++++++++----------- 5 files changed, 117 insertions(+), 62 deletions(-) diff --git a/demo/c/music.c b/demo/c/music.c index 48f5db6..df34b66 100644 --- a/demo/c/music.c +++ b/demo/c/music.c @@ -35,50 +35,50 @@ static const note_t amazing_grace[] = { { PITCH_TEMPO, TEMPO_FROM_BPM(QUARTER, 90) }, { PITCH_INTERNOTE, DSOUND_DEFAULT_internote_ms }, - { PITCH_D4, QUARTER }, - { PITCH_G4, HALF }, - { PITCH_B4, EIGHTH }, - { PITCH_G4, EIGHTH }, - { PITCH_B4, HALF }, - { PITCH_A4, QUARTER }, - { PITCH_G4, HALF }, - { PITCH_E4, QUARTER }, - { PITCH_D4, HALF }, - - { PITCH_D4, QUARTER }, - { PITCH_G4, HALF }, - { PITCH_B4, EIGHTH }, - { PITCH_G4, EIGHTH }, - { PITCH_B4, HALF }, - { PITCH_A4, QUARTER }, - { PITCH_D3, HALF_DOTTED + QUARTER }, // Tied note + { PITCH_D3, QUARTER }, + { PITCH_G3, HALF }, + { PITCH_B3, EIGHTH }, + { PITCH_G3, EIGHTH }, + { PITCH_B3, HALF }, + { PITCH_A3, QUARTER }, + { PITCH_G3, HALF }, + { PITCH_E3, QUARTER }, + { PITCH_D3, HALF }, + + { PITCH_D3, QUARTER }, + { PITCH_G3, HALF }, + { PITCH_B3, EIGHTH }, + { PITCH_G3, EIGHTH }, + { PITCH_B3, HALF }, + { PITCH_A3, QUARTER }, + { PITCH_D4, HALF_DOTTED + QUARTER }, // Tied note { PITCH_REST, QUARTER }, - { PITCH_B4, QUARTER }, - { PITCH_D3, QUARTER_DOTTED }, - { PITCH_B4, EIGHTH }, - { PITCH_D3, EIGHTH }, - { PITCH_B4, EIGHTH }, - { PITCH_G4, HALF }, - - { PITCH_D4, QUARTER }, - { PITCH_E4, QUARTER_DOTTED }, - { PITCH_G4, EIGHTH }, - { PITCH_G4, EIGHTH }, - { PITCH_E4, EIGHTH }, - { PITCH_D4, HALF }, - - { PITCH_D4, QUARTER }, - { PITCH_G4, HALF }, - { PITCH_B4, EIGHTH }, - { PITCH_G4, EIGHTH }, - { PITCH_B4, HALF }, - { PITCH_A4, QUARTER }, - { PITCH_G4, HALF_DOTTED }, + { PITCH_B3, QUARTER }, + { PITCH_D4, QUARTER_DOTTED }, + { PITCH_B3, EIGHTH }, + { PITCH_D4, EIGHTH }, + { PITCH_B3, EIGHTH }, + { PITCH_G3, HALF }, + + { PITCH_D3, QUARTER }, + { PITCH_E3, QUARTER_DOTTED }, + { PITCH_G3, EIGHTH }, + { PITCH_G3, EIGHTH }, + { PITCH_E3, EIGHTH }, + { PITCH_D3, HALF }, + + { PITCH_D3, QUARTER }, + { PITCH_G3, HALF }, + { PITCH_B3, EIGHTH }, + { PITCH_G3, EIGHTH }, + { PITCH_B3, HALF }, + { PITCH_A3, QUARTER }, + { PITCH_G3, HALF_DOTTED }, // Slowly repeat the last phrase - { PITCH_TEMPO, TEMPO_FROM_BPM(QUARTER, 80) }, + { PITCH_TEMPO, TEMPO_FROM_BPM(QUARTER, 60) }, { PITCH_REPEAT, 1 }, // Number of times to repeat { 0, 8 }, // Number of array elements to repeat, // expressed as two unsigned byte values that will @@ -94,7 +94,7 @@ int main(int argc,char *argv[]) { for(i = 2; i <=6; i++) { intro_ms += amazing_grace[i].length; } - intro_ms = (intro_ms * amazing_grace[0].length) + ((6-2) * amazing_grace[1].length); + intro_ms = (intro_ms * amazing_grace[0].length); // Play the melody in a loop for(i = 0; !shutdown_requested(); i++) { @@ -107,6 +107,7 @@ int main(int argc,char *argv[]) { // Alternate whether to play the full song or just the intro if (i & 0x01) { dsound_wait(); + sleep(1); } else { #ifdef CONF_CONIO cputc_native_5(CHAR_DASH); diff --git a/demo/c/sound.c b/demo/c/sound.c index 7922252..16edc62 100644 --- a/demo/c/sound.c +++ b/demo/c/sound.c @@ -30,9 +30,25 @@ #include #endif +static note_t chromatic_scale[] = { + { PITCH_TEMPO, TEMPO_FROM_BPM(QUARTER, 120) }, + { PITCH_INTERNOTE, DSOUND_DEFAULT_internote_ms }, + + { PITCH_A0, QUARTER }, + + { PITCH_REPEAT, PITCH_MAX }, // Number of times to repeat + { 0, 1 }, // Number of array elements to repeat, + // expressed as two unsigned byte values that will + // be read as a single, unsigned two-byte value + + { PITCH_END, 0 } +}; + int main(int argc,char *argv[]) { // Play each of the system sounds + // NOTE: these are manually defined and not the actual sounds in ROM + // c.f. https://mralligator.com/rcx/ - ROM 327c, code 1772 unsigned char i; for (i = 0; i < DSOUND_SYS_MAX; i++) { #ifdef CONF_CONIO @@ -54,6 +70,48 @@ int main(int argc,char *argv[]) { sleep(1); } + + // Play the full, available chromatic scale + i = 1; + +#ifdef CONF_CONIO + // Display a music note on the LCD (quarter note) + dlcd_show(LCD_4_DOT); + dlcd_show(LCD_3_BOTL); + + // Update and show the note number + cputc_hex_1(i); +#endif // CONF_CONIO + + int note_duration_ms = chromatic_scale[2].length * chromatic_scale[0].length; + + dsound_play(chromatic_scale); + msleep(chromatic_scale[1].length); // Internote duration + + for (i = 2; i <= PITCH_MAX; i++) { + // Update the chromatic scale data structure on the fly + // (NOTE: Really shouldn't attempt this for normal dsound_play() use) + chromatic_scale[2].pitch = i; + msleep(note_duration_ms); +#ifdef CONF_CONIO + cputc_hex_1(i % 10); + cputc_hex_2(i / 10); +#endif // CONF_CONIO + } + + // End of loop; wait for playing to stop +#ifdef CONF_CONIO + cputc_native_5(CHAR_DASH); +#endif // CONF_CONIO + + dsound_wait(); + +#ifdef CONF_CONIO + cls(); +#endif // CONF_CONIO + + sleep(1); + return 0; } #else diff --git a/include/dmusic.h b/include/dmusic.h index 123a92f..719ffd9 100644 --- a/include/dmusic.h +++ b/include/dmusic.h @@ -257,9 +257,9 @@ extern "C" { //@} //! maximum pitch value -#define PITCH_MAX 98 +#define PITCH_MAX 97 -//! repeat last {note->length} notes +//! repeat last {note->length} times {number} notes //! PITCH_REPEAT is a two-element sequence: //! The length value of the first element is the number of times to repeat //! The second element is the number of array elements to repeat, expressed as diff --git a/include/dsound.h b/include/dsound.h index ffe2166..1eb85e8 100644 --- a/include/dsound.h +++ b/include/dsound.h @@ -55,7 +55,7 @@ extern "C" { /// /// The last entry in the list should have the {pitch} value set to \ref PITCH_END /// -/// Rests should be specified by placing \ref PITCH_PAUSE in the {pitch} value. +/// Rests should be specified by placing \ref PITCH_REST in the {pitch} value. /// The duration of the rest is placed in {length}. typedef struct { unsigned char pitch; //!< note pitch: 0 = rest, 1 ^= A_0 (~55 Hz) diff --git a/kernel/dsound.c b/kernel/dsound.c index 637b2f9..5c435c0 100644 --- a/kernel/dsound.c +++ b/kernel/dsound.c @@ -47,20 +47,16 @@ /////////////////////////////////////////////////////////////////////////////// //! note pitch -> frequency generator lookup table, index 0 = rest and 1 ^= A0 -static const unsigned pitch2freq[]={ - 0x0000, 0x8d03, 0x8603, 0x7d03, 0x7703, 0x7003, 0x6a03, 0x6303, - 0x5e03, 0x5903, 0x5403, 0x4f03, 0x4a03, 0x4603, 0x4203, 0xfd83, - 0xee83, 0xe083, 0xd483, 0xc783, 0xbc83, 0xb283, 0xa883, 0x9e83, - 0x9583, 0x8d83, 0x8583, 0x7e83, 0x7683, 0x7083, 0x6983, 0x6383, - 0x5e83, 0x5983, 0x5383, 0x4f83, 0x4a83, 0x4683, 0x4283, 0xfc02, - 0xee02, 0xe102, 0xd402, 0xc802, 0xbd02, 0xb202, 0xa802, 0x9e02, - 0x9502, 0x8d02, 0x8502, 0xfc82, 0xee82, 0xe082, 0xd482, 0xc882, - 0xbd82, 0xb282, 0xa882, 0x9e82, 0x9682, 0x8d82, 0x8582, 0x7e82, - 0x7682, 0x7082, 0x6982, 0x6382, 0x5e82, 0x5882, 0x5382, 0x4f82, - 0x4a82, 0x4682, 0x4282, 0xfc01, 0xee01, 0xe001, 0xd401, 0xc801, - 0xbd01, 0xb201, 0xa801, 0x9e01, 0x9501, 0x8d01, 0x8501, 0x7e01, - 0x7601, 0x7001, 0x6901, 0x6301, 0x5e01, 0x5801, 0x5301, 0x4f01, - 0x4a01, 0x4601 +static const unsigned pitch2freq[]={ /* rest ( */ 0x0000, /* ) */ 0x8d03, 0x8603, 0x7d03, // Octave 0 + 0x7703, 0x7003, 0x6a03, 0x6303, 0x5e03, 0x5903, 0x5403, 0x4f03, 0x4a03, 0x4603, 0x4203, 0xfd83, // Octave 1 + 0xee83, 0xe083, 0xd483, 0xc783, 0xbc83, 0xb283, 0xa883, 0x9e83, 0x9583, 0x8d83, 0x8583, 0x7e83, // Octave 2 + 0x7683, 0x7083, 0x6983, 0x6383, 0x5e83, 0x5983, 0x5383, 0x4f83, 0x4a83, 0x4683, 0x4283, 0xfc02, // Octave 3 + 0xee02, 0xe102, 0xd402, 0xc802, 0xbd02, 0xb202, 0xa802, 0x9e02, 0x9502, 0x8d02, 0x8502, 0xfc82, // Octave 4 + 0xee82, 0xe082, 0xd482, 0xc882, 0xbd82, 0xb282, 0xa882, 0x9e82, 0x9682, 0x8d82, 0x8582, 0x7e82, // Octave 5 + 0x7682, 0x7082, 0x6982, 0x6382, 0x5e82, 0x5882, 0x5382, 0x4f82, 0x4a82, 0x4682, 0x4282, 0xfc01, // Octave 6 + 0xee01, 0xe001, 0xd401, 0xc801, 0xbd01, 0xb201, 0xa801, 0x9e01, 0x9501, 0x8d01, 0x8501, 0x7e01, // Octave 7 + 0x7601, 0x7001, 0x6901, 0x6301, 0x5e01, 0x5801, 0x5301, 0x4f01, 0x4a01, 0x4601 // Octave 8 +// C C#/Db D D#/Eb E F F#/Gb G G#/Ab A A#/Bb B // Note Columns }; //! single beep @@ -146,8 +142,8 @@ static void dsound_handler(void *data) { DEBUG("note: %d,%d (%d)", pitch, dsound_next_note->length, dsound_64th_ms * dsound_next_note->length - dsound_internote_ms); - if (pitchlength - && ++repcnt == dsound_next_note->length) { + && repcnt++ == dsound_next_note->length) { repcnt = 0; dsound_next_note += 2; } else { - dsound_next_note -= (((unsigned short)dsound_next_note[1].pitch) << 8) - | ((unsigned short)dsound_next_note[1].length); + dsound_next_note -= ((dsound_next_note[1].pitch) << 8) + | (dsound_next_note[1].length); } } else { /* PITCH_END or broken sound */ play_pause();