Renamed SS_GEN_NUM to SS_MAX_GENERATORS.
[ahxm.git] / compiler.y
blob0021517c52a108c635816fd159d0b2a37b37ad90
1 %{
2 /*
4 Ann Hell Ex Machina - Music Software
5 Copyright (C) 2003/2005 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 "ss_core.h" /* for ss_debug */
35 #include "song.h"
37 /*******************
38 Data
39 ********************/
41 int yylex(void);
42 void yyerror(char * s);
44 /* injecting code functions (defined in compiler.l) */
45 int push_code(char * code, int times, int dyn);
46 int push_code_from_file(char * file);
48 /* current track */
49 int track;
51 /* current time */
52 double cur_time;
54 /* note globals */
55 static double length;
56 static int octave;
57 static int transpose;
58 static double staccato;
59 static float volume;
60 static double gliss;
62 /* parser debugging */
64 #define DEBUGF if(ss_debug)printf
66 /* named blocks */
68 struct named_block
70 char name[64];
71 char * block;
74 static struct named_block * named_blocks=NULL;
75 static int n_named_blocks=0;
76 static int named_blocks_size=0;
78 /* group info */
79 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
93 char name[64];
94 double time;
97 static struct mark * marks=NULL;
98 static int n_marks=0;
99 static int marks_size=0;
101 /* arpeggiator */
102 struct arp
104 double delay;
105 int transpose;
106 float volume;
107 int track;
110 static struct arp * arps=NULL;
111 static int n_arps=0;
112 static int arps_size=0;
114 static double arp_delay;
115 static int arp_transpose;
116 static float arp_volume;
117 static int arp_track;
119 int compiler_error=0;
121 extern int yyline;
123 /*******************
124 Code
125 ********************/
127 void c_err(char * e1, char * e2, char * e3)
128 /* reports an error from the compiler */
130 printf("ahxm:");
131 if(e1 != NULL) printf(" %s", e1);
132 if(e2 != NULL) printf(" %s", e2);
133 if(e3 != NULL) printf(" %s", e3);
134 printf(" in line %d\n", yyline);
136 compiler_error++;
140 static void forward(double step)
141 /* moves forward current time */
143 /* add step */
144 cur_time += step;
146 /* quantizations could be done here */
150 /* named blocks */
152 static int set_named_block(char * name, char * block)
153 /* sets a named block */
155 int n;
157 /* find first if block is previously defined */
158 for(n=0;n < n_named_blocks;n++)
160 if(strcmp(name, named_blocks[n].name) == 0)
162 free(named_blocks[n].block);
163 break;
167 if(n == n_named_blocks)
169 /* need to expand? */
170 if(n_named_blocks == named_blocks_size)
172 named_blocks_size += 4;
174 named_blocks=(struct named_block *)
175 realloc(named_blocks,
176 named_blocks_size *
177 sizeof(struct named_block));
180 n_named_blocks++;
183 strncpy(named_blocks[n].name, name, sizeof(named_blocks[n].name));
184 named_blocks[n].block=block;
186 return(1);
190 static void insert_named_block(char * name)
191 /* inserts a named block */
193 int n;
195 for(n=0;n < n_named_blocks;n++)
197 if(strcmp(name, named_blocks[n].name) == 0)
199 push_code(named_blocks[n].block, 1, 0);
200 return;
204 c_err("block-not-found", name, NULL);
208 static int insert_file(char * filename)
210 if(!push_code_from_file(filename))
212 c_err("script-not-found", filename, NULL);
213 return(1);
216 return(0);
220 /* groups */
222 static int push_group(void)
223 /* starts a new group of notes */
225 if(n_groups == groups_size)
227 groups_size += 4;
229 groups=(struct group *) realloc(groups,
230 groups_size * sizeof(struct group));
233 groups[n_groups].start=cur_time;
234 groups[n_groups].gliss=0.0;
235 groups[n_groups].max=0.0;
237 n_groups++;
239 return(1);
243 static int next_group_part(void)
244 /* part delimiter */
246 if(n_groups == 0)
248 c_err("missing-start-of-group", NULL, NULL);
249 return(0);
252 /* store maximum frame */
253 if(groups[n_groups - 1].max < cur_time)
254 groups[n_groups - 1].max=cur_time;
256 /* add glissando delay */
257 groups[n_groups - 1].gliss += gliss;
259 /* rewind */
260 cur_time=groups[n_groups - 1].start + groups[n_groups - 1].gliss;
262 return(1);
266 static int pop_group(void)
267 /* finishes a group, moving the frame to the end of the longer part */
269 if(n_groups == 0)
271 c_err("missing-start-of-group", NULL, NULL);
272 return(0);
275 n_groups--;
277 cur_time=groups[n_groups].max;
279 return(1);
283 /* marks */
285 static void add_mark(char * name)
286 /* creates a new mark */
288 if(n_marks == marks_size)
290 marks_size += 4;
292 marks=(struct mark *) realloc(marks,
293 marks_size * sizeof(struct mark));
296 strncpy(marks[n_marks].name, name, sizeof(marks[n_marks].name));
297 marks[n_marks].time=cur_time;
299 n_marks++;
303 static void find_mark(char * name, int set)
304 /* finds a mark by name, optionally moving time cursor there */
306 int n;
308 for(n=0;n < n_marks;n++)
310 if(strcmp(marks[n].name, name) == 0)
312 if(set)
314 if(cur_time > marks[n].time)
315 c_err("mark-overpassed", name, NULL);
316 else
317 cur_time=marks[n].time;
319 else
320 if(cur_time != marks[n].time)
321 c_err("mark-mismatch", name, NULL);
323 return;
327 c_err("mark-not-found", name, NULL);
331 /* arpeggiator */
333 static void arp_default(void)
334 /* resets arpeggiator values to the default ones */
336 arp_delay=0.0;
337 arp_transpose=0;
338 arp_volume=1.0;
339 arp_track=track;
343 static void add_arp(void)
344 /* adds an arpeggiator note */
346 /* if the note is exactly the same, do nothing */
347 if(arp_delay == 0.0 && arp_transpose == 0 &&
348 arp_volume == 1.0 && arp_track == track)
349 return;
351 if(n_arps == arps_size)
353 arps_size += 4;
355 arps=(struct arp *) realloc(arps,
356 arps_size * sizeof(struct arp));
359 arps[n_arps].delay=arp_delay;
360 arps[n_arps].transpose=arp_transpose;
361 arps[n_arps].volume=arp_volume;
362 arps[n_arps].track=arp_track;
364 n_arps++;
365 arp_default();
369 /* song events */
371 static void add_note_event(int note)
372 /* adds a note event */
374 int n;
375 int np;
376 union song_ev e;
378 /* calculate the note */
379 np=note + transpose + (octave * 12);
381 /* is note out of range? */
382 if(np < 0 || np > 127)
384 c_err("note-out-of-range", NULL, NULL);
385 return;
388 e.note.type=SONG_EV_NOTE;
389 e.note.time=cur_time;
390 e.note.trk_id=track;
391 e.note.note=np;
392 e.note.len=length * staccato;
393 e.note.vol=volume;
395 add_song_ev(&e);
397 printf("Note(%d): %lf %d %lf %lf\n",
398 track, cur_time, np, length, volume);
400 /* add arpeggiator repetitions */
401 for(n=0;n < n_arps;n++)
403 e.note.time=cur_time + arps[n].delay;
404 e.note.trk_id=arps[n].track;
405 e.note.note=np + arps[n].transpose;
406 e.note.vol=volume * arps[n].volume;
408 add_song_ev(&e);
413 static void add_tempo_event(int trk_id, double tempo)
415 union song_ev e;
417 e.tempo.type=SONG_EV_TEMPO;
418 e.tempo.time=cur_time;
419 e.tempo.trk_id=trk_id;
420 e.tempo.tempo=tempo;
421 add_song_ev(&e);
425 static void add_meter_event(int trk_id, int num, int den)
427 union song_ev e;
429 e.meter.type=SONG_EV_METER;
430 e.meter.time=cur_time;
431 e.meter.trk_id=trk_id;
432 e.meter.num=num;
433 e.meter.den=den;
434 add_song_ev(&e);
437 static void add_measure_event(void)
439 union song_ev e;
441 e.generic.type=SONG_EV_MEASURE;
442 e.generic.time=cur_time;
443 e.generic.trk_id=-1;
444 add_song_ev(&e);
448 static void add_ss_sustain_event(double sustain)
450 union song_ev e;
452 e.ss_sustain.type=SONG_EV_SS_SUSTAIN;
453 e.ss_sustain.time=cur_time;
454 e.ss_sustain.trk_id=track;
455 e.ss_sustain.sustain=sustain;
457 add_song_ev(&e);
461 static void add_ss_channel_event(int channel, float vol)
463 union song_ev e;
465 e.ss_channel.type=SONG_EV_SS_CHANNEL;
466 e.ss_channel.time=cur_time;
467 e.ss_channel.trk_id=track;
468 e.ss_channel.channel=channel;
469 e.ss_channel.vol=vol;
471 add_song_ev(&e);
475 static void add_ss_wav_event(char * wav_file, int base, int min, int max,
476 double loop_start, double loop_end)
478 union song_ev e;
480 e.ss_wav.type=SONG_EV_SS_WAV;
481 e.ss_wav.time=cur_time;
482 e.ss_wav.trk_id=track;
483 e.ss_wav.file=wav_file;
484 e.ss_wav.base=base;
485 e.ss_wav.min=min;
486 e.ss_wav.max=max;
487 e.ss_wav.loop_start=loop_start;
488 e.ss_wav.loop_end=loop_end;
489 add_song_ev(&e);
493 static void add_ss_pat_event(char * pat_file)
495 union song_ev e;
497 e.ss_pat.type=SONG_EV_SS_PAT;
498 e.ss_pat.time=cur_time;
499 e.ss_pat.trk_id=track;
500 e.ss_pat.file=pat_file;
502 add_song_ev(&e);
506 static void add_ss_eff_event(int type, int channel, double size, float gain,
507 double depth, double freq, double phase, float initial, float final)
509 union song_ev e;
511 e.ss_eff.type=type;
512 e.ss_eff.time=cur_time;
513 e.ss_eff.trk_id=track;
514 e.ss_eff.channel=channel;
515 e.ss_eff.size=size;
516 e.ss_eff.gain=gain;
517 e.ss_eff.depth=depth;
518 e.ss_eff.freq=freq;
519 e.ss_eff.phase=phase;
520 e.ss_eff.initial=initial;
521 e.ss_eff.final=final;
523 add_song_ev(&e);
527 static void add_ss_pitch_stretch(int note, double len, float vol)
529 union song_ev e;
531 e.ss_pitch_stretch.type=SONG_EV_SS_PITCH_STRETCH;
532 e.ss_pitch_stretch.time=cur_time;
533 e.ss_pitch_stretch.trk_id=track;
534 e.ss_pitch_stretch.note=note;
535 e.ss_pitch_stretch.len=len;
536 e.ss_pitch_stretch.vol=vol;
538 add_song_ev(&e);
542 static void add_midi_channel_event(int channel)
544 union song_ev e;
546 e.midi_channel.type=SONG_EV_MIDI_CHANNEL;
547 e.midi_channel.time=cur_time;
548 e.midi_channel.trk_id=track;
549 e.midi_channel.channel=channel;
551 add_song_ev(&e);
555 static void add_midi_program_event(int program)
557 union song_ev e;
559 e.midi_program.type=SONG_EV_MIDI_PROGRAM;
560 e.midi_program.time=cur_time;
561 e.midi_program.trk_id=track;
562 e.midi_program.program=program;
564 add_song_ev(&e);
568 static void init_track(void)
569 /* sets the default values for a new track */
571 cur_time=0.0;
572 length=0.0;
573 transpose=0;
574 staccato=0.8;
575 volume=0.75;
576 octave=5;
577 gliss=0;
579 /* groups should not cross track boundaries */
580 n_groups=0;
582 /* reset arpeggiator */
583 n_arps=0;
584 arp_default();
590 %union {
591 int i;
592 double d;
593 char * p;
596 %token <i> P_INTEGER S_INTEGER
597 %token <d> P_REAL S_REAL
598 %token <i> NOTE_P NOTE_T3 NOTE_T5
599 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
601 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
603 %token <p> XC_STR
604 %token <i> XC_MSECS XC_ABSNOTE
606 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT SS_SUSTAIN SS_VIBRATO SS_CHANNEL SS_VOL
608 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS SS_EFF_FLANGER
609 %token SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_FADER SS_EFF_REVERB SS_EFF_OFF
611 %token SS_PITCH_STRETCH SS_TIME_STRETCH
613 %token MIDI_CHANNEL MIDI_PROGRAM MIDI_GENERIC
615 %type <i> integer note note_pitch rest
616 %type <d> real p_number number note_length
618 %type <d> arp_list arp_note
619 %type <i> xc_absnote
623 script:
624 script stmt { ; }
625 | /* NULL */
628 stmt:
629 note {
630 /* note event */
631 add_note_event($1);
632 forward(length);
634 | rest {
635 /* rest */
636 forward(length);
638 | 'z' note_length {
639 /* zero note */
640 length=$2;
642 | 'o' P_INTEGER {
643 /* absolute octave */
644 octave=$2;
646 | 'o' S_INTEGER {
647 /* relative octave */
648 octave += $2;
650 | 'v' P_INTEGER {
651 /* absolute volume */
652 volume=(float)$2;
654 | 'v' P_REAL {
655 /* absolute volume */
656 volume=(float)$2;
658 | 'v' S_REAL {
659 /* relative volume */
660 volume += (float)$2;
662 | 't' integer {
663 /* transpose */
664 transpose=$2;
666 | 's' p_number {
667 /* staccato */
668 staccato=$2;
671 | '<' {
672 /* start of group */
673 push_group();
675 | ';' {
676 /* group delimiter */
677 next_group_part();
679 | '>' {
680 /* end of group */
681 pop_group();
683 | 'l' note_length {
684 /* glissando */
685 gliss=$2;
688 | '|' {
689 /* measure mark event */
690 add_measure_event();
693 | NEW_MARK {
694 /* add new mark */
695 add_mark($1);
697 | GOTO_MARK {
698 /* go to mark */
699 find_mark($1, 1);
701 | ASSERT_MARK {
702 /* assert mark */
703 find_mark($1, 0);
706 | '\\' {
707 /* new track */
709 track++;
710 init_track();
712 | 'T' p_number {
713 /* tempo setting */
714 add_tempo_event(-1, $2);
716 | 'M' P_INTEGER '/' P_INTEGER {
717 /* meter (time signature) setting */
718 add_meter_event(-1, $2, $4);
721 | BLOCK '*' P_INTEGER {
722 /* repeat block */
723 push_code($1, $3, 1);
725 | BLOCK BLK_ASSIGN {
726 /* assign block */
727 set_named_block($2, $1);
729 | BLK_INSERT {
730 /* insert named block */
731 insert_named_block($1);
733 | FILE_INSERT {
734 /* insert file */
735 insert_file($1);
738 | arp { ; }
740 | xc_cmd { ; }
744 integer:
745 P_INTEGER { $$ = $1; }
746 | S_INTEGER { $$ = $1; }
749 real:
750 P_REAL { $$ = $1; }
751 | S_REAL { $$ = $1; }
754 p_number:
755 P_INTEGER { $$ = (double) $1; }
756 | P_REAL { $$ = $1; }
759 number:
760 integer { $$ = (double) $1; }
761 | real { $$ = $1; }
764 note:
765 note_pitch { $$ = $1; }
766 | note note_length { $$ = $1; length=$2; }
767 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
770 note_pitch:
771 NOTE_P { $$ = $1; }
772 | note_pitch '&' { $$ = $1 - 1; }
773 | note_pitch '#' { $$ = $1 + 1; }
774 | note_pitch '\'' { $$ = $1 + 12; }
775 | note_pitch ',' { $$ = $1 - 12; }
778 note_length:
779 P_INTEGER { $$ = 1 / (double) $1; }
780 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
781 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
782 | note_length '*' p_number { $$ = $1 * $3; }
783 | note_length '.' { $$ = $1 * 1.5; }
786 rest:
787 'r' { ; }
788 | rest note_length {
789 /* rest with length */
790 length=$2;
794 arp:
795 'x' {
796 /* empty arpeggiator */
797 n_arps=0;
798 arp_default();
800 | 'x' arp_list { ; }
803 arp_list:
804 arp_note {
805 /* first arpeggiator note */
806 n_arps=0;
807 add_arp();
809 | arp_list ',' arp_note {
810 /* rest of arpeggiator notes */
811 add_arp();
815 arp_note:
816 note_length {
817 /* arpeggiator delay */
818 arp_delay=$1;
820 | arp_note '~' number {
821 /* arpeggiator volume */
822 arp_volume=(float)$3;
824 | arp_note S_INTEGER {
825 /* arpeggiator transpose */
826 arp_transpose=$2;
828 | arp_note '@' P_INTEGER {
829 /* arpeggiator track */
830 arp_track=$3;
834 xc_absnote:
835 P_INTEGER { $$ = $1; }
836 | XC_ABSNOTE { $$ = $1; }
839 xc_cmd:
840 SS_WAV XC_STR xc_absnote {
841 /* load .wav file with just one note */
842 add_ss_wav_event($2, $3, $3, $3, -1.0, -1.0);
844 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote {
845 /* load .wav file */
846 add_ss_wav_event($2, $3, $4, $5, -1.0, -1.0);
848 | SS_WAV XC_STR xc_absnote xc_absnote xc_absnote number number {
849 /* load .wav file, with loop boundaries */
850 add_ss_wav_event($2, $3, $4, $5, $6, $7);
852 | SS_PAT XC_STR {
853 /* load .pat file */
854 add_ss_pat_event($2);
856 | SS_SUSTAIN XC_MSECS {
857 /* sets sustain */
858 add_ss_sustain_event($2);
860 | SS_CHANNEL integer number {
861 /* sets volume for a channel */
862 add_ss_channel_event($2, $3);
864 | SS_VOL number number {
865 /* set vol for 2 channels */
866 add_ss_channel_event(0, $2);
867 add_ss_channel_event(1, $3);
869 | SS_VOL number number number {
870 /* set vol for 3 channels */
871 add_ss_channel_event(0, $2);
872 add_ss_channel_event(1, $3);
873 add_ss_channel_event(2, $4);
875 | SS_VOL number number number number {
876 /* set vol for 4 channels */
877 add_ss_channel_event(0, $2);
878 add_ss_channel_event(1, $3);
879 add_ss_channel_event(2, $4);
880 add_ss_channel_event(3, $5);
882 | SS_VOL number number number number number number {
883 /* set vol for 6 channels */
884 add_ss_channel_event(0, $2);
885 add_ss_channel_event(1, $3);
886 add_ss_channel_event(2, $4);
887 add_ss_channel_event(3, $5);
888 add_ss_channel_event(4, $6);
889 add_ss_channel_event(5, $7);
891 | SS_EFF_DELAY integer XC_MSECS {
892 /* delay effect */
893 add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
894 $2, $3, 0, 0, 0, 0, 0, 0);
897 | SS_EFF_ECHO integer XC_MSECS number {
898 /* echo effect */
899 add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
900 $2, $3, $4, 0, 0, 0, 0, 0);
903 | SS_EFF_COMB integer XC_MSECS number {
904 /* comb effect */
905 add_ss_eff_event(SONG_EV_SS_EFF_COMB,
906 $2, $3, $4, 0, 0, 0, 0, 0);
909 | SS_EFF_ALLPASS integer XC_MSECS number {
910 /* allpass effect */
911 add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
912 $2, $3, $4, 0, 0, 0, 0, 0);
915 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
916 /* flanger effect */
917 add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
918 $2, $3, $4, $5, $6, $7, 0, 0);
921 | SS_EFF_WOBBLE integer number number {
922 /* wobble effect */
923 add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
924 $2, 0, 0, 0, $3, $4, 0, 0);
927 | SS_EFF_SQWOBBLE integer number number {
928 /* square wobble effect */
929 add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
930 $2, 0, 0, 0, $3, $4, 0, 0);
933 | SS_EFF_FADER integer XC_MSECS number number {
934 /* fader effect */
935 add_ss_eff_event(SONG_EV_SS_EFF_FADER,
936 $2, $3, 0, 0, 0, 0, $4, $5);
939 | SS_EFF_REVERB integer {
940 /* reverb effect */
941 add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
942 $2, 0, 0, 0, 0, 0, 0, 0);
945 | SS_EFF_OFF integer {
946 /* off effect */
947 add_ss_eff_event(SONG_EV_SS_EFF_OFF,
948 $2, 0, 0, 0, 0, 0, 0, 0);
951 | SS_PITCH_STRETCH xc_absnote number number {
952 /* pitch stretch note */
953 add_ss_pitch_stretch($2, $3, $4);
955 forward($3);
958 | MIDI_CHANNEL integer {
959 /* midi channel */
960 add_midi_channel_event($2);
963 | MIDI_PROGRAM integer {
964 /* midi program */
965 add_midi_program_event($2);
971 void yyerror(char * s)
973 c_err(s, NULL, NULL);
976 #ifdef QQ
977 int main(void)
979 init_track();
981 push_code("!this-is-a-mark", 1, 0);
982 push_code("< c1 ; e& ; g>", 1, 0);
983 push_code("^this-is-a-mark", 1, 0);
984 push_code("x4,2-1,2.+4", 1, 0);
985 push_code("a b'' c,, ", 1, 0);
986 push_code("v0.1 (d8 v+0.1)*10", 1, 0);
987 push_code("t1 t-2 t+3", 1, 0);
988 push_code("{ fader -1 100ms 0 1 } r r4. z2 `room_kit.ahs` o4 o+1 o-2 ", 1, 0);
989 push_code("{ sustain 100ms }", 1, 0);
990 push_code("T120.0 M4/4 z8 abcde T80 (edcba)=drum1 $drum1 $drum1 ((a&b)*3 (cd)*2)*10", 2, 0);
992 yyparse();
994 printf("Exiting main...\n");
995 exit(0);
997 #endif
999 static void compile_startup(void)
1001 track=0;
1002 yyline=1;
1003 compiler_error=0;
1005 /* default settings */
1006 add_tempo_event(-2, 120.0);
1007 add_meter_event(-2, 4, 4);
1008 init_track();
1012 int compile(char * code)
1014 compile_startup();
1016 push_code(code, 1, 0);
1018 return(yyparse() + compiler_error);
1022 int compile_file(char * file)
1024 compile_startup();
1026 if(insert_file(file))
1027 return(1);
1029 return(yyparse() + compiler_error);