Added an abstract to mp_doccer documents.
[ahxm.git] / compiler.y
blob2a9f948190fb311d19e602702f8993e15ca5845f
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"
36 /*******************
37 Data
38 ********************/
40 int yylex(void);
41 void yyerror(const char * s);
43 /* injecting code functions (defined in compiler.l) */
44 int push_code(const char * code);
45 int push_code_from_file(const 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 sample_t volume_from;
62 static sample_t volume_to;
63 static double gliss;
65 /* parser debugging */
67 #define DEBUGF if(verbose >= 2)printf
69 /* blocks */
71 struct block {
72 const 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 const 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 sample_t 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 sample_t 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 int block_seed = 0;
126 unsigned int volume_seed = 0;
128 /* solo track (-1, no solo) */
129 int solo_track = -1;
131 /*******************
132 Code
133 ********************/
135 unsigned int ah_rnd(unsigned int * seed)
136 /* special randomizer */
138 *seed = (*seed * 58321) + 11113;
140 return *seed >> 16;
144 void c_err(const char * e1, const char * e2, const 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 sample_t volume(void)
174 sample_t f;
176 if (volume_from == volume_to)
177 f = volume_from;
178 else {
179 unsigned int r = ah_rnd(&volume_seed) % 1000;
181 f = volume_from + (volume_to - volume_from) *
182 (((sample_t) r) / 1000.0);
185 return f;
189 /* blocks */
191 static int find_block(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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, sample_t 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(const 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(const 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_sf2_event(const char * sf2_file, const char *insname)
642 struct song_ev *e = add_song_ev(SONG_EV_SS_SF2);
644 e->name = sf2_file;
645 e->str2 = insname;
649 static void add_ss_eff_event(int type, int channel, double size, sample_t gain,
650 double depth, double freq, double phase, sample_t initial, sample_t final)
652 struct song_ev *e = add_song_ev(type);
654 e->channel = channel;
655 e->len = size;
656 e->vol = gain;
657 e->depth = depth;
658 e->freq = freq;
659 e->phase = phase;
660 e->initial = initial;
661 e->final = final;
665 static void add_ss_pitch_stretch(int note, double len, sample_t vol)
667 struct song_ev *e = add_song_ev(SONG_EV_SS_PITCH_STRETCH);
669 e->value = note;
670 e->len = len;
671 e->vol = vol;
675 static void add_ss_print_wave_tempo(int note, double len)
677 struct song_ev *e = add_song_ev(SONG_EV_SS_PRINT_WAVE_TEMPO);
679 e->value = note;
680 e->len = len;
684 static void add_ss_master_volume(sample_t vol)
686 struct song_ev *e = add_song_ev(SONG_EV_SS_MASTER_VOLUME);
688 e->trk_id = -1;
689 e->vol = vol;
693 static void add_midi_channel_event(int channel)
695 struct song_ev *e = add_song_ev(SONG_EV_MIDI_CHANNEL);
697 e->channel = channel - 1;
701 static void add_midi_program_event(int program)
703 struct song_ev *e = add_song_ev(SONG_EV_MIDI_PROGRAM);
705 e->value = program;
709 static void add_song_info_event(const char * author, const char * name)
711 struct song_ev *e = add_song_ev(SONG_EV_SONG_INFO);
713 e->str2 = author;
714 e->name = name;
718 static void init_track(void)
719 /* sets the default values for a new track */
721 int n;
723 /* is there an end time? test if this is longer */
724 if (cur_time > end_time) {
725 add_mark("END");
726 end_time = cur_time;
729 cur_time = 0.0;
730 length = 0.0;
731 transpose = 0;
732 staccato = 0.8;
733 volume_from = volume_to = 0.75;
734 octave = 5;
735 gliss = 0;
737 /* groups should not cross track boundaries */
738 n_groups = 0;
740 /* reset arpeggiator */
741 n_arps = 0;
742 arp_default();
744 /* is there a START mark? if so, move there */
745 if ((n = seek_mark("START")) != -1)
746 cur_time = marks[n].time;
748 /* reset alterations */
749 for (n = 0; n < 12; n++)
750 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"); set_block_d("Am", "$CM");
1283 set_block_d("C#M", "A#######"); set_block_d("A#m", "$C#M");
1284 set_block_d("DM", "A#--#---"); set_block_d("Bm", "$DM");
1285 set_block_d("E&M", "A--&--&&"); set_block_d("Cm", "$E&M");
1286 set_block_d("EM", "A##-##--"); set_block_d("C#m", "$EM");
1287 set_block_d("FM", "A------&"); set_block_d("Dm", "$FM");
1288 set_block_d("F#M", "A######-"); set_block_d("D#m", "$F#M");
1289 set_block_d("GM", "A---#---"); set_block_d("Em", "$GM");
1290 set_block_d("A&M", "A-&&--&&"); set_block_d("Fm", "$A&M");
1291 set_block_d("AM", "A#--##--"); set_block_d("F#m", "$AM");
1292 set_block_d("B&M", "A--&---&"); set_block_d("Gm", "$B&M");
1293 set_block_d("BM", "A##-###-"); set_block_d("G#m", "$BM");
1297 static int do_parse(void)
1299 int r = yyparse() + compiler_error;
1301 if (solo_track != -1)
1302 mute_tracks(-solo_track);
1304 return r;
1308 int compile_ahs_string(const char * code)
1310 compile_startup();
1312 push_code(strdup(code));
1314 return do_parse();
1318 int compile_ahs(const char * file)
1320 compile_startup();
1322 if (insert_file(file))
1323 return 1;
1325 return do_parse();