Updated RELEASE_NOTES.
[ahxm.git] / compiler.y
blobe4ba2ba11c58b6e0786654c0da7c4dcbdeacafcd
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_midi_channel_event(int channel)
686 struct song_ev *e = add_song_ev(SONG_EV_MIDI_CHANNEL);
688 e->channel = channel - 1;
692 static void add_midi_program_event(int program)
694 struct song_ev *e = add_song_ev(SONG_EV_MIDI_PROGRAM);
696 e->value = program;
700 static void add_song_info_event(const char * author, const char * name)
702 struct song_ev *e = add_song_ev(SONG_EV_SONG_INFO);
704 e->str2 = author;
705 e->name = name;
709 static void init_track(void)
710 /* sets the default values for a new track */
712 int n;
714 /* is there an end time? test if this is longer */
715 if (cur_time > end_time) {
716 add_mark("END");
717 end_time = cur_time;
720 cur_time = 0.0;
721 length = 0.0;
722 transpose = 0;
723 staccato = 0.8;
724 volume_from = volume_to = 0.75;
725 octave = 5;
726 gliss = 0;
728 /* groups should not cross track boundaries */
729 n_groups = 0;
731 /* reset arpeggiator */
732 n_arps = 0;
733 arp_default();
735 /* is there a START mark? if so, move there */
736 if ((n = seek_mark("START")) != -1)
737 cur_time = marks[n].time;
739 /* reset alterations */
740 for (n = 0; n < 12; n++)
741 alterations[n] = 0;
747 %union {
748 int i;
749 double d;
750 char * p;
753 %token <i> P_INTEGER S_INTEGER
754 %token <d> P_REAL S_REAL
755 %token <i> NOTE_P NOTE_T3 NOTE_T5
756 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
758 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
760 %token <p> ALTSTR
762 %token <p> XC_STR
763 %token <i> XC_ABSNOTE
764 %token <d> XC_MSECS
766 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT SS_SF2
767 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL
769 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
770 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
771 %token SS_EFF_FADER SS_EFF_REVERB
772 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
773 %token SS_EFF_OFF
775 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
777 %token SONG_INFO
779 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
781 %type <i> integer note note_pitch rest back
782 %type <d> real p_number number note_length
784 %type <d> arp_list arp_note
785 %type <i> xc_absnote
789 script:
790 script stmt { ; }
791 | /* NULL */
794 stmt:
795 note {
796 /* note event */
797 add_note_event($1);
798 forward(length);
800 | rest {
801 /* rest */
802 forward(length);
804 | back {
805 /* back */
806 add_back_event();
808 | 'z' note_length {
809 /* zero note */
810 length = $2;
812 | 'o' P_INTEGER {
813 /* absolute octave */
814 octave = $2;
816 | 'o' S_INTEGER {
817 /* relative octave */
818 octave += $2;
820 | 'v' P_INTEGER {
821 /* absolute volume */
822 volume_from = volume_to = $2;
824 | 'v' P_REAL {
825 /* absolute volume */
826 volume_from = volume_to = $2;
828 | 'v' S_REAL {
829 /* relative volume */
830 volume_from += $2;
831 volume_to += $2;
833 | 'v' P_REAL ',' P_REAL {
834 /* absolute volume ranges */
835 volume_from = $2;
836 volume_to = $4;
838 | 't' integer {
839 /* transpose */
840 transpose = $2;
842 | 's' p_number {
843 /* staccato */
844 staccato = $2;
847 | '<' {
848 /* start of group */
849 push_group();
851 | ';' {
852 /* group delimiter */
853 next_group_part();
855 | '>' {
856 /* end of group */
857 pop_group();
859 | 'l' note_length {
860 /* glissando */
861 gliss = $2;
864 | '|' {
865 /* measure mark event */
866 add_measure_event();
869 | NEW_MARK {
870 /* add new mark */
871 add_mark($1);
873 | GOTO_MARK {
874 /* go to mark */
875 find_mark($1, 1);
877 | ASSERT_MARK {
878 /* assert mark */
879 find_mark($1, 0);
882 | '\\' {
883 /* new track */
885 track++;
886 init_track();
888 | 'T' p_number {
889 /* tempo setting */
890 add_tempo_event(-1, $2);
892 | 'M' P_INTEGER '/' P_INTEGER {
893 /* meter (time signature) setting */
894 add_meter_event(-1, $2, $4);
896 | ALTSTR {
897 /* alteration string */
898 set_alteration($1);
901 | BLOCK '*' P_INTEGER {
902 /* repeat block */
903 int n;
905 /* store the block as <TMP> */
906 set_block("<TMP>", $1);
908 for(n = 0;n < $3;n++)
909 insert_block("<TMP>");
911 | BLOCK BLK_ASSIGN {
912 /* assign block */
913 set_block($2, $1);
915 | BLK_INSERT {
916 /* insert block */
917 insert_block($1);
919 | FILE_INSERT {
920 /* insert file */
921 insert_file($1);
924 | arp { ; }
926 | xc_cmd { ; }
930 integer:
931 P_INTEGER { $$ = $1; }
932 | S_INTEGER { $$ = $1; }
935 real:
936 P_REAL { $$ = $1; }
937 | S_REAL { $$ = $1; }
940 p_number:
941 P_INTEGER { $$ = (double) $1; }
942 | P_REAL { $$ = $1; }
945 number:
946 integer { $$ = (double) $1; }
947 | real { $$ = $1; }
950 note:
951 note_pitch { $$ = $1; }
952 | note note_length { $$ = $1; length=$2; }
953 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
956 note_pitch:
957 NOTE_P { $$ = $1; }
958 | note_pitch '&' { $$ = $1 - 1; }
959 | note_pitch '#' { $$ = $1 + 1; }
960 | note_pitch '\'' { $$ = $1 + 12; }
961 | note_pitch ',' { $$ = $1 - 12; }
964 note_length:
965 P_INTEGER { $$ = 1 / (double) $1; }
966 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
967 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
968 | note_length '*' p_number { $$ = $1 * $3; }
969 | note_length '.' { $$ = $1 * 1.5; }
972 rest:
973 'r' { ; }
974 | rest note_length {
975 /* rest with length */
976 length = $2;
980 back:
981 'k' { ; }
982 | back note_length {
983 /* back with length */
984 length = $2;
988 arp:
989 'x' {
990 /* empty arpeggiator */
991 n_arps = 0;
992 arp_default();
994 | 'x' arp_list { ; }
997 arp_list:
998 arp_note {
999 /* first arpeggiator note */
1000 n_arps = 0;
1001 add_arp();
1003 | arp_list ',' arp_note {
1004 /* rest of arpeggiator notes */
1005 add_arp();
1009 arp_note:
1010 note_length {
1011 /* arpeggiator delay */
1012 arp_delay = $1;
1014 | arp_note '~' number {
1015 /* arpeggiator volume */
1016 arp_volume = $3;
1018 | arp_note S_INTEGER {
1019 /* arpeggiator transpose */
1020 arp_transpose = $2;
1022 | arp_note '/' P_INTEGER {
1023 /* arpeggiator track offset */
1024 arp_track_off = $3;
1026 | arp_note NOTE_T3 {
1027 /* HACK: /3 */
1028 arp_track_off = 3;
1030 | arp_note NOTE_T5 {
1031 /* HACK: /5 */
1032 arp_track_off = 5;
1036 xc_absnote:
1037 P_INTEGER { $$ = $1; }
1038 | XC_ABSNOTE { $$ = $1; }
1041 xc_cmd:
1042 SS_WAV XC_STR xc_absnote {
1043 /* load .wav file with just one note */
1044 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1046 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1047 /* load .wav file */
1048 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1050 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1051 /* load .wav file, with loop boundaries */
1052 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1054 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1055 /* load .wav file, with loop boundaries,
1056 first channel and skip channels */
1057 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1059 | SS_PAT XC_STR {
1060 /* load .pat file */
1061 add_ss_pat_event($2);
1063 | SS_SF2 XC_STR {
1064 /* list instruments in .sf2 file */
1065 add_ss_sf2_event($2, NULL);
1067 | SS_SF2 XC_STR XC_STR {
1068 /* load instrument from .sf2 file */
1069 add_ss_sf2_event($2, $3);
1072 | SS_SUSTAIN XC_MSECS {
1073 /* sets sustain */
1074 add_ss_sustain_event($2);
1076 | SS_ATTACK XC_MSECS {
1077 /* sets attack */
1078 add_ss_attack_event($2);
1080 | SS_VIBRATO XC_MSECS number {
1081 /* sets vibrato */
1082 add_ss_vibrato_event($2, $3);
1084 | SS_PORTAMENTO number {
1085 /* sets portamento */
1086 add_ss_portamento_event($2);
1088 | SS_CHANNEL integer number {
1089 /* sets volume for a channel */
1090 add_ss_channel_event($2, $3);
1092 | SS_VOL number number {
1093 /* set vol for 2 channels */
1094 add_ss_channel_event(0, $2);
1095 add_ss_channel_event(1, $3);
1097 | SS_VOL number number number {
1098 /* set vol for 3 channels */
1099 add_ss_channel_event(0, $2);
1100 add_ss_channel_event(1, $3);
1101 add_ss_channel_event(2, $4);
1103 | SS_VOL number number number number {
1104 /* set vol for 4 channels */
1105 add_ss_channel_event(0, $2);
1106 add_ss_channel_event(1, $3);
1107 add_ss_channel_event(2, $4);
1108 add_ss_channel_event(3, $5);
1110 | SS_VOL number number number number number number {
1111 /* set vol for 6 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);
1116 add_ss_channel_event(4, $6);
1117 add_ss_channel_event(5, $7);
1119 | SS_EFF_DELAY integer XC_MSECS {
1120 /* delay effect */
1121 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1122 $2, $3, 0, 0, 0, 0, 0, 0);
1125 | SS_EFF_ECHO integer XC_MSECS number {
1126 /* echo effect */
1127 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1128 $2, $3, $4, 0, 0, 0, 0, 0);
1131 | SS_EFF_COMB integer XC_MSECS number {
1132 /* comb effect */
1133 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1134 $2, $3, $4, 0, 0, 0, 0, 0);
1137 | SS_EFF_ALLPASS integer XC_MSECS number {
1138 /* allpass effect */
1139 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1140 $2, $3, $4, 0, 0, 0, 0, 0);
1143 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1144 /* flanger effect */
1145 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1146 $2, $3, $4, $5, $6, $7, 0, 0);
1149 | SS_EFF_WOBBLE integer number number {
1150 /* wobble effect */
1151 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1152 $2, 0, 0.8, 0, $3, $4, 0, 0);
1155 | SS_EFF_WOBBLE integer number number number {
1156 /* wobble effect, with gain */
1157 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1158 $2, 0, $5, 0, $3, $4, 0, 0);
1161 | SS_EFF_SQWOBBLE integer number number {
1162 /* square wobble effect */
1163 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1164 $2, 0, 0, 0, $3, $4, 0, 0);
1167 | SS_EFF_HFWOBBLE integer number number {
1168 /* half wobble effect */
1169 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1170 $2, 0, 0, 0, $3, $4, 0, 0);
1173 | SS_EFF_FADER integer XC_MSECS number number {
1174 /* fader effect */
1175 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1176 $2, $3, 0, 0, 0, 0, $4, $5);
1179 | SS_EFF_REVERB integer {
1180 /* reverb effect */
1181 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1182 $2, 0, 0, 0, 0, 0, 0, 0);
1185 | SS_EFF_FOLDBACK integer number {
1186 /* foldback distortion effect */
1187 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1188 $2, 0, $3, 0, 0, 0, 0, 0);
1190 | SS_EFF_ATAN integer number {
1191 /* atan distortion effect */
1192 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1193 $2, 0, $3, 0, 0, 0, 0, 0);
1195 | SS_EFF_DISTORT integer number {
1196 /* distort distortion effect */
1197 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1198 $2, 0, $3, 0, 0, 0, 0, 0);
1200 | SS_EFF_OVERDRIVE integer number {
1201 /* overdrive distortion effect */
1202 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1203 $2, 0, $3, 0, 0, 0, 0, 0);
1206 | SS_EFF_OFF integer {
1207 /* off effect */
1208 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1209 $2, 0, 0, 0, 0, 0, 0, 0);
1212 | SS_PITCH_STRETCH xc_absnote number number {
1213 /* pitch stretch note */
1214 add_ss_pitch_stretch($2, $3, $4);
1216 forward($3);
1219 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1220 /* print tempo from wave */
1221 add_ss_print_wave_tempo($2, $3);
1224 | SONG_INFO XC_STR XC_STR {
1225 /* add song info */
1226 add_song_info_event($2, $3);
1229 | MIDI_CHANNEL integer {
1230 /* midi channel */
1231 add_midi_channel_event($2);
1234 | MIDI_PROGRAM integer {
1235 /* midi program */
1236 add_midi_program_event($2);
1242 void yyerror(const char * s)
1244 c_err(s, NULL, NULL);
1248 #define set_block_d(n,b) set_block(n,strdup(b))
1250 static void compile_startup(void)
1252 track = 0;
1253 yyline = 1;
1254 compiler_error = 0;
1256 /* default settings */
1257 add_tempo_event(-2, 120.0);
1258 add_meter_event(-2, 4, 4);
1259 init_track();
1261 /* standard tonalities */
1262 set_block_d("CM", "A"); set_block_d("Am", "$CM");
1263 set_block_d("C#M", "A#######"); set_block_d("A#m", "$C#M");
1264 set_block_d("DM", "A#--#---"); set_block_d("Bm", "$DM");
1265 set_block_d("E&M", "A--&--&&"); set_block_d("Cm", "$E&M");
1266 set_block_d("EM", "A##-##--"); set_block_d("C#m", "$EM");
1267 set_block_d("FM", "A------&"); set_block_d("Dm", "$FM");
1268 set_block_d("F#M", "A######-"); set_block_d("D#m", "$F#M");
1269 set_block_d("GM", "A---#---"); set_block_d("Em", "$GM");
1270 set_block_d("A&M", "A-&&--&&"); set_block_d("Fm", "$A&M");
1271 set_block_d("AM", "A#--##--"); set_block_d("F#m", "$AM");
1272 set_block_d("B&M", "A--&---&"); set_block_d("Gm", "$B&M");
1273 set_block_d("BM", "A##-###-"); set_block_d("G#m", "$BM");
1277 static int do_parse(void)
1279 int r = yyparse() + compiler_error;
1281 if (solo_track != -1)
1282 mute_tracks(-solo_track);
1284 return r;
1288 int compile_ahs_string(const char * code)
1290 compile_startup();
1292 push_code(strdup(code));
1294 return do_parse();
1298 int compile_ahs(const char * file)
1300 compile_startup();
1302 if (insert_file(file))
1303 return 1;
1305 return do_parse();