From 05ce8e10cda54daecc52fd0e04972b28cc811668 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Mon, 12 Jul 2021 16:46:54 +0800 Subject: Volume changing command Now the sheets can contain commands to change volumes for the channels. --- parser.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 7 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index 3b0d30c..1764f86 100644 --- a/parser.c +++ b/parser.c @@ -13,12 +13,16 @@ /* A note of type BEAT_DURATION_TYPE stores the new bpm in the secs field. */ +/* A note of type VOLUME_TYPE stores the new volume in the secs + field. */ + typedef enum { NONE_TYPE, NOTE_TYPE, SILENT_TYPE, INSTRUMENT_TYPE, - BEAT_DURATION_TYPE + BEAT_DURATION_TYPE, + VOLUME_TYPE } PType; struct PNote_s { @@ -103,6 +107,11 @@ print_note(const PNote note) "%.3f beats per minute.\n", note.secs); break; + case VOLUME_TYPE: + fprintf(stderr, "a note of the type that changes the volume to " + "%.3f times.\n", + note.secs); + break; } } @@ -267,6 +276,28 @@ read_sheet(const char *str, LENT len) if (*(str+counter) == ' ') { /* Just skip spaces so that they don't block us reading anchor chars. */ + } else if (*(str+counter) == 'v') { + /* changing volume note */ + + counter++; + + for (;*(str+counter) == ' ';) counter++; + + if (*(str+counter) != '\n' && + *(str+counter) != 13 && + sscanf(str+counter, "%lf%n", + &local, &num_chars_read) == 1) { + temp_note = (PNote) { + NULL, local, + 0, VOLUME_TYPE, NULL + }; + + /* fprintf(stderr, "print a note\n"); + * print_note(temp_note); */ + + counter += num_chars_read-1; + } + *(current_unit.notes+channel_num) = temp_note; } else if (*(str+counter) == 'b') { /* changing bpm note */ @@ -528,6 +559,10 @@ play_sheet(const PSheet sh, const Volume v) Beats dur = BEAT_DUR; + /* Each channel can specify its sound. */ + + Volume *volume_per_channel = MYALLOC(Volume, channel_num);; + #ifdef DEBUG fprintf(stderr, "before finding num\n"); #endif @@ -550,12 +585,14 @@ play_sheet(const PSheet sh, const Volume v) #endif *(temp+i) = MYALLOC(WaveFrag, *(num_notes_per_channel+i)); + + *(channel_num_array+i) = 0; + + *(volume_per_channel+i) = 1.0; } war = MYALLOC(WaveFrag, channel_num); - for (LENT i = 0; i < channel_num;) *(channel_num_array+i++) = 0; - #ifdef DEBUG fprintf(stderr, "before for loop\n"); #endif @@ -575,7 +612,8 @@ play_sheet(const PSheet sh, const Volume v) if (pn.type != NOTE_TYPE && pn.type != SILENT_TYPE && - pn.type != BEAT_DURATION_TYPE) continue; + pn.type != BEAT_DURATION_TYPE && + pn.type != VOLUME_TYPE) continue; if (pn.len >= 10) { fprintf(stderr, "A note cannot have more than 10 semitones together.\n"); @@ -590,17 +628,24 @@ play_sheet(const PSheet sh, const Volume v) switch (pn.type) { case NOTE_TYPE: for (LENT k = 0; k < pn.len; k++) { - *(st_temp+k) = make_sound(inst, v * ((k==1) ? 0.3 : 1.0), + *(st_temp+k) = make_sound(inst, v * *(volume_per_channel+j), stoh(*(pn.tones+k)), pn.secs * dur); } break; case BEAT_DURATION_TYPE: dur = 60.0 / pn.secs; break; - default: - /* SILENT_TYPE */ + case VOLUME_TYPE: + *(volume_per_channel+j) = pn.secs; + break; + case SILENT_TYPE: *(st_temp) = silent_note(pn.secs, dur); break; + default: + /* Not goint to happen */ + fprintf(stderr, "something weird happens in play_sheet.\n"); + exit(1); + break; } #ifdef DEBUG @@ -644,6 +689,7 @@ play_sheet(const PSheet sh, const Volume v) free(temp); free(num_notes_per_channel); free(channel_num_array); + free(volume_per_channel); #ifdef DEBUG fprintf(stderr, "after merging\n"); -- cgit v1.2.3-18-g5258