More reformatting.
[ahxm.git] / compiler.y
blob39443656d08ca46b28e48b790c6a0161afea2838
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 if (cur_time != marks[n].time)
402 c_err("mark-mismatch", name, NULL);
404 return;
407 c_err("mark-not-found", name, NULL);
411 /* arpeggiator */
413 static void arp_default(void)
414 /* resets arpeggiator values to the default ones */
416 arp_delay = 0.0;
417 arp_transpose = 0;
418 arp_volume = 1.0;
419 arp_track_off = 0;
423 static void add_arp(void)
424 /* adds an arpeggiator note */
426 struct arp *a;
428 /* if the note is exactly the same, do nothing */
429 if (arp_delay == 0.0 && arp_transpose == 0 &&
430 arp_volume == 1.0 && arp_track_off == 0)
431 return;
433 if (n_arps == arps_size) {
434 GROW(arps, arps_size, struct arp);
435 arps_size++;
438 a = &arps[n_arps];
440 a->delay = arp_delay;
441 a->transpose = arp_transpose;
442 a->volume = arp_volume;
443 a->track_off = arp_track_off;
445 n_arps++;
446 arp_default();
450 static void set_alteration(const char *altstr)
451 /* sets the alterations from altstr */
453 int n, steps[] = { 2, 0, 2, 0, 1, 2, 0, 2, 0, 2, 0, 1 };
455 /* reset alterations */
456 for (n = 0; n < 12; n++)
457 alterations[n] = 0;
459 /* changed according the altstr spec */
460 for (n = 0; *altstr != '\0' && n < 12; altstr++) {
461 switch (*altstr) {
462 case '&':
463 alterations[n] = -1;
464 break;
466 case '#':
467 alterations[n] = 1;
468 break;
471 /* move to next natural note */
472 n += steps[n];
477 /* song events */
479 static struct song_ev *add_song_ev(song_ev_type type)
481 struct song_ev *r;
483 r = add_event(&song, &n_song_ev);
485 r->type = type;
486 r->time = cur_time;
487 r->trk_id = track;
488 r->event_id = n_song_ev - 1;
490 return r;
494 static void add_note_event(int note)
495 /* adds a note event */
497 int n;
498 int np;
499 struct song_ev *e;
501 /* sum the alteration */
502 if ((n = note % 12) < 0)
503 n += 12;
505 note += alterations[n];
507 /* calculate the note */
508 np = note + transpose + (octave * 12);
510 /* is note out of range? */
511 if (np < 0 || np > 127) {
512 c_err("note-out-of-range", NULL, NULL);
513 return;
516 e = add_song_ev(SONG_EV_NOTE);
518 e->value = np;
519 e->len = length * staccato;
520 e->vol = volume();
522 /* add arpeggiator repetitions */
523 for (n = 0; n < n_arps; n++) {
525 e = add_song_ev(SONG_EV_NOTE);
527 e->time = cur_time + arps[n].delay;
528 e->trk_id = track + arps[n].track_off;
529 e->value = np + arps[n].transpose;
530 e->len = length * staccato;
531 e->vol = volume() * arps[n].volume;
536 static void add_back_event(void)
538 struct song_ev *e = add_song_ev(SONG_EV_BACK);
540 e->len = length;
544 static void add_tempo_event(int trk_id, double tempo)
546 struct song_ev *e = add_song_ev(SONG_EV_TEMPO);
548 e->trk_id = trk_id;
549 e->amount = tempo;
553 static void add_meter_event(int trk_id, int num, int den)
555 struct song_ev *e = add_song_ev(SONG_EV_METER);
557 e->trk_id = trk_id;
558 e->min = num;
559 e->max = den;
562 static void add_measure_event(void)
564 struct song_ev *e = add_song_ev(SONG_EV_MEASURE);
566 e->trk_id = -1;
567 e->value = yyline;
571 static void add_ss_sustain_event(double sustain)
573 struct song_ev *e = add_song_ev(SONG_EV_SS_SUSTAIN);
575 e->amount = sustain;
579 static void add_ss_attack_event(double attack)
581 struct song_ev *e = add_song_ev(SONG_EV_SS_ATTACK);
583 e->amount = attack;
587 static void add_ss_vibrato_event(double depth, double freq)
589 struct song_ev *e = add_song_ev(SONG_EV_SS_VIBRATO);
591 e->depth = depth;
592 e->freq = freq;
596 static void add_ss_portamento_event(double portamento)
598 struct song_ev *e = add_song_ev(SONG_EV_SS_PORTAMENTO);
600 e->amount = portamento;
604 static void add_ss_channel_event(int channel, sample_t vol)
606 struct song_ev *e = add_song_ev(SONG_EV_SS_CHANNEL);
608 e->channel = channel;
609 e->vol = vol;
613 static void add_ss_wav_event(const char *wav_file, int base, int min,
614 int max, double loop_start, double loop_end,
615 int first_channel, int skip_channels)
617 struct song_ev *e = add_song_ev(SONG_EV_SS_WAV);
619 e->name = wav_file;
620 e->value = base;
621 e->min = min;
622 e->max = max;
623 e->start = loop_start;
624 e->end = loop_end;
625 e->channel = first_channel;
626 e->skip_channels = skip_channels;
630 static void add_ss_pat_event(const char *pat_file)
632 struct song_ev *e = add_song_ev(SONG_EV_SS_PAT);
634 e->name = pat_file;
638 static void add_ss_sf2_event(const char *sf2_file, const char *insname)
640 struct song_ev *e = add_song_ev(SONG_EV_SS_SF2);
642 e->name = sf2_file;
643 e->str2 = insname;
647 static void add_ss_eff_event(int type, int channel, double size,
648 sample_t gain, double depth, double freq,
649 double phase, sample_t initial,
650 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;
755 %union {
756 int i;
757 double d;
758 char * p;
761 %token <i> P_INTEGER S_INTEGER
762 %token <d> P_REAL S_REAL
763 %token <i> NOTE_P NOTE_T3 NOTE_T5
764 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
766 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
768 %token <p> ALTSTR
770 %token <p> LIBPATH_ADD
772 %token <p> XC_STR
773 %token <i> XC_ABSNOTE
774 %token <d> XC_MSECS
776 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT SS_SF2
777 %token SS_SUSTAIN SS_ATTACK SS_VIBRATO SS_PORTAMENTO SS_CHANNEL SS_VOL SS_MASTER_VOL
779 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
780 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_HFWOBBLE
781 %token SS_EFF_FADER SS_EFF_REVERB
782 %token SS_EFF_FOLDBACK SS_EFF_ATAN SS_EFF_DISTORT SS_EFF_OVERDRIVE
783 %token SS_EFF_OFF
785 %token SS_PITCH_STRETCH SS_TIME_STRETCH SS_PRINT_WAVE_TEMPO
787 %token SONG_INFO
789 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
791 %type <i> integer note note_pitch rest back
792 %type <d> real p_number number note_length
794 %type <d> arp_list arp_note
795 %type <i> xc_absnote
799 script:
800 script stmt { ; }
801 | /* NULL */
804 stmt:
805 note {
806 /* note event */
807 add_note_event($1);
808 forward(length);
810 | rest {
811 /* rest */
812 forward(length);
814 | back {
815 /* back */
816 add_back_event();
818 | 'z' note_length {
819 /* zero note */
820 length = $2;
822 | 'o' P_INTEGER {
823 /* absolute octave */
824 octave = $2;
826 | 'o' S_INTEGER {
827 /* relative octave */
828 octave += $2;
830 | 'v' P_INTEGER {
831 /* absolute volume */
832 volume_from = volume_to = $2;
834 | 'v' P_REAL {
835 /* absolute volume */
836 volume_from = volume_to = $2;
838 | 'v' S_REAL {
839 /* relative volume */
840 volume_from += $2;
841 volume_to += $2;
843 | 'v' P_REAL ',' P_REAL {
844 /* absolute volume ranges */
845 volume_from = $2;
846 volume_to = $4;
848 | 't' integer {
849 /* transpose */
850 transpose = $2;
852 | 's' p_number {
853 /* staccato */
854 staccato = $2;
857 | '<' {
858 /* start of group */
859 push_group();
861 | ';' {
862 /* group delimiter */
863 next_group_part();
865 | '>' {
866 /* end of group */
867 pop_group();
869 | 'l' note_length {
870 /* glissando */
871 gliss = $2;
874 | '|' {
875 /* measure mark event */
876 add_measure_event();
879 | NEW_MARK {
880 /* add new mark */
881 add_mark($1);
883 | GOTO_MARK {
884 /* go to mark */
885 find_mark($1, 1);
887 | ASSERT_MARK {
888 /* assert mark */
889 find_mark($1, 0);
892 | '\\' {
893 /* new track */
895 track++;
896 init_track();
898 | 'T' p_number {
899 /* tempo setting */
900 add_tempo_event(-1, $2);
902 | 'M' P_INTEGER '/' P_INTEGER {
903 /* meter (time signature) setting */
904 add_meter_event(-1, $2, $4);
906 | ALTSTR {
907 /* alteration string */
908 set_alteration($1);
911 | BLOCK '*' P_INTEGER {
912 /* repeat block */
913 int n;
915 /* store the block as <TMP> */
916 set_block("<TMP>", $1);
918 for(n = 0;n < $3;n++)
919 insert_block("<TMP>");
921 | BLOCK BLK_ASSIGN {
922 /* assign block */
923 set_block($2, $1);
925 | BLK_INSERT {
926 /* insert block */
927 insert_block($1);
929 | FILE_INSERT {
930 /* insert file */
931 insert_file($1);
933 | LIBPATH_ADD {
934 /* add library path */
935 libpath_add($1, 0);
938 | arp { ; }
940 | xc_cmd { ; }
944 integer:
945 P_INTEGER { $$ = $1; }
946 | S_INTEGER { $$ = $1; }
949 real:
950 P_REAL { $$ = $1; }
951 | S_REAL { $$ = $1; }
954 p_number:
955 P_INTEGER { $$ = (double) $1; }
956 | P_REAL { $$ = $1; }
959 number:
960 integer { $$ = (double) $1; }
961 | real { $$ = $1; }
964 note:
965 note_pitch { $$ = $1; }
966 | note note_length { $$ = $1; length=$2; }
967 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
970 note_pitch:
971 NOTE_P { $$ = $1; }
972 | note_pitch '&' { $$ = $1 - 1; }
973 | note_pitch '#' { $$ = $1 + 1; }
974 | note_pitch '\'' { $$ = $1 + 12; }
975 | note_pitch ',' { $$ = $1 - 12; }
978 note_length:
979 P_INTEGER { $$ = 1 / (double) $1; }
980 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
981 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
982 | note_length '*' p_number { $$ = $1 * $3; }
983 | note_length '.' { $$ = $1 * 1.5; }
986 rest:
987 'r' { ; }
988 | rest note_length {
989 /* rest with length */
990 length = $2;
994 back:
995 'k' { ; }
996 | back note_length {
997 /* back with length */
998 length = $2;
1002 arp:
1003 'x' {
1004 /* empty arpeggiator */
1005 n_arps = 0;
1006 arp_default();
1008 | 'x' arp_list { ; }
1011 arp_list:
1012 arp_note {
1013 /* first arpeggiator note */
1014 n_arps = 0;
1015 add_arp();
1017 | arp_list ',' arp_note {
1018 /* rest of arpeggiator notes */
1019 add_arp();
1023 arp_note:
1024 note_length {
1025 /* arpeggiator delay */
1026 arp_delay = $1;
1028 | arp_note '~' number {
1029 /* arpeggiator volume */
1030 arp_volume = $3;
1032 | arp_note S_INTEGER {
1033 /* arpeggiator transpose */
1034 arp_transpose = $2;
1036 | arp_note '/' P_INTEGER {
1037 /* arpeggiator track offset */
1038 arp_track_off = $3;
1040 | arp_note NOTE_T3 {
1041 /* HACK: /3 */
1042 arp_track_off = 3;
1044 | arp_note NOTE_T5 {
1045 /* HACK: /5 */
1046 arp_track_off = 5;
1050 xc_absnote:
1051 P_INTEGER { $$ = $1; }
1052 | XC_ABSNOTE { $$ = $1; }
1055 xc_cmd:
1056 SS_WAV XC_STR xc_absnote {
1057 /* load .wav file with just one note */
1058 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0, 0, 0);
1060 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
1061 /* load .wav file */
1062 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0, 0, 0);
1064 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
1065 /* load .wav file, with loop boundaries */
1066 add_ss_wav_event($2, $3, $4, $5, $6, $7, 0, 0);
1068 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number number number {
1069 /* load .wav file, with loop boundaries,
1070 first channel and skip channels */
1071 add_ss_wav_event($2, $3, $4, $5, $6, $7, $8, $9);
1073 | SS_PAT XC_STR {
1074 /* load .pat file */
1075 add_ss_pat_event($2);
1077 | SS_SF2 XC_STR {
1078 /* list instruments in .sf2 file */
1079 add_ss_sf2_event($2, NULL);
1081 | SS_SF2 XC_STR XC_STR {
1082 /* load instrument from .sf2 file */
1083 add_ss_sf2_event($2, $3);
1086 | SS_SUSTAIN XC_MSECS {
1087 /* sets sustain */
1088 add_ss_sustain_event($2);
1090 | SS_ATTACK XC_MSECS {
1091 /* sets attack */
1092 add_ss_attack_event($2);
1094 | SS_VIBRATO XC_MSECS number {
1095 /* sets vibrato */
1096 add_ss_vibrato_event($2, $3);
1098 | SS_PORTAMENTO number {
1099 /* sets portamento */
1100 add_ss_portamento_event($2);
1102 | SS_CHANNEL integer number {
1103 /* sets volume for a channel */
1104 add_ss_channel_event($2, $3);
1106 | SS_VOL number number {
1107 /* set vol for 2 channels */
1108 add_ss_channel_event(0, $2);
1109 add_ss_channel_event(1, $3);
1111 | SS_VOL number number number {
1112 /* set vol for 3 channels */
1113 add_ss_channel_event(0, $2);
1114 add_ss_channel_event(1, $3);
1115 add_ss_channel_event(2, $4);
1117 | SS_VOL number number number number {
1118 /* set vol for 4 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);
1124 | SS_VOL number number number number number number {
1125 /* set vol for 6 channels */
1126 add_ss_channel_event(0, $2);
1127 add_ss_channel_event(1, $3);
1128 add_ss_channel_event(2, $4);
1129 add_ss_channel_event(3, $5);
1130 add_ss_channel_event(4, $6);
1131 add_ss_channel_event(5, $7);
1133 | SS_EFF_DELAY integer XC_MSECS {
1134 /* delay effect */
1135 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
1136 $2, $3, 0, 0, 0, 0, 0, 0);
1139 | SS_EFF_ECHO integer XC_MSECS number {
1140 /* echo effect */
1141 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
1142 $2, $3, $4, 0, 0, 0, 0, 0);
1145 | SS_EFF_COMB integer XC_MSECS number {
1146 /* comb effect */
1147 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
1148 $2, $3, $4, 0, 0, 0, 0, 0);
1151 | SS_EFF_ALLPASS integer XC_MSECS number {
1152 /* allpass effect */
1153 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
1154 $2, $3, $4, 0, 0, 0, 0, 0);
1157 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
1158 /* flanger effect */
1159 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
1160 $2, $3, $4, $5, $6, $7, 0, 0);
1163 | SS_EFF_WOBBLE integer number number {
1164 /* wobble effect */
1165 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1166 $2, 0, 0.8, 0, $3, $4, 0, 0);
1169 | SS_EFF_WOBBLE integer number number number {
1170 /* wobble effect, with gain */
1171 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
1172 $2, 0, $5, 0, $3, $4, 0, 0);
1175 | SS_EFF_SQWOBBLE integer number number {
1176 /* square wobble effect */
1177 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
1178 $2, 0, 0, 0, $3, $4, 0, 0);
1181 | SS_EFF_HFWOBBLE integer number number {
1182 /* half wobble effect */
1183 add_ss_eff_event(SONG_EV_SS_EFF_HFWOBBLE,
1184 $2, 0, 0, 0, $3, $4, 0, 0);
1187 | SS_EFF_FADER integer XC_MSECS number number {
1188 /* fader effect */
1189 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
1190 $2, $3, 0, 0, 0, 0, $4, $5);
1193 | SS_EFF_REVERB integer {
1194 /* reverb effect */
1195 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
1196 $2, 0, 0, 0, 0, 0, 0, 0);
1199 | SS_EFF_FOLDBACK integer number {
1200 /* foldback distortion effect */
1201 add_ss_eff_event(SONG_EV_SS_EFF_FOLDBACK,
1202 $2, 0, $3, 0, 0, 0, 0, 0);
1204 | SS_EFF_ATAN integer number {
1205 /* atan distortion effect */
1206 add_ss_eff_event(SONG_EV_SS_EFF_ATAN,
1207 $2, 0, $3, 0, 0, 0, 0, 0);
1209 | SS_EFF_DISTORT integer number {
1210 /* distort distortion effect */
1211 add_ss_eff_event(SONG_EV_SS_EFF_DISTORT,
1212 $2, 0, $3, 0, 0, 0, 0, 0);
1214 | SS_EFF_OVERDRIVE integer number {
1215 /* overdrive distortion effect */
1216 add_ss_eff_event(SONG_EV_SS_EFF_OVERDRIVE,
1217 $2, 0, $3, 0, 0, 0, 0, 0);
1220 | SS_EFF_OFF integer {
1221 /* off effect */
1222 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
1223 $2, 0, 0, 0, 0, 0, 0, 0);
1226 | SS_PITCH_STRETCH xc_absnote number number {
1227 /* pitch stretch note */
1228 add_ss_pitch_stretch($2, $3, $4);
1230 forward($3);
1233 | SS_PRINT_WAVE_TEMPO xc_absnote number {
1234 /* print tempo from wave */
1235 add_ss_print_wave_tempo($2, $3);
1238 | SS_MASTER_VOL number {
1239 /* set master volume */
1240 add_ss_master_volume($2);
1243 | SONG_INFO XC_STR XC_STR {
1244 /* add song info */
1245 add_song_info_event($2, $3);
1248 | MIDI_CHANNEL integer {
1249 /* midi channel */
1250 add_midi_channel_event($2);
1253 | MIDI_PROGRAM integer {
1254 /* midi program */
1255 add_midi_program_event($2);
1261 void yyerror(const char *s)
1263 c_err(s, NULL, NULL);
1267 #define set_block_d(n,b) set_block(n,strdup(b))
1269 static void compile_startup(void)
1271 track = 0;
1272 yyline = 1;
1273 compiler_error = 0;
1275 /* default settings */
1276 add_tempo_event(-2, 120.0);
1277 add_meter_event(-2, 4, 4);
1278 init_track();
1280 /* standard tonalities */
1281 set_block_d("CM", "A");
1282 set_block_d("Am", "$CM");
1283 set_block_d("C#M", "A#######");
1284 set_block_d("A#m", "$C#M");
1285 set_block_d("DM", "A#--#---");
1286 set_block_d("Bm", "$DM");
1287 set_block_d("E&M", "A--&--&&");
1288 set_block_d("Cm", "$E&M");
1289 set_block_d("EM", "A##-##--");
1290 set_block_d("C#m", "$EM");
1291 set_block_d("FM", "A------&");
1292 set_block_d("Dm", "$FM");
1293 set_block_d("F#M", "A######-");
1294 set_block_d("D#m", "$F#M");
1295 set_block_d("GM", "A---#---");
1296 set_block_d("Em", "$GM");
1297 set_block_d("A&M", "A-&&--&&");
1298 set_block_d("Fm", "$A&M");
1299 set_block_d("AM", "A#--##--");
1300 set_block_d("F#m", "$AM");
1301 set_block_d("B&M", "A--&---&");
1302 set_block_d("Gm", "$B&M");
1303 set_block_d("BM", "A##-###-");
1304 set_block_d("G#m", "$BM");
1308 static int do_parse(void)
1310 int r = yyparse() + compiler_error;
1312 if (solo_track != -1)
1313 mute_tracks(-solo_track);
1315 return r;
1319 int compile_ahs_string(const char *code)
1321 compile_startup();
1323 push_code(strdup(code));
1325 return do_parse();
1329 int compile_ahs(const char *file)
1331 compile_startup();
1333 if (insert_file(file))
1334 return 1;
1336 return do_parse();