n_song_tracks moved back to song.c.
[ahxm.git] / compiler.y
blobfe44e5948a56da6821cb5d4b710a6ea16d11b2c1
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 /* FIXME: solo tracks don't work */
487 /* if (solo_track != -1 && ev->trk_id >= 0 && ev->trk_id != solo_track)
488 return NULL; */
490 /* FIXME: account number of tracks */
491 /* if (n_song_tracks < ev->trk_id + 1)
492 n_song_tracks = ev->trk_id + 1;
494 r = add_event(&song, &n_song_ev);
496 r->type = type;
497 r->time = cur_time;
498 r->trk_id = track;
500 return r;
504 static void copy_song_ev(song_ev_type type, double time, struct song_ev *ev)
506 /* skip tracks if a solo is requested */
507 if (solo_track != -1 && ev->trk_id >= 0 && ev->trk_id != solo_track)
508 return;
510 /* account number of tracks */
511 if (n_song_tracks < ev->trk_id + 1)
512 n_song_tracks = ev->trk_id + 1;
514 ev->type = type;
515 ev->time = time;
516 ev->event_id = n_song_ev;
518 copy_event(&song, &n_song_ev, ev);
522 static void add_note_event(int note)
523 /* adds a note event */
525 int n;
526 int np;
527 struct song_ev *e;
529 /* sum the alteration */
530 if ((n = note % 12) < 0)
531 n += 12;
533 note += alterations[n];
535 /* calculate the note */
536 np = note + transpose + (octave * 12);
538 /* is note out of range? */
539 if (np < 0 || np > 127) {
540 c_err("note-out-of-range", NULL, NULL);
541 return;
544 e = add_song_ev(SONG_EV_NOTE);
546 e->value = np;
547 e->len = length * staccato;
548 e->vol = volume();
550 /* add arpeggiator repetitions */
551 for (n = 0; n < n_arps; n++) {
553 e = add_song_ev(SONG_EV_NOTE);
555 e->time = cur_time + arps[n].delay;
556 e->trk_id = track + arps[n].track_off;
557 e->value = np + arps[n].transpose;
558 e->len = length * staccato;
559 e->vol = volume() * arps[n].volume;
564 static void add_back_event(void)
566 struct song_ev *e = add_song_ev(SONG_EV_BACK);
568 e->len = length;
572 static void add_tempo_event(int trk_id, double tempo)
574 struct song_ev *e = add_song_ev(SONG_EV_TEMPO);
576 e->trk_id = trk_id;
577 e->amount = tempo;
581 static void add_meter_event(int trk_id, int num, int den)
583 struct song_ev *e = add_song_ev(SONG_EV_METER);
585 e->trk_id = trk_id;
586 e->min = num;
587 e->max = den;
590 static void add_measure_event(void)
592 struct song_ev *e = add_song_ev(SONG_EV_MEASURE);
594 e->trk_id = -1;
595 e->value = yyline;
599 static void add_ss_sustain_event(double sustain)
601 struct song_ev *e = add_song_ev(SONG_EV_SS_SUSTAIN);
603 e->amount = sustain;
607 static void add_ss_attack_event(double attack)
609 struct song_ev *e = add_song_ev(SONG_EV_SS_ATTACK);
611 e->amount = attack;
615 static void add_ss_vibrato_event(double depth, double freq)
617 struct song_ev *e = add_song_ev(SONG_EV_SS_VIBRATO);
619 e->depth = depth;
620 e->freq = freq;
624 static void add_ss_portamento_event(double portamento)
626 struct song_ev *e = add_song_ev(SONG_EV_SS_PORTAMENTO);
628 e->amount = portamento;
632 static void add_ss_channel_event(int channel, float vol)
634 struct song_ev *e = add_song_ev(SONG_EV_SS_CHANNEL);
636 e->channel = channel;
637 e->vol = vol;
641 static void add_ss_wav_event(char * wav_file, int base, int min, int max,
642 double loop_start, double loop_end, int first_channel, int skip_channels)
644 struct song_ev *e = add_song_ev(SONG_EV_SS_WAV);
646 e->name = wav_file;
647 e->value = base;
648 e->min = min;
649 e->max = max;
650 e->start = loop_start;
651 e->end = loop_end;
652 e->channel = first_channel;
653 e->skip_channels = skip_channels;
657 static void add_ss_pat_event(char * pat_file)
659 struct song_ev *e = add_song_ev(SONG_EV_SS_PAT);
661 e->name = pat_file;
665 static void add_ss_eff_event(int type, int channel, double size, float gain,
666 double depth, double freq, double phase, float initial, float final)
668 struct song_ev *e = add_song_ev(type);
670 e->channel = channel;
671 e->len = size;
672 e->vol = gain;
673 e->depth = depth;
674 e->freq = freq;
675 e->phase = phase;
676 e->initial = initial;
677 e->final = final;
681 static void add_ss_pitch_stretch(int note, double len, float vol)
683 struct song_ev *e = add_song_ev(SONG_EV_SS_PITCH_STRETCH);
685 e->value = note;
686 e->len = len;
687 e->vol = vol;
691 static void add_ss_print_wave_tempo(int note, double len)
693 struct song_ev *e = add_song_ev(SONG_EV_SS_PRINT_WAVE_TEMPO);
695 e->value = note;
696 e->len = len;
700 static void add_midi_channel_event(int channel)
702 struct song_ev *e = add_song_ev(SONG_EV_MIDI_CHANNEL);
704 e->channel = channel - 1;
708 static void add_midi_program_event(int program)
710 struct song_ev *e = add_song_ev(SONG_EV_MIDI_PROGRAM);
712 e->value = program;
716 static void add_song_info_event(char * author, char * name)
718 struct song_ev *e = add_song_ev(SONG_EV_SONG_INFO);
720 e->author = author;
721 e->name = name;
725 static void init_track(void)
726 /* sets the default values for a new track */
728 int n;
730 /* is there an end time? test if this is longer */
731 if (cur_time > end_time) {
732 add_mark("END");
733 end_time = cur_time;
736 cur_time = 0.0;
737 length = 0.0;
738 transpose = 0;
739 staccato = 0.8;
740 volume_from = volume_to = 0.75;
741 octave = 5;
742 gliss = 0;
744 /* groups should not cross track boundaries */
745 n_groups = 0;
747 /* reset arpeggiator */
748 n_arps = 0;
749 arp_default();
751 /* is there a START mark? if so, move there */
752 if ((n = seek_mark("START")) != -1)
753 cur_time = marks[n].time;
755 /* reset alterations */
756 for (n = 0; n < 12; n++)
757 alterations[n] = 0;
763 %union {
764 int i;
765 double d;
766 char * p;
769 %token <i> P_INTEGER S_INTEGER
770 %token <d> P_REAL S_REAL
771 %token <i> NOTE_P NOTE_T3 NOTE_T5
772 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
774 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
776 %token <p> ALTSTR
778 %token <p> XC_STR
779 %token <i> XC_ABSNOTE
780 %token <d> XC_MSECS
782 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT
783 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL
785 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
786 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
787 %token SS_EFF_FADER SS_EFF_REVERB
788 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
789 %token SS_EFF_OFF
791 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
793 %token SONG_INFO
795 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
797 %type <i> integer note note_pitch rest back
798 %type <d> real p_number number note_length
800 %type <d> arp_list arp_note
801 %type <i> xc_absnote
805 script:
806 script stmt { ; }
807 | /* NULL */
810 stmt:
811 note {
812 /* note event */
813 add_note_event($1);
814 forward(length);
816 | rest {
817 /* rest */
818 forward(length);
820 | back {
821 /* back */
822 add_back_event();
824 | 'z' note_length {
825 /* zero note */
826 length = $2;
828 | 'o' P_INTEGER {
829 /* absolute octave */
830 octave = $2;
832 | 'o' S_INTEGER {
833 /* relative octave */
834 octave += $2;
836 | 'v' P_INTEGER {
837 /* absolute volume */
838 volume_from = volume_to = (float)$2;
840 | 'v' P_REAL {
841 /* absolute volume */
842 volume_from = volume_to = (float)$2;
844 | 'v' S_REAL {
845 /* relative volume */
846 volume_from += (float)$2;
847 volume_to += (float)$2;
849 | 'v' P_REAL ',' P_REAL {
850 /* absolute volume ranges */
851 volume_from = (float)$2;
852 volume_to = (float)$4;
854 | 't' integer {
855 /* transpose */
856 transpose = $2;
858 | 's' p_number {
859 /* staccato */
860 staccato = $2;
863 | '<' {
864 /* start of group */
865 push_group();
867 | ';' {
868 /* group delimiter */
869 next_group_part();
871 | '>' {
872 /* end of group */
873 pop_group();
875 | 'l' note_length {
876 /* glissando */
877 gliss = $2;
880 | '|' {
881 /* measure mark event */
882 add_measure_event();
885 | NEW_MARK {
886 /* add new mark */
887 add_mark($1);
889 | GOTO_MARK {
890 /* go to mark */
891 find_mark($1, 1);
893 | ASSERT_MARK {
894 /* assert mark */
895 find_mark($1, 0);
898 | '\\' {
899 /* new track */
901 track++;
902 init_track();
904 | 'T' p_number {
905 /* tempo setting */
906 add_tempo_event(-1, $2);
908 | 'M' P_INTEGER '/' P_INTEGER {
909 /* meter (time signature) setting */
910 add_meter_event(-1, $2, $4);
912 | ALTSTR {
913 /* alteration string */
914 set_alteration($1);
917 | BLOCK '*' P_INTEGER {
918 /* repeat block */
919 int n;
921 /* store the block as <TMP> */
922 set_block("<TMP>", $1);
924 for(n = 0;n < $3;n++)
925 insert_block("<TMP>");
927 | BLOCK BLK_ASSIGN {
928 /* assign block */
929 set_block($2, $1);
931 | BLK_INSERT {
932 /* insert block */
933 insert_block($1);
935 | FILE_INSERT {
936 /* insert file */
937 insert_file($1);
940 | arp { ; }
942 | xc_cmd { ; }
946 integer:
947 P_INTEGER { $$ = $1; }
948 | S_INTEGER { $$ = $1; }
951 real:
952 P_REAL { $$ = $1; }
953 | S_REAL { $$ = $1; }
956 p_number:
957 P_INTEGER { $$ = (double) $1; }
958 | P_REAL { $$ = $1; }
961 number:
962 integer { $$ = (double) $1; }
963 | real { $$ = $1; }
966 note:
967 note_pitch { $$ = $1; }
968 | note note_length { $$ = $1; length=$2; }
969 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
972 note_pitch:
973 NOTE_P { $$ = $1; }
974 | note_pitch '&' { $$ = $1 - 1; }
975 | note_pitch '#' { $$ = $1 + 1; }
976 | note_pitch '\'' { $$ = $1 + 12; }
977 | note_pitch ',' { $$ = $1 - 12; }
980 note_length:
981 P_INTEGER { $$ = 1 / (double) $1; }
982 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
983 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
984 | note_length '*' p_number { $$ = $1 * $3; }
985 | note_length '.' { $$ = $1 * 1.5; }
988 rest:
989 'r' { ; }
990 | rest note_length {
991 /* rest with length */
992 length = $2;
996 back:
997 'k' { ; }
998 | back note_length {
999 /* back with length */
1000 length = $2;
1004 arp:
1005 'x' {
1006 /* empty arpeggiator */
1007 n_arps = 0;
1008 arp_default();
1010 | 'x' arp_list { ; }
1013 arp_list:
1014 arp_note {
1015 /* first arpeggiator note */
1016 n_arps = 0;
1017 add_arp();
1019 | arp_list ',' arp_note {
1020 /* rest of arpeggiator notes */
1021 add_arp();
1025 arp_note:
1026 note_length {
1027 /* arpeggiator delay */
1028 arp_delay = $1;
1030 | arp_note '~' number {
1031 /* arpeggiator volume */
1032 arp_volume = (float)$3;
1034 | arp_note S_INTEGER {
1035 /* arpeggiator transpose */
1036 arp_transpose = $2;
1038 | arp_note '/' P_INTEGER {
1039 /* arpeggiator track offset */
1040 arp_track_off = $3;
1042 | arp_note NOTE_T3 {
1043 /* HACK: /3 */
1044 arp_track_off = 3;
1046 | arp_note NOTE_T5 {
1047 /* HACK: /5 */
1048 arp_track_off = 5;
1052 xc_absnote:
1053 P_INTEGER { $$ = $1; }
1054 | XC_ABSNOTE { $$ = $1; }
1057 xc_cmd:
1058 SS_WAV XC_STR xc_absnote {
1059 /* load .wav file with just one note */
1060 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1062 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1063 /* load .wav file */
1064 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1066 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1067 /* load .wav file, with loop boundaries */
1068 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1070 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1071 /* load .wav file, with loop boundaries,
1072 first channel and skip channels */
1073 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1075 | SS_PAT XC_STR {
1076 /* load .pat file */
1077 add_ss_pat_event($2);
1079 | SS_SUSTAIN XC_MSECS {
1080 /* sets sustain */
1081 add_ss_sustain_event($2);
1083 | SS_ATTACK XC_MSECS {
1084 /* sets attack */
1085 add_ss_attack_event($2);
1087 | SS_VIBRATO XC_MSECS number {
1088 /* sets vibrato */
1089 add_ss_vibrato_event($2, $3);
1091 | SS_PORTAMENTO number {
1092 /* sets portamento */
1093 add_ss_portamento_event($2);
1095 | SS_CHANNEL integer number {
1096 /* sets volume for a channel */
1097 add_ss_channel_event($2, $3);
1099 | SS_VOL number number {
1100 /* set vol for 2 channels */
1101 add_ss_channel_event(0, $2);
1102 add_ss_channel_event(1, $3);
1104 | SS_VOL number number number {
1105 /* set vol for 3 channels */
1106 add_ss_channel_event(0, $2);
1107 add_ss_channel_event(1, $3);
1108 add_ss_channel_event(2, $4);
1110 | SS_VOL number number number number {
1111 /* set vol for 4 channels */
1112 add_ss_channel_event(0, $2);
1113 add_ss_channel_event(1, $3);
1114 add_ss_channel_event(2, $4);
1115 add_ss_channel_event(3, $5);
1117 | SS_VOL number number number number number number {
1118 /* set vol for 6 channels */
1119 add_ss_channel_event(0, $2);
1120 add_ss_channel_event(1, $3);
1121 add_ss_channel_event(2, $4);
1122 add_ss_channel_event(3, $5);
1123 add_ss_channel_event(4, $6);
1124 add_ss_channel_event(5, $7);
1126 | SS_EFF_DELAY integer XC_MSECS {
1127 /* delay effect */
1128 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1129 $2, $3, 0, 0, 0, 0, 0, 0);
1132 | SS_EFF_ECHO integer XC_MSECS number {
1133 /* echo effect */
1134 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1135 $2, $3, $4, 0, 0, 0, 0, 0);
1138 | SS_EFF_COMB integer XC_MSECS number {
1139 /* comb effect */
1140 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1141 $2, $3, $4, 0, 0, 0, 0, 0);
1144 | SS_EFF_ALLPASS integer XC_MSECS number {
1145 /* allpass effect */
1146 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1147 $2, $3, $4, 0, 0, 0, 0, 0);
1150 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1151 /* flanger effect */
1152 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1153 $2, $3, $4, $5, $6, $7, 0, 0);
1156 | SS_EFF_WOBBLE integer number number {
1157 /* wobble effect */
1158 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1159 $2, 0, 0.8, 0, $3, $4, 0, 0);
1162 | SS_EFF_WOBBLE integer number number number {
1163 /* wobble effect, with gain */
1164 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1165 $2, 0, $5, 0, $3, $4, 0, 0);
1168 | SS_EFF_SQWOBBLE integer number number {
1169 /* square wobble effect */
1170 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1171 $2, 0, 0, 0, $3, $4, 0, 0);
1174 | SS_EFF_HFWOBBLE integer number number {
1175 /* half wobble effect */
1176 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1177 $2, 0, 0, 0, $3, $4, 0, 0);
1180 | SS_EFF_FADER integer XC_MSECS number number {
1181 /* fader effect */
1182 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1183 $2, $3, 0, 0, 0, 0, $4, $5);
1186 | SS_EFF_REVERB integer {
1187 /* reverb effect */
1188 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1189 $2, 0, 0, 0, 0, 0, 0, 0);
1192 | SS_EFF_FOLDBACK integer number {
1193 /* foldback distortion effect */
1194 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1195 $2, 0, $3, 0, 0, 0, 0, 0);
1197 | SS_EFF_ATAN integer number {
1198 /* atan distortion effect */
1199 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1200 $2, 0, $3, 0, 0, 0, 0, 0);
1202 | SS_EFF_DISTORT integer number {
1203 /* distort distortion effect */
1204 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1205 $2, 0, $3, 0, 0, 0, 0, 0);
1207 | SS_EFF_OVERDRIVE integer number {
1208 /* overdrive distortion effect */
1209 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1210 $2, 0, $3, 0, 0, 0, 0, 0);
1213 | SS_EFF_OFF integer {
1214 /* off effect */
1215 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1216 $2, 0, 0, 0, 0, 0, 0, 0);
1219 | SS_PITCH_STRETCH xc_absnote number number {
1220 /* pitch stretch note */
1221 add_ss_pitch_stretch($2, $3, $4);
1223 forward($3);
1226 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1227 /* print tempo from wave */
1228 add_ss_print_wave_tempo($2, $3);
1231 | SONG_INFO XC_STR XC_STR {
1232 /* add song info */
1233 add_song_info_event($2, $3);
1236 | MIDI_CHANNEL integer {
1237 /* midi channel */
1238 add_midi_channel_event($2);
1241 | MIDI_PROGRAM integer {
1242 /* midi program */
1243 add_midi_program_event($2);
1249 void yyerror(char * s)
1251 c_err(s, NULL, NULL);
1255 #define set_block_d(n,b) set_block(n,strdup(b))
1257 static void compile_startup(void)
1259 track = 0;
1260 yyline = 1;
1261 compiler_error = 0;
1263 /* default settings */
1264 add_tempo_event(-2, 120.0);
1265 add_meter_event(-2, 4, 4);
1266 init_track();
1268 /* standard tonalities */
1269 set_block_d("CM", "A"); set_block_d("Am", "$CM");
1270 set_block_d("C#M", "A#######"); set_block_d("A#m", "$C#M");
1271 set_block_d("DM", "A#--#---"); set_block_d("Bm", "$DM");
1272 set_block_d("E&M", "A--&--&&"); set_block_d("Cm", "$E&M");
1273 set_block_d("EM", "A##-##--"); set_block_d("C#m", "$EM");
1274 set_block_d("FM", "A------&"); set_block_d("Dm", "$FM");
1275 set_block_d("F#M", "A######-"); set_block_d("D#m", "$F#M");
1276 set_block_d("GM", "A---#---"); set_block_d("Em", "$GM");
1277 set_block_d("A&M", "A-&&--&&"); set_block_d("Fm", "$A&M");
1278 set_block_d("AM", "A#--##--"); set_block_d("F#m", "$AM");
1279 set_block_d("B&M", "A--&---&"); set_block_d("Gm", "$B&M");
1280 set_block_d("BM", "A##-###-"); set_block_d("G#m", "$BM");
1284 static int do_parse(void)
1286 int r = yyparse();
1288 return r + compiler_error;
1292 int compile_ahs_string(char * code)
1294 compile_startup();
1296 push_code(strdup(code));
1298 return do_parse();
1302 int compile_ahs(char * file)
1304 compile_startup();
1306 if (insert_file(file))
1307 return 1;
1309 return do_parse();