Updated TODO.
[ahxm.git] / compiler.y
blobb63ac01b1e15c6be35c56b05f8d02e92b1134652
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_from;
62 static float volume_to;
63 static double gliss;
65 /* parser debugging */
67 #define DEBUGF if(verbose >= 2)printf
69 /* blocks */
71 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 {
82 double start;
83 double gliss;
84 double max;
87 static struct group * groups = NULL;
88 static int n_groups = 0;
89 static int groups_size = 0;
91 /* mark info */
92 struct mark {
93 char * name;
94 double time;
97 static struct mark * marks = NULL;
98 static int n_marks = 0;
100 /* arpeggiator */
101 struct arp {
102 double delay;
103 int transpose;
104 float volume;
105 int track_off;
108 static struct arp * arps = NULL;
109 static int n_arps = 0;
110 static int arps_size = 0;
112 static double arp_delay;
113 static int arp_transpose;
114 static float arp_volume;
115 static int arp_track_off;
117 int compiler_error = 0;
119 extern int yyline;
121 /* alterations for each note */
122 int alterations[12];
124 /* random seeds */
125 unsigned long block_seed = 0;
126 unsigned long volume_seed = 0;
128 /* solo track (-1, no solo) */
129 int solo_track = -1;
131 /*******************
132 Code
133 ********************/
135 unsigned long ah_rnd(unsigned long * seed)
136 /* special randomizer */
138 *seed = (*seed * 58321) + 11113;
140 return *seed >> 16;
144 void c_err(char * e1, char * e2, char * e3)
145 /* reports an error from the compiler */
147 printf("ahxm:");
149 if (e1 != NULL)
150 printf(" %s", e1);
151 if (e2 != NULL)
152 printf(" %s", e2);
153 if (e3 != NULL)
154 printf(" %s", e3);
156 printf(" in line %d\n", yyline);
158 compiler_error++;
162 static void forward(double step)
163 /* moves forward current time */
165 /* add step */
166 cur_time += step;
168 /* quantizations could be done here */
172 static float volume(void)
174 float f;
176 if (volume_from == volume_to)
177 f = volume_from;
178 else {
179 unsigned long r = ah_rnd(&volume_seed) % 1000;
181 f = volume_from + (volume_to - volume_from) *
182 (((float)r) / 1000.0);
185 return f;
189 /* blocks */
191 static int find_block(char * name)
192 /* finds a block */
194 int n;
196 for (n = 0; n < n_blocks; n++) {
197 if (strcmp(name, blocks[n].name) == 0)
198 return n;
201 return -1;
205 static int set_block(char * name, char * block)
206 /* defines a block */
208 int n;
209 struct block * b;
210 char * start;
211 char * stop;
213 /* if block already exists, free it */
214 if ((n = find_block(name)) >= 0) {
215 b = &blocks[n];
217 /* free all subblocks */
218 for (n = 0; n < b->n_sblocks; n++)
219 free(b->sblocks[n]);
221 /* free the subblock array */
222 free(b->sblocks);
224 else {
225 GROW(blocks, n_blocks, struct block);
226 b = &blocks[n_blocks++];
228 b->name = strdup(name);
231 /* reset */
232 b->n_sblocks = 0;
233 b->sblocks = NULL;
235 /* now split in subblocks (delimited by : ) */
236 start = block;
238 while ((stop = strchr(start, ':')) != NULL) {
239 /* break there */
240 *stop = '\0';
242 /* add the subblock */
243 GROW(b->sblocks, b->n_sblocks, char *);
244 b->sblocks[b->n_sblocks++] = strdup(start);
246 start = stop + 1;
249 /* no more separators? store the rest */
250 GROW(b->sblocks, b->n_sblocks, char *);
251 b->sblocks[b->n_sblocks++] = strdup(start);
253 /* the original block is no longer needed */
254 free(block);
256 return 1;
260 static void insert_block(char * name)
261 /* inserts a block */
263 int n;
265 if ((n = find_block(name)) >= 0) {
266 struct block * b;
268 b = &blocks[n];
270 /* get one of them, randomly */
271 n = ah_rnd(&block_seed) % b->n_sblocks;
273 push_code(strdup(b->sblocks[n]));
275 else
276 c_err("block-not-found", name, NULL);
280 static int insert_file(char * filename)
282 if (!push_code_from_file(filename)) {
283 c_err("script-not-found", filename, NULL);
284 return 1;
287 return 0;
291 /* groups */
293 static int push_group(void)
294 /* starts a new group of notes */
296 struct group * g;
298 if (n_groups == groups_size) {
299 GROW(groups, groups_size, struct group);
300 groups_size ++;
303 g = &groups[n_groups++];
305 g->start = cur_time;
306 g->gliss = 0.0;
307 g->max = 0.0;
309 return 1;
313 static int next_group_part(void)
314 /* part delimiter */
316 struct group * g;
318 if (n_groups == 0) {
319 c_err("missing-start-of-group", NULL, NULL);
320 return 0;
323 g = &groups[n_groups - 1];
325 /* store maximum frame */
326 if (g->max < cur_time)
327 g->max = cur_time;
329 /* add glissando delay */
330 g->gliss += gliss;
332 /* rewind */
333 cur_time = g->start + g->gliss;
335 return 1;
339 static int pop_group(void)
340 /* finishes a group, moving the frame to the end of the longer part */
342 if (n_groups == 0) {
343 c_err("missing-start-of-group", NULL, NULL);
344 return 0;
347 n_groups--;
349 /* if other parts of group were longer than the last one,
350 move pointer there */
351 if (groups[n_groups].max > cur_time)
352 cur_time = groups[n_groups].max;
354 return 1;
358 /* marks */
360 static int seek_mark(char * name)
361 /* seeks a mark by name; returns its offset or -1 */
363 int n;
365 for (n = 0; n < n_marks; n++)
366 if (strcmp(marks[n].name, name) == 0)
367 return n;
369 return -1;
373 static void add_mark(char * name)
374 /* creates a new mark */
376 int n;
378 if ((n = seek_mark(name)) == -1) {
379 n = n_marks++;
380 GROW(marks, n, struct mark);
381 marks[n].name = strdup(name);
384 marks[n].time = cur_time;
388 static void find_mark(char * name, int set)
389 /* finds a mark by name, optionally moving time cursor there */
391 int n;
393 if ((n = seek_mark(name)) != -1) {
394 if (set) {
395 if (cur_time > marks[n].time) {
396 /* if mark is not END, fail */
397 if (strcmp(name, "END") != 0)
398 c_err("mark-overpassed", name, NULL);
400 else
401 cur_time = marks[n].time;
403 else
404 if (cur_time != marks[n].time)
405 c_err("mark-mismatch", name, NULL);
407 return;
410 c_err("mark-not-found", name, NULL);
414 /* arpeggiator */
416 static void arp_default(void)
417 /* resets arpeggiator values to the default ones */
419 arp_delay = 0.0;
420 arp_transpose = 0;
421 arp_volume = 1.0;
422 arp_track_off = 0;
426 static void add_arp(void)
427 /* adds an arpeggiator note */
429 struct arp * a;
431 /* if the note is exactly the same, do nothing */
432 if (arp_delay == 0.0 && arp_transpose == 0 &&
433 arp_volume == 1.0 && arp_track_off == 0)
434 return;
436 if (n_arps == arps_size) {
437 GROW(arps, arps_size, struct arp);
438 arps_size ++;
441 a = &arps[n_arps];
443 a->delay = arp_delay;
444 a->transpose = arp_transpose;
445 a->volume = arp_volume;
446 a->track_off = arp_track_off;
448 n_arps++;
449 arp_default();
453 static void set_alteration(char * altstr)
454 /* sets the alterations from altstr */
456 int n, steps[] = { 2, 0, 2, 0, 1, 2, 0, 2, 0, 2, 0, 1 };
458 /* reset alterations */
459 for (n = 0; n < 12; n++)
460 alterations[n] = 0;
462 /* changed according the altstr spec */
463 for (n = 0; *altstr != '\0' && n < 12; altstr++) {
464 switch (*altstr) {
465 case '&':
466 alterations[n] = -1;
467 break;
469 case '#':
470 alterations[n] = 1;
471 break;
474 /* move to next natural note */
475 n += steps[n];
480 /* song events */
482 static struct song_ev * add_song_ev(song_ev_type type)
484 struct song_ev * r;
486 r = add_event(&song, &n_song_ev);
488 r->type = type;
489 r->time = cur_time;
490 r->trk_id = track;
491 r->event_id = n_song_ev - 1;
493 return r;
497 static void add_note_event(int note)
498 /* adds a note event */
500 int n;
501 int np;
502 struct song_ev *e;
504 /* sum the alteration */
505 if ((n = note % 12) < 0)
506 n += 12;
508 note += alterations[n];
510 /* calculate the note */
511 np = note + transpose + (octave * 12);
513 /* is note out of range? */
514 if (np < 0 || np > 127) {
515 c_err("note-out-of-range", NULL, NULL);
516 return;
519 e = add_song_ev(SONG_EV_NOTE);
521 e->value = np;
522 e->len = length * staccato;
523 e->vol = volume();
525 /* add arpeggiator repetitions */
526 for (n = 0; n < n_arps; n++) {
528 e = add_song_ev(SONG_EV_NOTE);
530 e->time = cur_time + arps[n].delay;
531 e->trk_id = track + arps[n].track_off;
532 e->value = np + arps[n].transpose;
533 e->len = length * staccato;
534 e->vol = volume() * arps[n].volume;
539 static void add_back_event(void)
541 struct song_ev *e = add_song_ev(SONG_EV_BACK);
543 e->len = length;
547 static void add_tempo_event(int trk_id, double tempo)
549 struct song_ev *e = add_song_ev(SONG_EV_TEMPO);
551 e->trk_id = trk_id;
552 e->amount = tempo;
556 static void add_meter_event(int trk_id, int num, int den)
558 struct song_ev *e = add_song_ev(SONG_EV_METER);
560 e->trk_id = trk_id;
561 e->min = num;
562 e->max = den;
565 static void add_measure_event(void)
567 struct song_ev *e = add_song_ev(SONG_EV_MEASURE);
569 e->trk_id = -1;
570 e->value = yyline;
574 static void add_ss_sustain_event(double sustain)
576 struct song_ev *e = add_song_ev(SONG_EV_SS_SUSTAIN);
578 e->amount = sustain;
582 static void add_ss_attack_event(double attack)
584 struct song_ev *e = add_song_ev(SONG_EV_SS_ATTACK);
586 e->amount = attack;
590 static void add_ss_vibrato_event(double depth, double freq)
592 struct song_ev *e = add_song_ev(SONG_EV_SS_VIBRATO);
594 e->depth = depth;
595 e->freq = freq;
599 static void add_ss_portamento_event(double portamento)
601 struct song_ev *e = add_song_ev(SONG_EV_SS_PORTAMENTO);
603 e->amount = portamento;
607 static void add_ss_channel_event(int channel, float vol)
609 struct song_ev *e = add_song_ev(SONG_EV_SS_CHANNEL);
611 e->channel = channel;
612 e->vol = vol;
616 static void add_ss_wav_event(char * wav_file, int base, int min, int max,
617 double loop_start, double loop_end, int first_channel, int skip_channels)
619 struct song_ev *e = add_song_ev(SONG_EV_SS_WAV);
621 e->name = wav_file;
622 e->value = base;
623 e->min = min;
624 e->max = max;
625 e->start = loop_start;
626 e->end = loop_end;
627 e->channel = first_channel;
628 e->skip_channels = skip_channels;
632 static void add_ss_pat_event(char * pat_file)
634 struct song_ev *e = add_song_ev(SONG_EV_SS_PAT);
636 e->name = pat_file;
640 static void add_ss_eff_event(int type, int channel, double size, float gain,
641 double depth, double freq, double phase, float initial, float final)
643 struct song_ev *e = add_song_ev(type);
645 e->channel = channel;
646 e->len = size;
647 e->vol = gain;
648 e->depth = depth;
649 e->freq = freq;
650 e->phase = phase;
651 e->initial = initial;
652 e->final = final;
656 static void add_ss_pitch_stretch(int note, double len, float vol)
658 struct song_ev *e = add_song_ev(SONG_EV_SS_PITCH_STRETCH);
660 e->value = note;
661 e->len = len;
662 e->vol = vol;
666 static void add_ss_print_wave_tempo(int note, double len)
668 struct song_ev *e = add_song_ev(SONG_EV_SS_PRINT_WAVE_TEMPO);
670 e->value = note;
671 e->len = len;
675 static void add_midi_channel_event(int channel)
677 struct song_ev *e = add_song_ev(SONG_EV_MIDI_CHANNEL);
679 e->channel = channel - 1;
683 static void add_midi_program_event(int program)
685 struct song_ev *e = add_song_ev(SONG_EV_MIDI_PROGRAM);
687 e->value = program;
691 static void add_song_info_event(char * author, char * name)
693 struct song_ev *e = add_song_ev(SONG_EV_SONG_INFO);
695 e->author = author;
696 e->name = name;
700 static void init_track(void)
701 /* sets the default values for a new track */
703 int n;
705 /* is there an end time? test if this is longer */
706 if (cur_time > end_time) {
707 add_mark("END");
708 end_time = cur_time;
711 cur_time = 0.0;
712 length = 0.0;
713 transpose = 0;
714 staccato = 0.8;
715 volume_from = volume_to = 0.75;
716 octave = 5;
717 gliss = 0;
719 /* groups should not cross track boundaries */
720 n_groups = 0;
722 /* reset arpeggiator */
723 n_arps = 0;
724 arp_default();
726 /* is there a START mark? if so, move there */
727 if ((n = seek_mark("START")) != -1)
728 cur_time = marks[n].time;
730 /* reset alterations */
731 for (n = 0; n < 12; n++)
732 alterations[n] = 0;
738 %union {
739 int i;
740 double d;
741 char * p;
744 %token <i> P_INTEGER S_INTEGER
745 %token <d> P_REAL S_REAL
746 %token <i> NOTE_P NOTE_T3 NOTE_T5
747 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
749 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
751 %token <p> ALTSTR
753 %token <p> XC_STR
754 %token <i> XC_ABSNOTE
755 %token <d> XC_MSECS
757 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT
758 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL
760 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
761 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
762 %token SS_EFF_FADER SS_EFF_REVERB
763 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
764 %token SS_EFF_OFF
766 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
768 %token SONG_INFO
770 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
772 %type <i> integer note note_pitch rest back
773 %type <d> real p_number number note_length
775 %type <d> arp_list arp_note
776 %type <i> xc_absnote
780 script:
781 script stmt { ; }
782 | /* NULL */
785 stmt:
786 note {
787 /* note event */
788 add_note_event($1);
789 forward(length);
791 | rest {
792 /* rest */
793 forward(length);
795 | back {
796 /* back */
797 add_back_event();
799 | 'z' note_length {
800 /* zero note */
801 length = $2;
803 | 'o' P_INTEGER {
804 /* absolute octave */
805 octave = $2;
807 | 'o' S_INTEGER {
808 /* relative octave */
809 octave += $2;
811 | 'v' P_INTEGER {
812 /* absolute volume */
813 volume_from = volume_to = (float)$2;
815 | 'v' P_REAL {
816 /* absolute volume */
817 volume_from = volume_to = (float)$2;
819 | 'v' S_REAL {
820 /* relative volume */
821 volume_from += (float)$2;
822 volume_to += (float)$2;
824 | 'v' P_REAL ',' P_REAL {
825 /* absolute volume ranges */
826 volume_from = (float)$2;
827 volume_to = (float)$4;
829 | 't' integer {
830 /* transpose */
831 transpose = $2;
833 | 's' p_number {
834 /* staccato */
835 staccato = $2;
838 | '<' {
839 /* start of group */
840 push_group();
842 | ';' {
843 /* group delimiter */
844 next_group_part();
846 | '>' {
847 /* end of group */
848 pop_group();
850 | 'l' note_length {
851 /* glissando */
852 gliss = $2;
855 | '|' {
856 /* measure mark event */
857 add_measure_event();
860 | NEW_MARK {
861 /* add new mark */
862 add_mark($1);
864 | GOTO_MARK {
865 /* go to mark */
866 find_mark($1, 1);
868 | ASSERT_MARK {
869 /* assert mark */
870 find_mark($1, 0);
873 | '\\' {
874 /* new track */
876 track++;
877 init_track();
879 | 'T' p_number {
880 /* tempo setting */
881 add_tempo_event(-1, $2);
883 | 'M' P_INTEGER '/' P_INTEGER {
884 /* meter (time signature) setting */
885 add_meter_event(-1, $2, $4);
887 | ALTSTR {
888 /* alteration string */
889 set_alteration($1);
892 | BLOCK '*' P_INTEGER {
893 /* repeat block */
894 int n;
896 /* store the block as <TMP> */
897 set_block("<TMP>", $1);
899 for(n = 0;n < $3;n++)
900 insert_block("<TMP>");
902 | BLOCK BLK_ASSIGN {
903 /* assign block */
904 set_block($2, $1);
906 | BLK_INSERT {
907 /* insert block */
908 insert_block($1);
910 | FILE_INSERT {
911 /* insert file */
912 insert_file($1);
915 | arp { ; }
917 | xc_cmd { ; }
921 integer:
922 P_INTEGER { $$ = $1; }
923 | S_INTEGER { $$ = $1; }
926 real:
927 P_REAL { $$ = $1; }
928 | S_REAL { $$ = $1; }
931 p_number:
932 P_INTEGER { $$ = (double) $1; }
933 | P_REAL { $$ = $1; }
936 number:
937 integer { $$ = (double) $1; }
938 | real { $$ = $1; }
941 note:
942 note_pitch { $$ = $1; }
943 | note note_length { $$ = $1; length=$2; }
944 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
947 note_pitch:
948 NOTE_P { $$ = $1; }
949 | note_pitch '&' { $$ = $1 - 1; }
950 | note_pitch '#' { $$ = $1 + 1; }
951 | note_pitch '\'' { $$ = $1 + 12; }
952 | note_pitch ',' { $$ = $1 - 12; }
955 note_length:
956 P_INTEGER { $$ = 1 / (double) $1; }
957 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
958 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
959 | note_length '*' p_number { $$ = $1 * $3; }
960 | note_length '.' { $$ = $1 * 1.5; }
963 rest:
964 'r' { ; }
965 | rest note_length {
966 /* rest with length */
967 length = $2;
971 back:
972 'k' { ; }
973 | back note_length {
974 /* back with length */
975 length = $2;
979 arp:
980 'x' {
981 /* empty arpeggiator */
982 n_arps = 0;
983 arp_default();
985 | 'x' arp_list { ; }
988 arp_list:
989 arp_note {
990 /* first arpeggiator note */
991 n_arps = 0;
992 add_arp();
994 | arp_list ',' arp_note {
995 /* rest of arpeggiator notes */
996 add_arp();
1000 arp_note:
1001 note_length {
1002 /* arpeggiator delay */
1003 arp_delay = $1;
1005 | arp_note '~' number {
1006 /* arpeggiator volume */
1007 arp_volume = (float)$3;
1009 | arp_note S_INTEGER {
1010 /* arpeggiator transpose */
1011 arp_transpose = $2;
1013 | arp_note '/' P_INTEGER {
1014 /* arpeggiator track offset */
1015 arp_track_off = $3;
1017 | arp_note NOTE_T3 {
1018 /* HACK: /3 */
1019 arp_track_off = 3;
1021 | arp_note NOTE_T5 {
1022 /* HACK: /5 */
1023 arp_track_off = 5;
1027 xc_absnote:
1028 P_INTEGER { $$ = $1; }
1029 | XC_ABSNOTE { $$ = $1; }
1032 xc_cmd:
1033 SS_WAV XC_STR xc_absnote {
1034 /* load .wav file with just one note */
1035 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1037 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1038 /* load .wav file */
1039 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1041 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1042 /* load .wav file, with loop boundaries */
1043 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1045 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1046 /* load .wav file, with loop boundaries,
1047 first channel and skip channels */
1048 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1050 | SS_PAT XC_STR {
1051 /* load .pat file */
1052 add_ss_pat_event($2);
1054 | SS_SUSTAIN XC_MSECS {
1055 /* sets sustain */
1056 add_ss_sustain_event($2);
1058 | SS_ATTACK XC_MSECS {
1059 /* sets attack */
1060 add_ss_attack_event($2);
1062 | SS_VIBRATO XC_MSECS number {
1063 /* sets vibrato */
1064 add_ss_vibrato_event($2, $3);
1066 | SS_PORTAMENTO number {
1067 /* sets portamento */
1068 add_ss_portamento_event($2);
1070 | SS_CHANNEL integer number {
1071 /* sets volume for a channel */
1072 add_ss_channel_event($2, $3);
1074 | SS_VOL number number {
1075 /* set vol for 2 channels */
1076 add_ss_channel_event(0, $2);
1077 add_ss_channel_event(1, $3);
1079 | SS_VOL number number number {
1080 /* set vol for 3 channels */
1081 add_ss_channel_event(0, $2);
1082 add_ss_channel_event(1, $3);
1083 add_ss_channel_event(2, $4);
1085 | SS_VOL number number number number {
1086 /* set vol for 4 channels */
1087 add_ss_channel_event(0, $2);
1088 add_ss_channel_event(1, $3);
1089 add_ss_channel_event(2, $4);
1090 add_ss_channel_event(3, $5);
1092 | SS_VOL number number number number number number {
1093 /* set vol for 6 channels */
1094 add_ss_channel_event(0, $2);
1095 add_ss_channel_event(1, $3);
1096 add_ss_channel_event(2, $4);
1097 add_ss_channel_event(3, $5);
1098 add_ss_channel_event(4, $6);
1099 add_ss_channel_event(5, $7);
1101 | SS_EFF_DELAY integer XC_MSECS {
1102 /* delay effect */
1103 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1104 $2, $3, 0, 0, 0, 0, 0, 0);
1107 | SS_EFF_ECHO integer XC_MSECS number {
1108 /* echo effect */
1109 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1110 $2, $3, $4, 0, 0, 0, 0, 0);
1113 | SS_EFF_COMB integer XC_MSECS number {
1114 /* comb effect */
1115 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1116 $2, $3, $4, 0, 0, 0, 0, 0);
1119 | SS_EFF_ALLPASS integer XC_MSECS number {
1120 /* allpass effect */
1121 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1122 $2, $3, $4, 0, 0, 0, 0, 0);
1125 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1126 /* flanger effect */
1127 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1128 $2, $3, $4, $5, $6, $7, 0, 0);
1131 | SS_EFF_WOBBLE integer number number {
1132 /* wobble effect */
1133 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1134 $2, 0, 0.8, 0, $3, $4, 0, 0);
1137 | SS_EFF_WOBBLE integer number number number {
1138 /* wobble effect, with gain */
1139 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1140 $2, 0, $5, 0, $3, $4, 0, 0);
1143 | SS_EFF_SQWOBBLE integer number number {
1144 /* square wobble effect */
1145 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1146 $2, 0, 0, 0, $3, $4, 0, 0);
1149 | SS_EFF_HFWOBBLE integer number number {
1150 /* half wobble effect */
1151 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1152 $2, 0, 0, 0, $3, $4, 0, 0);
1155 | SS_EFF_FADER integer XC_MSECS number number {
1156 /* fader effect */
1157 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1158 $2, $3, 0, 0, 0, 0, $4, $5);
1161 | SS_EFF_REVERB integer {
1162 /* reverb effect */
1163 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1164 $2, 0, 0, 0, 0, 0, 0, 0);
1167 | SS_EFF_FOLDBACK integer number {
1168 /* foldback distortion effect */
1169 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1170 $2, 0, $3, 0, 0, 0, 0, 0);
1172 | SS_EFF_ATAN integer number {
1173 /* atan distortion effect */
1174 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1175 $2, 0, $3, 0, 0, 0, 0, 0);
1177 | SS_EFF_DISTORT integer number {
1178 /* distort distortion effect */
1179 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1180 $2, 0, $3, 0, 0, 0, 0, 0);
1182 | SS_EFF_OVERDRIVE integer number {
1183 /* overdrive distortion effect */
1184 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1185 $2, 0, $3, 0, 0, 0, 0, 0);
1188 | SS_EFF_OFF integer {
1189 /* off effect */
1190 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1191 $2, 0, 0, 0, 0, 0, 0, 0);
1194 | SS_PITCH_STRETCH xc_absnote number number {
1195 /* pitch stretch note */
1196 add_ss_pitch_stretch($2, $3, $4);
1198 forward($3);
1201 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1202 /* print tempo from wave */
1203 add_ss_print_wave_tempo($2, $3);
1206 | SONG_INFO XC_STR XC_STR {
1207 /* add song info */
1208 add_song_info_event($2, $3);
1211 | MIDI_CHANNEL integer {
1212 /* midi channel */
1213 add_midi_channel_event($2);
1216 | MIDI_PROGRAM integer {
1217 /* midi program */
1218 add_midi_program_event($2);
1224 void yyerror(char * s)
1226 c_err(s, NULL, NULL);
1230 #define set_block_d(n,b) set_block(n,strdup(b))
1232 static void compile_startup(void)
1234 track = 0;
1235 yyline = 1;
1236 compiler_error = 0;
1238 /* default settings */
1239 add_tempo_event(-2, 120.0);
1240 add_meter_event(-2, 4, 4);
1241 init_track();
1243 /* standard tonalities */
1244 set_block_d("CM", "A"); set_block_d("Am", "$CM");
1245 set_block_d("C#M", "A#######"); set_block_d("A#m", "$C#M");
1246 set_block_d("DM", "A#--#---"); set_block_d("Bm", "$DM");
1247 set_block_d("E&M", "A--&--&&"); set_block_d("Cm", "$E&M");
1248 set_block_d("EM", "A##-##--"); set_block_d("C#m", "$EM");
1249 set_block_d("FM", "A------&"); set_block_d("Dm", "$FM");
1250 set_block_d("F#M", "A######-"); set_block_d("D#m", "$F#M");
1251 set_block_d("GM", "A---#---"); set_block_d("Em", "$GM");
1252 set_block_d("A&M", "A-&&--&&"); set_block_d("Fm", "$A&M");
1253 set_block_d("AM", "A#--##--"); set_block_d("F#m", "$AM");
1254 set_block_d("B&M", "A--&---&"); set_block_d("Gm", "$B&M");
1255 set_block_d("BM", "A##-###-"); set_block_d("G#m", "$BM");
1259 static int do_parse(void)
1261 int r = yyparse() + compiler_error;
1263 if (solo_track != -1)
1264 mute_tracks(-solo_track);
1266 return r;
1270 int compile_ahs_string(char * code)
1272 compile_startup();
1274 push_code(strdup(code));
1276 return do_parse();
1280 int compile_ahs(char * file)
1282 compile_startup();
1284 if (insert_file(file))
1285 return 1;
1287 return do_parse();