diff options
author | JSDurand <mmemmew@gmail.com> | 2021-07-12 16:46:54 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2021-07-12 16:46:54 +0800 |
commit | 05ce8e10cda54daecc52fd0e04972b28cc811668 (patch) | |
tree | 96d5c94a1373a09a4ccce3f1bb8a36297e09cfbc /parser.c | |
parent | 8d1acd562f16e8420c66e1f920912ecfa2fc0bda (diff) |
Now the sheets can contain commands to change volumes for the
channels.
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 60 |
1 files changed, 53 insertions, 7 deletions
@@ -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"); |