Tweaked CFLAGS detection in config.sh.
[ahxm.git] / compiler.y
blob89a88128f7f8e2fa42f3f05865735e8c38780b9b
1 %{
2 /*
4 Ann Hell Ex Machina - Music Software
5 Copyright (C) 2003/2008 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"
37 /** data **/
39 int yylex(void);
40 void yyerror(const char *s);
42 /* injecting code functions (defined in compiler.l) */
43 int push_code(const char *code);
44 int push_code_from_file(const char *file);
46 /* current track */
47 int track;
49 /* current time */
50 double cur_time = 0.0;
52 /* end time (longest time seen) */
53 double end_time = 0.0;
55 /* note globals */
56 static double length;
57 static int octave;
58 static int transpose;
59 static double staccato;
60 static sample_t volume_from;
61 static sample_t volume_to;
62 static double gliss;
64 /* parser debugging */
66 #define DEBUGF if(verbose >= 2)printf
68 /* blocks */
70 struct block {
71 const char *name;
72 int n_sblocks;
73 char **sblocks;
76 static struct block *blocks = NULL;
77 static int n_blocks = 0;
79 /* group info */
80 struct group {
81 double start;
82 double gliss;
83 double max;
86 static struct group *groups = NULL;
87 static int n_groups = 0;
88 static int groups_size = 0;
90 /* mark info */
91 struct mark {
92 const char *name;
93 double time;
96 static struct mark *marks = NULL;
97 static int n_marks = 0;
99 /* arpeggiator */
100 struct arp {
101 double delay;
102 int transpose;
103 sample_t volume;
104 int track_off;
107 static struct arp *arps = NULL;
108 static int n_arps = 0;
109 static int arps_size = 0;
111 static double arp_delay;
112 static int arp_transpose;
113 static sample_t arp_volume;
114 static int arp_track_off;
116 int compiler_error = 0;
118 extern int yyline;
120 /* alterations for each note */
121 int alterations[12];
123 /* random seeds */
124 unsigned int block_seed = 0;
125 unsigned int volume_seed = 0;
127 /* solo track (-1, no solo) */
128 int solo_track = -1;
131 /** code **/
133 unsigned int ah_rnd(unsigned int *seed)
134 /* special randomizer */
136 *seed = (*seed * 58321) + 11113;
138 return *seed >> 16;
142 void c_err(const char *e1, const char *e2, const char *e3)
143 /* reports an error from the compiler */
145 printf("ahxm:");
147 if (e1 != NULL)
148 printf(" %s", e1);
149 if (e2 != NULL)
150 printf(" %s", e2);
151 if (e3 != NULL)
152 printf(" %s", e3);
154 printf(" in line %d\n", yyline);
156 compiler_error++;
160 static void forward(double step)
161 /* moves forward current time */
163 /* add step */
164 cur_time += step;
166 /* quantizations could be done here */
170 static sample_t volume(void)
172 sample_t f;
174 if (volume_from == volume_to)
175 f = volume_from;
176 else {
177 unsigned int r = ah_rnd(&volume_seed) % 1000;
179 f = volume_from + (volume_to - volume_from) *
180 (((sample_t) r) / 1000.0);
183 return f;
187 /* blocks */
189 static int find_block(const char *name)
190 /* finds a block */
192 int n;
194 for (n = 0; n < n_blocks; n++) {
195 if (strcmp(name, blocks[n].name) == 0)
196 return n;
199 return -1;
203 static int set_block(const char *name, char *block)
204 /* defines a block */
206 int n;
207 struct block *b;
208 char *start;
209 char *stop;
211 /* if block already exists, free it */
212 if ((n = find_block(name)) >= 0) {
213 b = &blocks[n];
215 /* free all subblocks */
216 for (n = 0; n < b->n_sblocks; n++)
217 free(b->sblocks[n]);
219 /* free the subblock array */
220 free(b->sblocks);
222 else {
223 GROW(blocks, n_blocks, struct block);
224 b = &blocks[n_blocks++];
226 b->name = strdup(name);
229 /* reset */
230 b->n_sblocks = 0;
231 b->sblocks = NULL;
233 /* now split in subblocks (delimited by : ) */
234 start = block;
236 while ((stop = strchr(start, ':')) != NULL) {
237 /* break there */
238 *stop = '\0';
240 /* add the subblock */
241 GROW(b->sblocks, b->n_sblocks, char *);
242 b->sblocks[b->n_sblocks++] = strdup(start);
244 start = stop + 1;
247 /* no more separators? store the rest */
248 GROW(b->sblocks, b->n_sblocks, char *);
249 b->sblocks[b->n_sblocks++] = strdup(start);
251 /* the original block is no longer needed */
252 free(block);
254 return 1;
258 static void insert_block(const char *name)
259 /* inserts a block */
261 int n;
263 if ((n = find_block(name)) >= 0) {
264 struct block *b;
266 b = &blocks[n];
268 /* get one of them, randomly */
269 n = ah_rnd(&block_seed) % b->n_sblocks;
271 push_code(strdup(b->sblocks[n]));
273 else
274 c_err("block-not-found", name, NULL);
278 static int insert_file(const char *filename)
280 if (!push_code_from_file(filename)) {
281 c_err("script-not-found", filename, NULL);
282 return 1;
285 return 0;
289 /* groups */
291 static int push_group(void)
292 /* starts a new group of notes */
294 struct group *g;
296 if (n_groups == groups_size) {
297 GROW(groups, groups_size, struct group);
298 groups_size++;
301 g = &groups[n_groups++];
303 g->start = cur_time;
304 g->gliss = 0.0;
305 g->max = 0.0;
307 return 1;
311 static int next_group_part(void)
312 /* part delimiter */
314 struct group *g;
316 if (n_groups == 0) {
317 c_err("missing-start-of-group", NULL, NULL);
318 return 0;
321 g = &groups[n_groups - 1];
323 /* store maximum frame */
324 if (g->max < cur_time)
325 g->max = cur_time;
327 /* add glissando delay */
328 g->gliss += gliss;
330 /* rewind */
331 cur_time = g->start + g->gliss;
333 return 1;
337 static int pop_group(void)
338 /* finishes a group, moving the frame to the end of the longer part */
340 if (n_groups == 0) {
341 c_err("missing-start-of-group", NULL, NULL);
342 return 0;
345 n_groups--;
347 /* if other parts of group were longer than the last one,
348 move pointer there */
349 if (groups[n_groups].max > cur_time)
350 cur_time = groups[n_groups].max;
352 return 1;
356 /* marks */
358 static int seek_mark(const char *name)
359 /* seeks a mark by name; returns its offset or -1 */
361 int n;
363 for (n = 0; n < n_marks; n++)
364 if (strcmp(marks[n].name, name) == 0)
365 return n;
367 return -1;
371 static void add_mark(const char *name)
372 /* creates a new mark */
374 int n;
376 if ((n = seek_mark(name)) == -1) {
377 n = n_marks++;
378 GROW(marks, n, struct mark);
379 marks[n].name = strdup(name);
382 marks[n].time = cur_time;
386 static void find_mark(const char *name, int set)
387 /* finds a mark by name, optionally moving time cursor there */
389 int n;
391 if ((n = seek_mark(name)) != -1) {
392 if (set) {
393 if (cur_time > marks[n].time) {
394 /* if mark is not END, fail */
395 if (strcmp(name, "END") != 0)
396 c_err("mark-overpassed", name, NULL);
398 else
399 cur_time = marks[n].time;
401 else
402 if (cur_time != marks[n].time)
403 c_err("mark-mismatch", name, NULL);
405 return;
408 c_err("mark-not-found", name, NULL);
412 /* arpeggiator */
414 static void arp_default(void)
415 /* resets arpeggiator values to the default ones */
417 arp_delay = 0.0;
418 arp_transpose = 0;
419 arp_volume = 1.0;
420 arp_track_off = 0;
424 static void add_arp(void)
425 /* adds an arpeggiator note */
427 struct arp *a;
429 /* if the note is exactly the same, do nothing */
430 if (arp_delay == 0.0 && arp_transpose == 0 &&
431 arp_volume == 1.0 && arp_track_off == 0)
432 return;
434 if (n_arps == arps_size) {
435 GROW(arps, arps_size, struct arp);
436 arps_size++;
439 a = &arps[n_arps];
441 a->delay = arp_delay;
442 a->transpose = arp_transpose;
443 a->volume = arp_volume;
444 a->track_off = arp_track_off;
446 n_arps++;
447 arp_default();
451 static void set_alteration(const char *altstr)
452 /* sets the alterations from altstr */
454 int n, steps[] = { 2, 0, 2, 0, 1, 2, 0, 2, 0, 2, 0, 1 };
456 /* reset alterations */
457 for (n = 0; n < 12; n++)
458 alterations[n] = 0;
460 /* changed according the altstr spec */
461 for (n = 0; *altstr != '\0' && n < 12; altstr++) {
462 switch (*altstr) {
463 case '&':
464 alterations[n] = -1;
465 break;
467 case '#':
468 alterations[n] = 1;
469 break;
472 /* move to next natural note */
473 n += steps[n];
478 /* song events */
480 static struct song_ev *add_song_ev(song_ev_type type)
482 struct song_ev *r;
484 r = add_event(&song, &n_song_ev);
486 r->type = type;
487 r->time = cur_time;
488 r->trk_id = track;
489 r->event_id = n_song_ev - 1;
491 return r;
495 static void add_note_event(int note)
496 /* adds a note event */
498 int n;
499 int np;
500 struct song_ev *e;
502 /* sum the alteration */
503 if ((n = note % 12) < 0)
504 n += 12;
506 note += alterations[n];
508 /* calculate the note */
509 np = note + transpose + (octave * 12);
511 /* is note out of range? */
512 if (np < 0 || np > 127) {
513 c_err("note-out-of-range", NULL, NULL);
514 return;
517 e = add_song_ev(SONG_EV_NOTE);
519 e->value = np;
520 e->len = length * staccato;
521 e->vol = volume();
523 /* add arpeggiator repetitions */
524 for (n = 0; n < n_arps; n++) {
526 e = add_song_ev(SONG_EV_NOTE);
528 e->time = cur_time + arps[n].delay;
529 e->trk_id = track + arps[n].track_off;
530 e->value = np + arps[n].transpose;
531 e->len = length * staccato;
532 e->vol = volume() * arps[n].volume;
537 static void add_back_event(void)
539 struct song_ev *e = add_song_ev(SONG_EV_BACK);
541 e->len = length;
545 static void add_tempo_event(int trk_id, double tempo)
547 struct song_ev *e = add_song_ev(SONG_EV_TEMPO);
549 e->trk_id = trk_id;
550 e->amount = tempo;
554 static void add_meter_event(int trk_id, int num, int den)
556 struct song_ev *e = add_song_ev(SONG_EV_METER);
558 e->trk_id = trk_id;
559 e->min = num;
560 e->max = den;
563 static void add_measure_event(void)
565 struct song_ev *e = add_song_ev(SONG_EV_MEASURE);
567 e->trk_id = -1;
568 e->value = yyline;
572 static void add_ss_sustain_event(double sustain)
574 struct song_ev *e = add_song_ev(SONG_EV_SS_SUSTAIN);
576 e->amount = sustain;
580 static void add_ss_attack_event(double attack)
582 struct song_ev *e = add_song_ev(SONG_EV_SS_ATTACK);
584 e->amount = attack;
588 static void add_ss_vibrato_event(double depth, double freq)
590 struct song_ev *e = add_song_ev(SONG_EV_SS_VIBRATO);
592 e->depth = depth;
593 e->freq = freq;
597 static void add_ss_portamento_event(double portamento)
599 struct song_ev *e = add_song_ev(SONG_EV_SS_PORTAMENTO);
601 e->amount = portamento;
605 static void add_ss_channel_event(int channel, sample_t vol)
607 struct song_ev *e = add_song_ev(SONG_EV_SS_CHANNEL);
609 e->channel = channel;
610 e->vol = vol;
614 static void add_ss_wav_event(const char *wav_file, int base, int min,
615 int max, double loop_start, double loop_end,
616 int first_channel, int skip_channels)
618 struct song_ev *e = add_song_ev(SONG_EV_SS_WAV);
620 e->name = wav_file;
621 e->value = base;
622 e->min = min;
623 e->max = max;
624 e->start = loop_start;
625 e->end = loop_end;
626 e->channel = first_channel;
627 e->skip_channels = skip_channels;
631 static void add_ss_pat_event(const char *pat_file)
633 struct song_ev *e = add_song_ev(SONG_EV_SS_PAT);
635 e->name = pat_file;
639 static void add_ss_sf2_event(const char *sf2_file, const char *insname)
641 struct song_ev *e = add_song_ev(SONG_EV_SS_SF2);
643 e->name = sf2_file;
644 e->str2 = insname;
648 static void add_ss_eff_event(int type, int channel, double size,
649 sample_t gain, double depth, double freq,
650 double phase, sample_t initial,
651 sample_t final)
653 struct song_ev *e = add_song_ev(type);
655 e->channel = channel;
656 e->len = size;
657 e->vol = gain;
658 e->depth = depth;
659 e->freq = freq;
660 e->phase = phase;
661 e->initial = initial;
662 e->final = final;
666 static void add_ss_pitch_stretch(int note, double len, sample_t vol)
668 struct song_ev *e = add_song_ev(SONG_EV_SS_PITCH_STRETCH);
670 e->value = note;
671 e->len = len;
672 e->vol = vol;
676 static void add_ss_print_wave_tempo(int note, double len)
678 struct song_ev *e = add_song_ev(SONG_EV_SS_PRINT_WAVE_TEMPO);
680 e->value = note;
681 e->len = len;
685 static void add_ss_master_volume(sample_t vol)
687 struct song_ev *e = add_song_ev(SONG_EV_SS_MASTER_VOLUME);
689 e->trk_id = -1;
690 e->vol = vol;
694 static void add_midi_channel_event(int channel)
696 struct song_ev *e = add_song_ev(SONG_EV_MIDI_CHANNEL);
698 e->channel = channel - 1;
702 static void add_midi_program_event(int program)
704 struct song_ev *e = add_song_ev(SONG_EV_MIDI_PROGRAM);
706 e->value = program;
710 static void add_song_info_event(const char *author, const char *name)
712 struct song_ev *e = add_song_ev(SONG_EV_SONG_INFO);
714 e->str2 = author;
715 e->name = name;
719 static void init_track(void)
720 /* sets the default values for a new track */
722 int n;
724 /* is there an end time? test if this is longer */
725 if (cur_time > end_time) {
726 add_mark("END");
727 end_time = cur_time;
730 cur_time = 0.0;
731 length = 0.0;
732 transpose = 0;
733 staccato = 0.8;
734 volume_from = volume_to = 0.75;
735 octave = 5;
736 gliss = 0;
738 /* groups should not cross track boundaries */
739 n_groups = 0;
741 /* reset arpeggiator */
742 n_arps = 0;
743 arp_default();
745 /* is there a START mark? if so, move there */
746 if ((n = seek_mark("START")) != -1)
747 cur_time = marks[n].time;
749 /* reset alterations */
750 for (n = 0; n < 12; n++)
751 alterations[n] = 0;
756 %union {
757 int i;
758 double d;
759 char * p;
762 %token <i> P_INTEGER S_INTEGER
763 %token <d> P_REAL S_REAL
764 %token <i> NOTE_P NOTE_T3 NOTE_T5
765 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
767 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
769 %token <p> ALTSTR
771 %token <p> LIBPATH_ADD
773 %token <p> XC_STR
774 %token <i> XC_ABSNOTE
775 %token <d> XC_MSECS
777 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT SS_SF2
778 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL SS_MASTER_VOL
780 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
781 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
782 %token SS_EFF_FADER SS_EFF_REVERB
783 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
784 %token SS_EFF_OFF
786 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
788 %token SONG_INFO
790 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
792 %type <i> integer note note_pitch rest back
793 %type <d> real p_number number note_length
795 %type <d> arp_list arp_note
796 %type <i> xc_absnote
800 script:
801 script stmt { ; }
802 | /* NULL */
805 stmt:
806 note {
807 /* note event */
808 add_note_event($1);
809 forward(length);
811 | rest {
812 /* rest */
813 forward(length);
815 | back {
816 /* back */
817 add_back_event();
819 | 'z' note_length {
820 /* zero note */
821 length = $2;
823 | 'o' P_INTEGER {
824 /* absolute octave */
825 octave = $2;
827 | 'o' S_INTEGER {
828 /* relative octave */
829 octave += $2;
831 | 'v' P_INTEGER {
832 /* absolute volume */
833 volume_from = volume_to = $2;
835 | 'v' P_REAL {
836 /* absolute volume */
837 volume_from = volume_to = $2;
839 | 'v' S_REAL {
840 /* relative volume */
841 volume_from += $2;
842 volume_to += $2;
844 | 'v' P_REAL ',' P_REAL {
845 /* absolute volume ranges */
846 volume_from = $2;
847 volume_to = $4;
849 | 't' integer {
850 /* transpose */
851 transpose = $2;
853 | 's' p_number {
854 /* staccato */
855 staccato = $2;
858 | '<' {
859 /* start of group */
860 push_group();
862 | ';' {
863 /* group delimiter */
864 next_group_part();
866 | '>' {
867 /* end of group */
868 pop_group();
870 | 'l' note_length {
871 /* glissando */
872 gliss = $2;
875 | '|' {
876 /* measure mark event */
877 add_measure_event();
880 | NEW_MARK {
881 /* add new mark */
882 add_mark($1);
884 | GOTO_MARK {
885 /* go to mark */
886 find_mark($1, 1);
888 | ASSERT_MARK {
889 /* assert mark */
890 find_mark($1, 0);
893 | '\\' {
894 /* new track */
896 track++;
897 init_track();
899 | 'T' p_number {
900 /* tempo setting */
901 add_tempo_event(-1, $2);
903 | 'M' P_INTEGER '/' P_INTEGER {
904 /* meter (time signature) setting */
905 add_meter_event(-1, $2, $4);
907 | ALTSTR {
908 /* alteration string */
909 set_alteration($1);
912 | BLOCK '*' P_INTEGER {
913 /* repeat block */
914 int n;
916 /* store the block as <TMP> */
917 set_block("<TMP>", $1);
919 for(n = 0;n < $3;n++)
920 insert_block("<TMP>");
922 | BLOCK BLK_ASSIGN {
923 /* assign block */
924 set_block($2, $1);
926 | BLK_INSERT {
927 /* insert block */
928 insert_block($1);
930 | FILE_INSERT {
931 /* insert file */
932 insert_file($1);
934 | LIBPATH_ADD {
935 /* add library path */
936 libpath_add($1, 0);
939 | arp { ; }
941 | xc_cmd { ; }
945 integer:
946 P_INTEGER { $$ = $1; }
947 | S_INTEGER { $$ = $1; }
950 real:
951 P_REAL { $$ = $1; }
952 | S_REAL { $$ = $1; }
955 p_number:
956 P_INTEGER { $$ = (double) $1; }
957 | P_REAL { $$ = $1; }
960 number:
961 integer { $$ = (double) $1; }
962 | real { $$ = $1; }
965 note:
966 note_pitch { $$ = $1; }
967 | note note_length { $$ = $1; length=$2; }
968 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
971 note_pitch:
972 NOTE_P { $$ = $1; }
973 | note_pitch '&' { $$ = $1 - 1; }
974 | note_pitch '#' { $$ = $1 + 1; }
975 | note_pitch '\'' { $$ = $1 + 12; }
976 | note_pitch ',' { $$ = $1 - 12; }
979 note_length:
980 P_INTEGER { $$ = 1 / (double) $1; }
981 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
982 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
983 | note_length '*' p_number { $$ = $1 * $3; }
984 | note_length '.' { $$ = $1 * 1.5; }
987 rest:
988 'r' { ; }
989 | rest note_length {
990 /* rest with length */
991 length = $2;
995 back:
996 'k' { ; }
997 | back note_length {
998 /* back with length */
999 length = $2;
1003 arp:
1004 'x' {
1005 /* empty arpeggiator */
1006 n_arps = 0;
1007 arp_default();
1009 | 'x' arp_list { ; }
1012 arp_list:
1013 arp_note {
1014 /* first arpeggiator note */
1015 n_arps = 0;
1016 add_arp();
1018 | arp_list ',' arp_note {
1019 /* rest of arpeggiator notes */
1020 add_arp();
1024 arp_note:
1025 note_length {
1026 /* arpeggiator delay */
1027 arp_delay = $1;
1029 | arp_note '~' number {
1030 /* arpeggiator volume */
1031 arp_volume = $3;
1033 | arp_note S_INTEGER {
1034 /* arpeggiator transpose */
1035 arp_transpose = $2;
1037 | arp_note '/' P_INTEGER {
1038 /* arpeggiator track offset */
1039 arp_track_off = $3;
1041 | arp_note NOTE_T3 {
1042 /* HACK: /3 */
1043 arp_track_off = 3;
1045 | arp_note NOTE_T5 {
1046 /* HACK: /5 */
1047 arp_track_off = 5;
1051 xc_absnote:
1052 P_INTEGER { $$ = $1; }
1053 | XC_ABSNOTE { $$ = $1; }
1056 xc_cmd:
1057 SS_WAV XC_STR xc_absnote {
1058 /* load .wav file with just one note */
1059 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1061 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1062 /* load .wav file */
1063 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1065 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1066 /* load .wav file, with loop boundaries */
1067 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1069 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1070 /* load .wav file, with loop boundaries,
1071 first channel and skip channels */
1072 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1074 | SS_PAT XC_STR {
1075 /* load .pat file */
1076 add_ss_pat_event($2);
1078 | SS_SF2 XC_STR {
1079 /* list instruments in .sf2 file */
1080 add_ss_sf2_event($2, NULL);
1082 | SS_SF2 XC_STR XC_STR {
1083 /* load instrument from .sf2 file */
1084 add_ss_sf2_event($2, $3);
1087 | SS_SUSTAIN XC_MSECS {
1088 /* sets sustain */
1089 add_ss_sustain_event($2);
1091 | SS_ATTACK XC_MSECS {
1092 /* sets attack */
1093 add_ss_attack_event($2);
1095 | SS_VIBRATO XC_MSECS number {
1096 /* sets vibrato */
1097 add_ss_vibrato_event($2, $3);
1099 | SS_PORTAMENTO number {
1100 /* sets portamento */
1101 add_ss_portamento_event($2);
1103 | SS_CHANNEL integer number {
1104 /* sets volume for a channel */
1105 add_ss_channel_event($2, $3);
1107 | SS_VOL number number {
1108 /* set vol for 2 channels */
1109 add_ss_channel_event(0, $2);
1110 add_ss_channel_event(1, $3);
1112 | SS_VOL number number number {
1113 /* set vol for 3 channels */
1114 add_ss_channel_event(0, $2);
1115 add_ss_channel_event(1, $3);
1116 add_ss_channel_event(2, $4);
1118 | SS_VOL number number number number {
1119 /* set vol for 4 channels */
1120 add_ss_channel_event(0, $2);
1121 add_ss_channel_event(1, $3);
1122 add_ss_channel_event(2, $4);
1123 add_ss_channel_event(3, $5);
1125 | SS_VOL number number number number number number {
1126 /* set vol for 6 channels */
1127 add_ss_channel_event(0, $2);
1128 add_ss_channel_event(1, $3);
1129 add_ss_channel_event(2, $4);
1130 add_ss_channel_event(3, $5);
1131 add_ss_channel_event(4, $6);
1132 add_ss_channel_event(5, $7);
1134 | SS_EFF_DELAY integer XC_MSECS {
1135 /* delay effect */
1136 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1137 $2, $3, 0, 0, 0, 0, 0, 0);
1140 | SS_EFF_ECHO integer XC_MSECS number {
1141 /* echo effect */
1142 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1143 $2, $3, $4, 0, 0, 0, 0, 0);
1146 | SS_EFF_COMB integer XC_MSECS number {
1147 /* comb effect */
1148 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1149 $2, $3, $4, 0, 0, 0, 0, 0);
1152 | SS_EFF_ALLPASS integer XC_MSECS number {
1153 /* allpass effect */
1154 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1155 $2, $3, $4, 0, 0, 0, 0, 0);
1158 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1159 /* flanger effect */
1160 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1161 $2, $3, $4, $5, $6, $7, 0, 0);
1164 | SS_EFF_WOBBLE integer number number {
1165 /* wobble effect */
1166 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1167 $2, 0, 0.8, 0, $3, $4, 0, 0);
1170 | SS_EFF_WOBBLE integer number number number {
1171 /* wobble effect, with gain */
1172 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1173 $2, 0, $5, 0, $3, $4, 0, 0);
1176 | SS_EFF_SQWOBBLE integer number number {
1177 /* square wobble effect */
1178 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1179 $2, 0, 0, 0, $3, $4, 0, 0);
1182 | SS_EFF_HFWOBBLE integer number number {
1183 /* half wobble effect */
1184 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1185 $2, 0, 0, 0, $3, $4, 0, 0);
1188 | SS_EFF_FADER integer XC_MSECS number number {
1189 /* fader effect */
1190 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1191 $2, $3, 0, 0, 0, 0, $4, $5);
1194 | SS_EFF_REVERB integer {
1195 /* reverb effect */
1196 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1197 $2, 0, 0, 0, 0, 0, 0, 0);
1200 | SS_EFF_FOLDBACK integer number {
1201 /* foldback distortion effect */
1202 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1203 $2, 0, $3, 0, 0, 0, 0, 0);
1205 | SS_EFF_ATAN integer number {
1206 /* atan distortion effect */
1207 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1208 $2, 0, $3, 0, 0, 0, 0, 0);
1210 | SS_EFF_DISTORT integer number {
1211 /* distort distortion effect */
1212 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1213 $2, 0, $3, 0, 0, 0, 0, 0);
1215 | SS_EFF_OVERDRIVE integer number {
1216 /* overdrive distortion effect */
1217 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1218 $2, 0, $3, 0, 0, 0, 0, 0);
1221 | SS_EFF_OFF integer {
1222 /* off effect */
1223 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1224 $2, 0, 0, 0, 0, 0, 0, 0);
1227 | SS_PITCH_STRETCH xc_absnote number number {
1228 /* pitch stretch note */
1229 add_ss_pitch_stretch($2, $3, $4);
1231 forward($3);
1234 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1235 /* print tempo from wave */
1236 add_ss_print_wave_tempo($2, $3);
1239 | SS_MASTER_VOL number {
1240 /* set master volume */
1241 add_ss_master_volume($2);
1244 | SONG_INFO XC_STR XC_STR {
1245 /* add song info */
1246 add_song_info_event($2, $3);
1249 | MIDI_CHANNEL integer {
1250 /* midi channel */
1251 add_midi_channel_event($2);
1254 | MIDI_PROGRAM integer {
1255 /* midi program */
1256 add_midi_program_event($2);
1262 void yyerror(const char *s)
1264 c_err(s, NULL, NULL);
1268 #define set_block_d(n,b) set_block(n,strdup(b))
1270 static void compile_startup(void)
1272 track = 0;
1273 yyline = 1;
1274 compiler_error = 0;
1276 /* default settings */
1277 add_tempo_event(-2, 120.0);
1278 add_meter_event(-2, 4, 4);
1279 init_track();
1281 /* standard tonalities */
1282 set_block_d("CM", "A");
1283 set_block_d("Am", "$CM");
1284 set_block_d("C#M", "A#######");
1285 set_block_d("A#m", "$C#M");
1286 set_block_d("DM", "A#--#---");
1287 set_block_d("Bm", "$DM");
1288 set_block_d("E&M", "A--&--&&");
1289 set_block_d("Cm", "$E&M");
1290 set_block_d("EM", "A##-##--");
1291 set_block_d("C#m", "$EM");
1292 set_block_d("FM", "A------&");
1293 set_block_d("Dm", "$FM");
1294 set_block_d("F#M", "A######-");
1295 set_block_d("D#m", "$F#M");
1296 set_block_d("GM", "A---#---");
1297 set_block_d("Em", "$GM");
1298 set_block_d("A&M", "A-&&--&&");
1299 set_block_d("Fm", "$A&M");
1300 set_block_d("AM", "A#--##--");
1301 set_block_d("F#m", "$AM");
1302 set_block_d("B&M", "A--&---&");
1303 set_block_d("Gm", "$B&M");
1304 set_block_d("BM", "A##-###-");
1305 set_block_d("G#m", "$BM");
1309 static int do_parse(void)
1311 int r = yyparse() + compiler_error;
1313 if (solo_track != -1)
1314 mute_tracks(-solo_track);
1316 return r;
1320 int compile_ahs_string(const char *code)
1322 compile_startup();
1324 push_code(strdup(code));
1326 return do_parse();
1330 int compile_ahs(const char *file)
1332 compile_startup();
1334 if (insert_file(file))
1335 return 1;
1337 return do_parse();