input.c changed to ss_input.c (Closes: #1028).
[ahxm.git] / compiler.y
blob50229e896877c74aaa98e7b22186839778b5c96d
1 %{
2 /*
4 Ann Hell Ex Machina - Music Software
5 Copyright (C) 2003/2004 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 "core.h"
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(_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(void)
141 /* moves forward current time by current length */
143 /* just add current length to time cursor */
144 _cur_time += _length;
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_wav_event(char * wav_file, int base, int min, int max,
462 double loop_start, double loop_end)
464 union song_ev e;
466 e.ss_wav.type=SONG_EV_SS_WAV;
467 e.ss_wav.time=_cur_time;
468 e.ss_wav.trk_id=_track;
469 e.ss_wav.file=wav_file;
470 e.ss_wav.base=base;
471 e.ss_wav.min=min;
472 e.ss_wav.max=max;
473 e.ss_wav.loop_start=loop_start;
474 e.ss_wav.loop_end=loop_end;
475 add_song_ev(&e);
479 static void _add_ss_pat_event(char * pat_file)
481 union song_ev e;
483 e.ss_pat.type=SONG_EV_SS_PAT;
484 e.ss_pat.time=_cur_time;
485 e.ss_pat.trk_id=_track;
486 e.ss_pat.file=pat_file;
488 add_song_ev(&e);
492 static void _add_ss_eff_event(int type, int channel, double size, float gain,
493 double depth, double freq, double phase, float initial, float final)
495 union song_ev e;
497 e.ss_eff.type=type;
498 e.ss_eff.time=_cur_time;
499 e.ss_eff.trk_id=_track;
500 e.ss_eff.channel=channel;
501 e.ss_eff.size=size;
502 e.ss_eff.gain=gain;
503 e.ss_eff.depth=depth;
504 e.ss_eff.freq=freq;
505 e.ss_eff.phase=phase;
506 e.ss_eff.initial=initial;
507 e.ss_eff.final=final;
509 add_song_ev(&e);
513 static void _init_track(void)
514 /* sets the default values for a new track */
516 _cur_time=0.0;
517 _length=0.0;
518 _transpose=0;
519 _staccato=0.8;
520 _volume=0.75;
521 _octave=5;
522 _gliss=0;
524 /* groups should not cross track boundaries */
525 _n_groups=0;
527 /* reset arpeggiator */
528 _n_arps=0;
529 _arp_default();
535 %union {
536 int i;
537 double d;
538 char * p;
541 %token <i> P_INTEGER S_INTEGER
542 %token <d> P_REAL S_REAL
543 %token <i> NOTE_P NOTE_T3 NOTE_T5
544 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
546 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
548 %token <p> XC_STR
549 %token <i> XC_MSECS XC_ABSNOTE
551 %token SS_SEP SS_WAV SS_LOOP_WAV SS_PAT SS_SUSTAIN
552 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS
553 %token SS_EFF_FLANGER SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_FADER SS_EFF_REVERB
555 %type <i> integer note note_pitch rest
556 %type <d> real p_number number note_length
558 %type <d> arp_list arp_note
562 script:
563 script stmt { ; }
564 | /* NULL */
567 stmt:
568 note {
569 /* note event */
570 _add_note_event($1);
571 _forward();
573 | rest {
574 /* rest */
575 _forward();
577 | 'z' note_length {
578 /* zero note */
579 _length=$2;
581 | 'o' P_INTEGER {
582 /* absolute octave */
583 _octave=$2;
585 | 'o' S_INTEGER {
586 /* relative octave */
587 _octave += $2;
589 | 'v' P_INTEGER {
590 /* absolute volume */
591 _volume=(float)$2;
593 | 'v' P_REAL {
594 /* absolute volume */
595 _volume=(float)$2;
597 | 'v' S_REAL {
598 /* relative volume */
599 _volume += (float)$2;
601 | 't' integer {
602 /* transpose */
603 _transpose=$2;
605 | 's' p_number {
606 /* staccato */
607 _staccato=$2;
610 | '<' {
611 /* start of group */
612 _push_group();
614 | ';' {
615 /* group delimiter */
616 _next_group_part();
618 | '>' {
619 /* end of group */
620 _pop_group();
622 | 'l' note_length {
623 /* glissando */
624 _gliss=$2;
627 | '|' {
628 /* measure mark event */
629 _add_measure_event();
632 | NEW_MARK {
633 /* add new mark */
634 _add_mark($1);
636 | GOTO_MARK {
637 /* go to mark */
638 _find_mark($1, 1);
640 | ASSERT_MARK {
641 /* assert mark */
642 _find_mark($1, 0);
645 | '\\' {
646 /* new track */
648 _track++;
649 _init_track();
651 | 'T' p_number {
652 /* tempo setting */
653 _add_tempo_event(-1, $2);
655 | 'M' P_INTEGER '/' P_INTEGER {
656 /* meter (time signature) setting */
657 _add_meter_event(-1, $2, $4);
660 | BLOCK '*' P_INTEGER {
661 /* repeat block */
662 push_code($1, $3, 1);
664 | BLOCK BLK_ASSIGN {
665 /* assign block */
666 _set_named_block($2, $1);
668 | BLK_INSERT {
669 /* insert named block */
670 _insert_named_block($1);
672 | FILE_INSERT {
673 /* insert file */
674 _insert_file($1);
677 | arp { ; }
679 | xc_cmd { DEBUGF("xc_cmd\n"); }
683 integer:
684 P_INTEGER { $$ = $1; }
685 | S_INTEGER { $$ = $1; }
688 real:
689 P_REAL { $$ = $1; }
690 | S_REAL { $$ = $1; }
693 p_number:
694 P_INTEGER { $$ = (double) $1; }
695 | P_REAL { $$ = $1; }
698 number:
699 integer { $$ = (double) $1; }
700 | real { $$ = $1; }
703 note:
704 note_pitch { $$ = $1; }
705 | note note_length { $$ = $1; _length=$2; }
706 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
709 note_pitch:
710 NOTE_P { $$ = $1; }
711 | note_pitch '&' { $$ = $1 - 1; }
712 | note_pitch '#' { $$ = $1 + 1; }
713 | note_pitch '\'' { $$ = $1 + 12; }
714 | note_pitch ',' { $$ = $1 - 12; }
717 note_length:
718 P_INTEGER { $$ = 1 / (double) $1; }
719 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
720 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
721 | note_length '*' p_number { $$ = $1 * $3; }
722 | note_length '.' { $$ = $1 * 1.5; }
725 rest:
726 'r' { ; }
727 | rest note_length {
728 /* rest with length */
729 _length=$2;
733 arp:
734 'x' {
735 /* empty arpeggiator */
736 _n_arps=0;
737 _arp_default();
739 | 'x' arp_list { ; }
742 arp_list:
743 arp_note {
744 /* first arpeggiator note */
745 _n_arps=0;
746 _add_arp();
748 | arp_list ',' arp_note {
749 /* rest of arpeggiator notes */
750 _add_arp();
754 arp_note:
755 note_length {
756 /* arpeggiator delay */
757 _arp_delay=$1;
759 | arp_note '~' number {
760 /* arpeggiator volume */
761 _arp_volume=(float)$3;
763 | arp_note S_INTEGER {
764 /* arpeggiator transpose */
765 _arp_transpose=$2;
767 | arp_note '@' P_INTEGER {
768 /* arpeggiator track */
769 _arp_track=$3;
773 xc_cmd:
774 SS_WAV XC_STR XC_ABSNOTE XC_ABSNOTE XC_ABSNOTE {
775 /* load .wav file */
776 _add_ss_wav_event($2, $3, $4, $5, 0.0, 0.0);
778 | SS_WAV XC_STR XC_ABSNOTE XC_ABSNOTE XC_ABSNOTE number number {
779 /* load .wav file, with loop boundaries */
780 _add_ss_wav_event($2, $3, $4, $5, $6, $7);
782 | SS_PAT XC_STR {
783 /* load .pat file */
784 _add_ss_pat_event($2);
786 | SS_SUSTAIN XC_MSECS {
787 /* sets sustain */
788 _add_ss_sustain_event($2);
790 | SS_EFF_DELAY integer XC_MSECS {
791 /* delay effect */
792 _add_ss_eff_event(SONG_EV_SS_EFF_DELAY,
793 $2, $3, 0, 0, 0, 0, 0, 0);
796 | SS_EFF_ECHO integer XC_MSECS number {
797 /* echo effect */
798 _add_ss_eff_event(SONG_EV_SS_EFF_ECHO,
799 $2, $3, $4, 0, 0, 0, 0, 0);
802 | SS_EFF_COMB integer XC_MSECS number {
803 /* comb effect */
804 _add_ss_eff_event(SONG_EV_SS_EFF_COMB,
805 $2, $3, $4, 0, 0, 0, 0, 0);
808 | SS_EFF_ALLPASS integer XC_MSECS number {
809 /* allpass effect */
810 _add_ss_eff_event(SONG_EV_SS_EFF_ALLPASS,
811 $2, $3, $4, 0, 0, 0, 0, 0);
814 | SS_EFF_FLANGER integer XC_MSECS number XC_MSECS number number {
815 /* flanger effect */
816 _add_ss_eff_event(SONG_EV_SS_EFF_FLANGER,
817 $2, $3, $4, $5, $6, $7, 0, 0);
820 | SS_EFF_WOBBLE integer number number {
821 /* wobble effect */
822 _add_ss_eff_event(SONG_EV_SS_EFF_WOBBLE,
823 $2, 0, 0, 0, $3, $4, 0, 0);
826 | SS_EFF_SQWOBBLE integer number number {
827 /* square wobble effect */
828 _add_ss_eff_event(SONG_EV_SS_EFF_SQWOBBLE,
829 $2, 0, 0, 0, $3, $4, 0, 0);
832 | SS_EFF_FADER integer XC_MSECS number number {
833 /* fader effect */
834 _add_ss_eff_event(SONG_EV_SS_EFF_FADER,
835 $2, $3, 0, 0, 0, 0, $4, $5);
838 | SS_EFF_REVERB integer {
839 /* reverb effect */
840 _add_ss_eff_event(SONG_EV_SS_EFF_REVERB,
841 $2, 0, 0, 0, 0, 0, 0, 0);
847 void yyerror(char * s)
849 _c_err(s, NULL, NULL);
852 #ifdef QQ
853 int main(void)
855 _init_track();
857 push_code("!this-is-a-mark", 1, 0);
858 push_code("< c1 ; e& ; g>", 1, 0);
859 push_code("^this-is-a-mark", 1, 0);
860 push_code("x4,2-1,2.+4", 1, 0);
861 push_code("a b'' c,, ", 1, 0);
862 push_code("v0.1 (d8 v+0.1)*10", 1, 0);
863 push_code("t1 t-2 t+3", 1, 0);
864 push_code("{ fader -1 100ms 0 1 } r r4. z2 `room_kit.ahs` o4 o+1 o-2 ", 1, 0);
865 push_code("{ sustain 100ms }", 1, 0);
866 push_code("T120.0 M4/4 z8 abcde T80 (edcba)=drum1 $drum1 $drum1 ((a&b)*3 (cd)*2)*10", 2, 0);
868 yyparse();
870 printf("Exiting main...\n");
871 exit(0);
873 #endif
875 static void compile_startup(void)
877 _track=0;
878 yyline=1;
879 compiler_error=0;
881 /* default settings */
882 _add_tempo_event(-2, 120.0);
883 _add_meter_event(-2, 4, 4);
884 _init_track();
888 int compile(char * code)
890 compile_startup();
892 push_code(code, 1, 0);
894 return(yyparse() + compiler_error);
898 int compile_file(char * file)
900 compile_startup();
902 if(_insert_file(file))
903 return(1);
905 return(yyparse() + compiler_error);