Changed year in copyright notices.
[ahxm.git] / compiler.y
blob4d8852d65f40edee3d6bd66faf8a133b96aebec3
1 %{
2 /*
4 Ann Hell Ex Machina - Music Software
5 Copyright (C) 2003/2007 Angel Ortega <angel@triptico.com>
7 compiler.y - Scripting language YACC parser
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 http://www.triptico.com
27 #include "config.h"
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <math.h>
34 #include "ahxm.h"
36 /*******************
37 Data
38 ********************/
40 int yylex(void);
41 void yyerror(char * s);
43 /* injecting code functions (defined in compiler.l) */
44 int push_code(char * code);
45 int push_code_from_file(char * file);
47 /* current track */
48 int track;
50 /* current time */
51 double cur_time = 0.0;
53 /* end time (longest time seen) */
54 double end_time = 0.0;
56 /* note globals */
57 static double length;
58 static int octave;
59 static int transpose;
60 static double staccato;
61 static float volume;
62 static double gliss;
64 /* parser debugging */
66 #define DEBUGF if(verbose >= 2)printf
68 /* blocks */
70 struct block
72 char * name;
73 int n_sblocks;
74 char ** sblocks;
77 static struct block * blocks = NULL;
78 static int n_blocks = 0;
80 /* group info */
81 struct group
83 double start;
84 double gliss;
85 double max;
88 static struct group * groups = NULL;
89 static int n_groups = 0;
90 static int groups_size = 0;
92 /* mark info */
93 struct mark
95 char * name;
96 double time;
99 static struct mark * marks = NULL;
100 static int n_marks = 0;
102 /* arpeggiator */
103 struct arp
105 double delay;
106 int transpose;
107 float volume;
108 int track_off;
111 static struct arp * arps = NULL;
112 static int n_arps = 0;
113 static int arps_size = 0;
115 static double arp_delay;
116 static int arp_transpose;
117 static float arp_volume;
118 static int arp_track_off;
120 int compiler_error = 0;
122 extern int yyline;
124 /* alterations for each note */
125 int alterations[12];
127 /* random seeds */
128 unsigned long block_seed = 0;
130 /*******************
131 Code
132 ********************/
134 unsigned long ah_rnd(unsigned long * seed)
135 /* special randomizer */
137 *seed = (*seed * 58321) + 11113;
139 return(*seed >> 16);
143 void c_err(char * e1, char * e2, char * e3)
144 /* reports an error from the compiler */
146 printf("ahxm:");
147 if(e1 != NULL) printf(" %s", e1);
148 if(e2 != NULL) printf(" %s", e2);
149 if(e3 != NULL) printf(" %s", e3);
150 printf(" in line %d\n", yyline);
152 compiler_error++;
156 static void forward(double step)
157 /* moves forward current time */
159 /* add step */
160 cur_time += step;
162 /* quantizations could be done here */
166 /* blocks */
168 static int find_block(char * name)
169 /* finds a block */
171 int n;
173 for(n = 0;n < n_blocks;n++)
175 if(strcmp(name, blocks[n].name) == 0)
176 return(n);
179 return(-1);
183 static int set_block(char * name, char * block)
184 /* defines a block */
186 int n;
187 struct block * b;
188 char * start;
189 char * stop;
191 /* if block already exists, free it */
192 if((n = find_block(name)) >= 0)
194 b = &blocks[n];
196 /* free all subblocks */
197 for(n = 0;n < b->n_sblocks;n++)
198 free(b->sblocks[n]);
200 /* free the subblock array */
201 free(b->sblocks);
203 else
205 GROW(blocks, n_blocks, struct block);
206 b = &blocks[n_blocks++];
208 b->name = strdup(name);
211 /* reset */
212 b->n_sblocks = 0;
213 b->sblocks = NULL;
215 /* now split in subblocks (delimited by : ) */
216 start = block;
218 while((stop = strchr(start, ':')) != NULL)
220 /* break there */
221 *stop = '\0';
223 /* add the subblock */
224 GROW(b->sblocks, b->n_sblocks, char *);
225 b->sblocks[b->n_sblocks++] = strdup(start);
227 start = stop + 1;
230 /* no more separators? store the rest */
231 GROW(b->sblocks, b->n_sblocks, char *);
232 b->sblocks[b->n_sblocks++] = strdup(start);
234 /* the original block is no longer needed */
235 free(block);
237 return(1);
241 static void insert_block(char * name)
242 /* inserts a block */
244 int n;
246 if((n = find_block(name)) >= 0)
248 struct block * b;
250 b = &blocks[n];
252 /* get one of them, randomly */
253 n = ah_rnd(&block_seed) % b->n_sblocks;
255 push_code(strdup(b->sblocks[n]));
257 else
258 c_err("block-not-found", name, NULL);
262 static int insert_file(char * filename)
264 if(!push_code_from_file(filename))
266 c_err("script-not-found", filename, NULL);
267 return(1);
270 return(0);
274 /* groups */
276 static int push_group(void)
277 /* starts a new group of notes */
279 struct group * g;
281 if(n_groups == groups_size)
283 GROW(groups, groups_size, struct group);
284 groups_size ++;
287 g = &groups[n_groups++];
289 g->start = cur_time;
290 g->gliss = 0.0;
291 g->max = 0.0;
293 return(1);
297 static int next_group_part(void)
298 /* part delimiter */
300 struct group * g;
302 if(n_groups == 0)
304 c_err("missing-start-of-group", NULL, NULL);
305 return(0);
308 g = &groups[n_groups - 1];
310 /* store maximum frame */
311 if(g->max < cur_time)
312 g->max = cur_time;
314 /* add glissando delay */
315 g->gliss += gliss;
317 /* rewind */
318 cur_time = g->start + g->gliss;
320 return(1);
324 static int pop_group(void)
325 /* finishes a group, moving the frame to the end of the longer part */
327 if(n_groups == 0)
329 c_err("missing-start-of-group", NULL, NULL);
330 return(0);
333 n_groups--;
335 /* if other parts of group were longer than the last one,
336 move pointer there */
337 if(groups[n_groups].max > cur_time)
338 cur_time = groups[n_groups].max;
340 return(1);
344 /* marks */
346 static int seek_mark(char * name)
347 /* seeks a mark by name; returns its offset or -1 */
349 int n;
351 for(n = 0;n < n_marks;n++)
352 if(strcmp(marks[n].name, name) == 0)
353 return(n);
355 return(-1);
359 static void add_mark(char * name)
360 /* creates a new mark */
362 int n;
364 if((n = seek_mark(name)) == -1)
366 n = n_marks++;
367 GROW(marks, n, struct mark);
368 marks[n].name = strdup(name);
371 marks[n].time = cur_time;
375 static void find_mark(char * name, int set)
376 /* finds a mark by name, optionally moving time cursor there */
378 int n;
380 if((n = seek_mark(name)) != -1)
382 if(set)
384 if(cur_time > marks[n].time)
386 /* if mark is not END, fail */
387 if(strcmp(name, "END") != 0)
388 c_err("mark-overpassed", name, NULL);
390 else
391 cur_time = marks[n].time;
393 else
394 if(cur_time != marks[n].time)
395 c_err("mark-mismatch", name, NULL);
397 return;
400 c_err("mark-not-found", name, NULL);
404 /* arpeggiator */
406 static void arp_default(void)
407 /* resets arpeggiator values to the default ones */
409 arp_delay = 0.0;
410 arp_transpose = 0;
411 arp_volume = 1.0;
412 arp_track_off = 0;
416 static void add_arp(void)
417 /* adds an arpeggiator note */
419 struct arp * a;
421 /* if the note is exactly the same, do nothing */
422 if(arp_delay == 0.0 && arp_transpose == 0 &&
423 arp_volume == 1.0 && arp_track_off == 0)
424 return;
426 if(n_arps == arps_size)
428 GROW(arps, arps_size, struct arp);
429 arps_size ++;
432 a = &arps[n_arps];
434 a->delay = arp_delay;
435 a->transpose = arp_transpose;
436 a->volume = arp_volume;
437 a->track_off = arp_track_off;
439 n_arps++;
440 arp_default();
444 static void set_alteration(char * altstr)
445 /* sets the alterations from altstr */
447 int n, steps[] = { 2, 0, 2, 0, 1, 2, 0, 2, 0, 2, 0, 1 };
449 /* reset alterations */
450 for(n = 0;n < 12;n++) alterations[n] = 0;
452 /* changed according the altstr spec */
453 for(n = 0;*altstr != '\0' && n < 12;altstr++)
455 switch(*altstr)
457 case '&': alterations[n] = -1; break;
458 case '#': alterations[n] = 1; break;
461 /* move to next natural note */
462 n += steps[n];
467 /* song events */
469 static void add_note_event(int note)
470 /* adds a note event */
472 int n;
473 int np;
474 union song_ev e;
476 /* sum the alteration */
477 if((n = note % 12) < 0) n += 12;
478 note += alterations[n];
480 /* calculate the note */
481 np = note + transpose + (octave * 12);
483 /* is note out of range? */
484 if(np < 0 || np > 127)
486 c_err("note-out-of-range", NULL, NULL);
487 return;
490 e.note.trk_id = track;
491 e.note.note = np;
492 e.note.len = length * staccato;
493 e.note.vol = volume;
495 add_song_ev(SONG_EV_NOTE, cur_time, &e);
497 /* add arpeggiator repetitions */
498 for(n = 0;n < n_arps;n++)
500 e.note.trk_id = track + arps[n].track_off;
501 e.note.note = np + arps[n].transpose;
502 e.note.vol = volume * arps[n].volume;
504 add_song_ev(SONG_EV_NOTE, cur_time + arps[n].delay, &e);
509 static void add_back_event(void)
511 union song_ev e;
513 e.back.trk_id = track;
514 e.back.len = length;
515 add_song_ev(SONG_EV_BACK, cur_time, &e);
519 static void add_tempo_event(int trk_id, double tempo)
521 union song_ev e;
523 e.tempo.trk_id = trk_id;
524 e.tempo.tempo = tempo;
525 add_song_ev(SONG_EV_TEMPO, cur_time, &e);
529 static void add_meter_event(int trk_id, int num, int den)
531 union song_ev e;
533 e.meter.trk_id = trk_id;
534 e.meter.num = num;
535 e.meter.den = den;
536 add_song_ev(SONG_EV_METER, cur_time, &e);
539 static void add_measure_event(void)
541 union song_ev e;
543 e.measure.trk_id = -1;
544 e.measure.line = yyline;
546 add_song_ev(SONG_EV_MEASURE, cur_time, &e);
550 static void add_ss_sustain_event(double sustain)
552 union song_ev e;
554 e.ss_sustain.trk_id = track;
555 e.ss_sustain.sustain = sustain;
557 add_song_ev(SONG_EV_SS_SUSTAIN, cur_time, &e);
561 static void add_ss_attack_event(double attack)
563 union song_ev e;
565 e.ss_attack.trk_id = track;
566 e.ss_attack.attack = attack;
568 add_song_ev(SONG_EV_SS_ATTACK, cur_time, &e);
572 static void add_ss_vibrato_event(double depth, double freq)
574 union song_ev e;
576 e.ss_vibrato.trk_id = track;
577 e.ss_vibrato.vib_depth = depth;
578 e.ss_vibrato.vib_freq = freq;
580 add_song_ev(SONG_EV_SS_VIBRATO, cur_time, &e);
584 static void add_ss_portamento_event(double portamento)
586 union song_ev e;
588 e.ss_portamento.trk_id = track;
589 e.ss_portamento.portamento = portamento;
591 add_song_ev(SONG_EV_SS_PORTAMENTO, cur_time, &e);
595 static void add_ss_channel_event(int channel, float vol)
597 union song_ev e;
599 e.ss_channel.trk_id = track;
600 e.ss_channel.channel = channel;
601 e.ss_channel.vol = vol;
603 add_song_ev(SONG_EV_SS_CHANNEL, cur_time, &e);
607 static void add_ss_wav_event(char * wav_file, int base, int min, int max,
608 double loop_start, double loop_end, int first_channel, int skip_channels)
610 union song_ev e;
612 e.ss_wav.trk_id = track;
613 e.ss_wav.file = wav_file;
614 e.ss_wav.base = base;
615 e.ss_wav.min = min;
616 e.ss_wav.max = max;
617 e.ss_wav.loop_start = loop_start;
618 e.ss_wav.loop_end = loop_end;
619 e.ss_wav.first_channel = first_channel;
620 e.ss_wav.skip_channels = skip_channels;
622 add_song_ev(SONG_EV_SS_WAV, cur_time, &e);
626 static void add_ss_pat_event(char * pat_file)
628 union song_ev e;
630 e.ss_pat.trk_id = track;
631 e.ss_pat.file = pat_file;
633 add_song_ev(SONG_EV_SS_PAT, cur_time, &e);
637 static void add_ss_eff_event(int type, int channel, double size, float gain,
638 double depth, double freq, double phase, float initial, float final)
640 union song_ev e;
642 e.ss_eff.trk_id = track;
643 e.ss_eff.channel = channel;
644 e.ss_eff.size = size;
645 e.ss_eff.gain = gain;
646 e.ss_eff.depth = depth;
647 e.ss_eff.freq = freq;
648 e.ss_eff.phase = phase;
649 e.ss_eff.initial = initial;
650 e.ss_eff.final = final;
652 add_song_ev(type, cur_time, &e);
656 static void add_ss_pitch_stretch(int note, double len, float vol)
658 union song_ev e;
660 e.ss_pitch_stretch.trk_id = track;
661 e.ss_pitch_stretch.note = note;
662 e.ss_pitch_stretch.len = len;
663 e.ss_pitch_stretch.vol = vol;
665 add_song_ev(SONG_EV_SS_PITCH_STRETCH, cur_time, &e);
669 static void add_ss_print_wave_tempo(int note, double len)
671 union song_ev e;
673 e.ss_print_wave_tempo.trk_id = track;
674 e.ss_print_wave_tempo.note = note;
675 e.ss_print_wave_tempo.len = len;
677 add_song_ev(SONG_EV_SS_PRINT_WAVE_TEMPO, cur_time, &e);
681 static void add_midi_channel_event(int channel)
683 union song_ev e;
685 e.midi_channel.trk_id = track;
686 e.midi_channel.channel = channel - 1;
688 add_song_ev(SONG_EV_MIDI_CHANNEL, cur_time, &e);
692 static void add_midi_program_event(int program)
694 union song_ev e;
696 e.midi_program.trk_id = track;
697 e.midi_program.program = program;
699 add_song_ev(SONG_EV_MIDI_PROGRAM, cur_time, &e);
703 static void add_song_info_event(char * author, char * name)
705 union song_ev e;
707 e.song_info.trk_id = track;
708 e.song_info.author = author;
709 e.song_info.name = name;
711 add_song_ev(SONG_EV_SONG_INFO, cur_time, &e);
715 static void init_track(void)
716 /* sets the default values for a new track */
718 int n;
720 /* is there an end time? test if this is longer */
721 if(cur_time > end_time)
723 add_mark("END");
724 end_time = cur_time;
727 cur_time = 0.0;
728 length = 0.0;
729 transpose = 0;
730 staccato = 0.8;
731 volume = 0.75;
732 octave = 5;
733 gliss = 0;
735 /* groups should not cross track boundaries */
736 n_groups = 0;
738 /* reset arpeggiator */
739 n_arps = 0;
740 arp_default();
742 /* is there a START mark? if so, move there */
743 if((n = seek_mark("START")) != -1)
744 cur_time = marks[n].time;
746 /* reset alterations */
747 for(n = 0;n < 12;n++)
748 alterations[n] = 0;
754 %union {
755 int i;
756 double d;
757 char * p;
760 %token <i> P_INTEGER S_INTEGER
761 %token <d> P_REAL S_REAL
762 %token <i> NOTE_P NOTE_T3 NOTE_T5
763 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
765 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
767 %token <p> ALTSTR
769 %token <p> XC_STR
770 %token <i> XC_ABSNOTE
771 %token <d> XC_MSECS
773 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT
774 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL
776 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
777 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
778 %token SS_EFF_FADER SS_EFF_REVERB
779 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
780 %token SS_EFF_OFF
782 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
784 %token SONG_INFO
786 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
788 %type <i> integer note note_pitch rest back
789 %type <d> real p_number number note_length
791 %type <d> arp_list arp_note
792 %type <i> xc_absnote
796 script:
797 script stmt { ; }
798 | /* NULL */
801 stmt:
802 note {
803 /* note event */
804 add_note_event($1);
805 forward(length);
807 | rest {
808 /* rest */
809 forward(length);
811 | back {
812 /* back */
813 add_back_event();
815 | 'z' note_length {
816 /* zero note */
817 length = $2;
819 | 'o' P_INTEGER {
820 /* absolute octave */
821 octave = $2;
823 | 'o' S_INTEGER {
824 /* relative octave */
825 octave += $2;
827 | 'v' P_INTEGER {
828 /* absolute volume */
829 volume = (float)$2;
831 | 'v' P_REAL {
832 /* absolute volume */
833 volume = (float)$2;
835 | 'v' S_REAL {
836 /* relative volume */
837 volume += (float)$2;
839 | 't' integer {
840 /* transpose */
841 transpose = $2;
843 | 's' p_number {
844 /* staccato */
845 staccato = $2;
848 | '<' {
849 /* start of group */
850 push_group();
852 | ';' {
853 /* group delimiter */
854 next_group_part();
856 | '>' {
857 /* end of group */
858 pop_group();
860 | 'l' note_length {
861 /* glissando */
862 gliss = $2;
865 | '|' {
866 /* measure mark event */
867 add_measure_event();
870 | NEW_MARK {
871 /* add new mark */
872 add_mark($1);
874 | GOTO_MARK {
875 /* go to mark */
876 find_mark($1, 1);
878 | ASSERT_MARK {
879 /* assert mark */
880 find_mark($1, 0);
883 | '\\' {
884 /* new track */
886 track++;
887 init_track();
889 | 'T' p_number {
890 /* tempo setting */
891 add_tempo_event(-1, $2);
893 | 'M' P_INTEGER '/' P_INTEGER {
894 /* meter (time signature) setting */
895 add_meter_event(-1, $2, $4);
897 | ALTSTR {
898 /* alteration string */
899 set_alteration($1);
902 | BLOCK '*' P_INTEGER {
903 /* repeat block */
904 int n;
906 /* store the block as <TMP> */
907 set_block("<TMP>", $1);
909 for(n = 0;n < $3;n++)
910 insert_block("<TMP>");
912 | BLOCK BLK_ASSIGN {
913 /* assign block */
914 set_block($2, $1);
916 | BLK_INSERT {
917 /* insert block */
918 insert_block($1);
920 | FILE_INSERT {
921 /* insert file */
922 insert_file($1);
925 | arp { ; }
927 | xc_cmd { ; }
931 integer:
932 P_INTEGER { $$ = $1; }
933 | S_INTEGER { $$ = $1; }
936 real:
937 P_REAL { $$ = $1; }
938 | S_REAL { $$ = $1; }
941 p_number:
942 P_INTEGER { $$ = (double) $1; }
943 | P_REAL { $$ = $1; }
946 number:
947 integer { $$ = (double) $1; }
948 | real { $$ = $1; }
951 note:
952 note_pitch { $$ = $1; }
953 | note note_length { $$ = $1; length=$2; }
954 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
957 note_pitch:
958 NOTE_P { $$ = $1; }
959 | note_pitch '&' { $$ = $1 - 1; }
960 | note_pitch '#' { $$ = $1 + 1; }
961 | note_pitch '\'' { $$ = $1 + 12; }
962 | note_pitch ',' { $$ = $1 - 12; }
965 note_length:
966 P_INTEGER { $$ = 1 / (double) $1; }
967 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
968 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
969 | note_length '*' p_number { $$ = $1 * $3; }
970 | note_length '.' { $$ = $1 * 1.5; }
973 rest:
974 'r' { ; }
975 | rest note_length {
976 /* rest with length */
977 length = $2;
981 back:
982 'k' { ; }
983 | back note_length {
984 /* back with length */
985 length = $2;
989 arp:
990 'x' {
991 /* empty arpeggiator */
992 n_arps = 0;
993 arp_default();
995 | 'x' arp_list { ; }
998 arp_list:
999 arp_note {
1000 /* first arpeggiator note */
1001 n_arps = 0;
1002 add_arp();
1004 | arp_list ',' arp_note {
1005 /* rest of arpeggiator notes */
1006 add_arp();
1010 arp_note:
1011 note_length {
1012 /* arpeggiator delay */
1013 arp_delay = $1;
1015 | arp_note '~' number {
1016 /* arpeggiator volume */
1017 arp_volume = (float)$3;
1019 | arp_note S_INTEGER {
1020 /* arpeggiator transpose */
1021 arp_transpose = $2;
1023 | arp_note '/' P_INTEGER {
1024 /* arpeggiator track offset */
1025 arp_track_off = $3;
1027 | arp_note NOTE_T3 {
1028 /* HACK: /3 */
1029 arp_track_off = 3;
1031 | arp_note NOTE_T5 {
1032 /* HACK: /5 */
1033 arp_track_off = 5;
1037 xc_absnote:
1038 P_INTEGER { $$ = $1; }
1039 | XC_ABSNOTE { $$ = $1; }
1042 xc_cmd:
1043 SS_WAV XC_STR xc_absnote {
1044 /* load .wav file with just one note */
1045 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1047 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1048 /* load .wav file */
1049 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1051 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1052 /* load .wav file, with loop boundaries */
1053 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1055 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1056 /* load .wav file, with loop boundaries,
1057 first channel and skip channels */
1058 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1060 | SS_PAT XC_STR {
1061 /* load .pat file */
1062 add_ss_pat_event($2);
1064 | SS_SUSTAIN XC_MSECS {
1065 /* sets sustain */
1066 add_ss_sustain_event($2);
1068 | SS_ATTACK XC_MSECS {
1069 /* sets attack */
1070 add_ss_attack_event($2);
1072 | SS_VIBRATO XC_MSECS number {
1073 /* sets vibrato */
1074 add_ss_vibrato_event($2, $3);
1076 | SS_PORTAMENTO number {
1077 /* sets portamento */
1078 add_ss_portamento_event($2);
1080 | SS_CHANNEL integer number {
1081 /* sets volume for a channel */
1082 add_ss_channel_event($2, $3);
1084 | SS_VOL number number {
1085 /* set vol for 2 channels */
1086 add_ss_channel_event(0, $2);
1087 add_ss_channel_event(1, $3);
1089 | SS_VOL number number number {
1090 /* set vol for 3 channels */
1091 add_ss_channel_event(0, $2);
1092 add_ss_channel_event(1, $3);
1093 add_ss_channel_event(2, $4);
1095 | SS_VOL number number number number {
1096 /* set vol for 4 channels */
1097 add_ss_channel_event(0, $2);
1098 add_ss_channel_event(1, $3);
1099 add_ss_channel_event(2, $4);
1100 add_ss_channel_event(3, $5);
1102 | SS_VOL number number number number number number {
1103 /* set vol for 6 channels */
1104 add_ss_channel_event(0, $2);
1105 add_ss_channel_event(1, $3);
1106 add_ss_channel_event(2, $4);
1107 add_ss_channel_event(3, $5);
1108 add_ss_channel_event(4, $6);
1109 add_ss_channel_event(5, $7);
1111 | SS_EFF_DELAY integer XC_MSECS {
1112 /* delay effect */
1113 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1114 $2, $3, 0, 0, 0, 0, 0, 0);
1117 | SS_EFF_ECHO integer XC_MSECS number {
1118 /* echo effect */
1119 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1120 $2, $3, $4, 0, 0, 0, 0, 0);
1123 | SS_EFF_COMB integer XC_MSECS number {
1124 /* comb effect */
1125 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1126 $2, $3, $4, 0, 0, 0, 0, 0);
1129 | SS_EFF_ALLPASS integer XC_MSECS number {
1130 /* allpass effect */
1131 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1132 $2, $3, $4, 0, 0, 0, 0, 0);
1135 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1136 /* flanger effect */
1137 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1138 $2, $3, $4, $5, $6, $7, 0, 0);
1141 | SS_EFF_WOBBLE integer number number {
1142 /* wobble effect */
1143 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1144 $2, 0, 0.8, 0, $3, $4, 0, 0);
1147 | SS_EFF_WOBBLE integer number number number {
1148 /* wobble effect, with gain */
1149 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1150 $2, 0, $5, 0, $3, $4, 0, 0);
1153 | SS_EFF_SQWOBBLE integer number number {
1154 /* square wobble effect */
1155 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1156 $2, 0, 0, 0, $3, $4, 0, 0);
1159 | SS_EFF_HFWOBBLE integer number number {
1160 /* half wobble effect */
1161 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1162 $2, 0, 0, 0, $3, $4, 0, 0);
1165 | SS_EFF_FADER integer XC_MSECS number number {
1166 /* fader effect */
1167 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1168 $2, $3, 0, 0, 0, 0, $4, $5);
1171 | SS_EFF_REVERB integer {
1172 /* reverb effect */
1173 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1174 $2, 0, 0, 0, 0, 0, 0, 0);
1177 | SS_EFF_FOLDBACK integer number {
1178 /* foldback distortion effect */
1179 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1180 $2, 0, $3, 0, 0, 0, 0, 0);
1182 | SS_EFF_ATAN integer number {
1183 /* atan distortion effect */
1184 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1185 $2, 0, $3, 0, 0, 0, 0, 0);
1187 | SS_EFF_DISTORT integer number {
1188 /* distort distortion effect */
1189 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1190 $2, 0, $3, 0, 0, 0, 0, 0);
1192 | SS_EFF_OVERDRIVE integer number {
1193 /* overdrive distortion effect */
1194 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1195 $2, 0, $3, 0, 0, 0, 0, 0);
1198 | SS_EFF_OFF integer {
1199 /* off effect */
1200 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1201 $2, 0, 0, 0, 0, 0, 0, 0);
1204 | SS_PITCH_STRETCH xc_absnote number number {
1205 /* pitch stretch note */
1206 add_ss_pitch_stretch($2, $3, $4);
1208 forward($3);
1211 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1212 /* print tempo from wave */
1213 add_ss_print_wave_tempo($2, $3);
1216 | SONG_INFO XC_STR XC_STR {
1217 /* add song info */
1218 add_song_info_event($2, $3);
1221 | MIDI_CHANNEL integer {
1222 /* midi channel */
1223 add_midi_channel_event($2);
1226 | MIDI_PROGRAM integer {
1227 /* midi program */
1228 add_midi_program_event($2);
1234 void yyerror(char * s)
1236 c_err(s, NULL, NULL);
1240 #define set_block_d(n,b) set_block(n,strdup(b))
1242 static void compile_startup(void)
1244 track = 0;
1245 yyline = 1;
1246 compiler_error = 0;
1248 /* default settings */
1249 add_tempo_event(-2, 120.0);
1250 add_meter_event(-2, 4, 4);
1251 init_track();
1253 /* standard tonalities */
1254 set_block_d("CM", "A"); set_block_d("Am", "$CM");
1255 set_block_d("C#M", "A#######"); set_block_d("A#m", "$C#M");
1256 set_block_d("DM", "A#--#---"); set_block_d("Bm", "$DM");
1257 set_block_d("E&M", "A--&--&&"); set_block_d("Cm", "$E&M");
1258 set_block_d("EM", "A##-##--"); set_block_d("C#m", "$EM");
1259 set_block_d("FM", "A------&"); set_block_d("Dm", "$FM");
1260 set_block_d("F#M", "A######-"); set_block_d("D#m", "$F#M");
1261 set_block_d("GM", "A---#---"); set_block_d("Em", "$GM");
1262 set_block_d("A&M", "A-&&--&&"); set_block_d("Fm", "$A&M");
1263 set_block_d("AM", "A#--##--"); set_block_d("F#m", "$AM");
1264 set_block_d("B&M", "A--&---&"); set_block_d("Gm", "$B&M");
1265 set_block_d("BM", "A##-###-"); set_block_d("G#m", "$BM");
1269 static int do_parse(void)
1271 int r = yyparse();
1273 return(r + compiler_error);
1277 int compile_ahs_string(char * code)
1279 compile_startup();
1281 push_code(strdup(code));
1283 return(do_parse());
1287 int compile_ahs(char * file)
1289 compile_startup();
1291 if(insert_file(file))
1292 return(1);
1294 return(do_parse());