Tempo and measure events are generated.
[ahxm.git] / compiler.y
blobce6fae178b2a29d2c437698e86085cc2a08e273b
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 "event.h"
37 /*******************
38 Data
39 ********************/
41 int yylex(void);
42 void yyerror(char * s);
44 /* injecting code functions (defined in compiler.l) */
45 extern int push_code(char * code, int times, int dyn);
46 extern int push_code_from_file(char * file);
48 /* current track */
49 int _track;
51 /* current time */
52 double _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 static int _meas_num=4;
63 static int _meas_den=4;
65 /* parser debugging */
67 int _debug=1;
68 #define DEBUGF if(_debug)printf
70 /* named blocks */
72 struct _named_block
74 char name[64];
75 char * block;
78 static struct _named_block * _named_blocks=NULL;
79 static int _n_named_blocks=0;
80 static int _named_blocks_size=0;
82 /* group info */
83 struct _group
85 double start;
86 double gliss;
87 double max;
90 static struct _group * _groups=NULL;
91 static int _n_groups=0;
92 static int _groups_size=0;
94 /* mark info */
95 struct _mark
97 char name[64];
98 double time;
101 static struct _mark * _marks=NULL;
102 static int _n_marks=0;
103 static int _marks_size=0;
105 /* arpeggiator */
106 struct _arp
108 double delay;
109 int transpose;
110 float volume;
111 int track;
114 static struct _arp * _arps=NULL;
115 static int _n_arps=0;
116 static int _arps_size=0;
118 static double _arp_delay;
119 static int _arp_transpose;
120 static float _arp_volume;
121 static int _arp_track;
123 /*******************
124 Code
125 ********************/
127 void _c_err(char * e1, char * e2, char * e3)
128 /* reports an error from the compiler */
130 printf("Compiler error:");
131 if(e1 != NULL) printf(" %s", e1);
132 if(e2 != NULL) printf(" %s", e2);
133 if(e3 != NULL) printf(" %s", e3);
134 printf("\n");
138 static void _forward(void)
139 /* moves forward current time by current length */
141 /* just add current length to time cursor */
142 _time += _length;
144 /* quantizations could be done here */
148 static void _init_track(void)
149 /* sets the default values for a new track */
151 _time=0.0;
152 _length=0.0;
153 _transpose=0;
154 _staccato=0.8;
155 _volume=0.75;
156 _octave=5;
157 _gliss=0;
159 /* groups should not cross track boundaries */
160 _n_groups=0;
162 /* reset arpeggiator */
163 _n_arps=0;
167 /* named blocks */
169 static int _set_named_block(char * name, char * block)
170 /* sets a named block */
172 int n;
174 /* find first if block is previously defined */
175 for(n=0;n < _n_named_blocks;n++)
177 if(strcmp(name, _named_blocks[n].name) == 0)
179 free(_named_blocks[n].block);
180 break;
184 if(n == _n_named_blocks)
186 /* need to expand? */
187 if(_n_named_blocks == _named_blocks_size)
189 _named_blocks_size += 4;
191 _named_blocks=(struct _named_block *)
192 realloc(_named_blocks,
193 _named_blocks_size *
194 sizeof(struct _named_block));
197 _n_named_blocks++;
200 strncpy(_named_blocks[n].name, name, sizeof(_named_blocks[n].name));
201 _named_blocks[n].block=block;
203 return(1);
207 static void _insert_named_block(char * name)
208 /* inserts a named block */
210 int n;
212 for(n=0;n < _n_named_blocks;n++)
214 if(strcmp(name, _named_blocks[n].name) == 0)
216 push_code(_named_blocks[n].block, 1, 0);
217 return;
221 _c_err("block-not-found", name, NULL);
225 static void _insert_file(char * filename)
227 if(!push_code_from_file(filename))
228 _c_err("script-not-found", filename, NULL);
232 /* groups */
234 static int _push_group(void)
235 /* starts a new group of notes */
237 if(_n_groups == _groups_size)
239 _groups_size += 4;
241 _groups=(struct _group *) realloc(_groups,
242 _groups_size * sizeof(struct _group));
245 _groups[_n_groups].start=_time;
246 _groups[_n_groups].gliss=0.0;
247 _groups[_n_groups].max=0.0;
249 _n_groups++;
251 return(1);
255 static int _next_group_part(void)
256 /* part delimiter */
258 if(_n_groups == 0)
260 _c_err("missing-start-of-group", NULL, NULL);
261 return(0);
264 /* store maximum frame */
265 if(_groups[_n_groups - 1].max < _time)
266 _groups[_n_groups - 1].max=_time;
268 /* add glissando delay */
269 _groups[_n_groups - 1].gliss += _gliss;
271 /* rewind */
272 _time=_groups[_n_groups - 1].start + _groups[_n_groups - 1].gliss;
274 return(1);
278 static int _pop_group(void)
279 /* finishes a group, moving the frame to the end of the longer part */
281 if(_n_groups == 0)
283 _c_err("missing-start-of-group", NULL, NULL);
284 return(0);
287 _n_groups--;
289 _time=_groups[_n_groups].max;
291 return(1);
295 /* marks */
297 static void _add_mark(char * name)
298 /* creates a new mark */
300 if(_n_marks == _marks_size)
302 _marks_size += 4;
304 _marks=(struct _mark *) realloc(_marks,
305 _marks_size * sizeof(struct _mark));
308 strncpy(_marks[_n_marks].name, name, sizeof(_marks[_n_marks].name));
309 _marks[_n_marks].time=_time;
311 _n_marks++;
315 static void _find_mark(char * name, int set)
316 /* finds a mark by name, optionally moving time cursor there */
318 int n;
320 for(n=0;n < _n_marks;n++)
322 if(strcmp(_marks[n].name, name) == 0)
324 if(set)
326 if(_time > _marks[n].time)
327 _c_err("mark-overpassed", name, NULL);
328 else
329 _time=_marks[n].time;
331 else
332 if(_time != _marks[n].time)
333 _c_err("mark-mismatch", name, NULL);
335 return;
339 _c_err("mark-not-found", name, NULL);
343 /* arpeggiator */
345 static void _arp_default(void)
346 /* resets arpeggiator values to the default ones */
348 _arp_delay=0.0;
349 _arp_transpose=0;
350 _arp_volume=1.0;
351 _arp_track=_track;
355 static void _add_arp(void)
356 /* adds an arpeggiator note */
358 /* if the note is exactly the same, do nothing */
359 if(_arp_delay == 0.0 && _arp_transpose == 0 &&
360 _arp_volume == 1.0 && _arp_track == _track)
361 return;
363 if(_n_arps == _arps_size)
365 _arps_size += 4;
367 _arps=(struct _arp *) realloc(_arps,
368 _arps_size * sizeof(struct _arp));
371 _arps[_n_arps].delay=_arp_delay;
372 _arps[_n_arps].transpose=_arp_transpose;
373 _arps[_n_arps].volume=_arp_volume;
374 _arps[_n_arps].track=_arp_track;
376 _n_arps++;
377 _arp_default();
381 /* events */
383 static void _add_note_event(int note)
384 /* adds a note event */
386 int n;
387 int np;
388 union event1 e1;
390 /* calculate the note */
391 np=note + _transpose + (_octave * 12);
393 /* is note out of range? */
394 if(np < 0 || np > 127)
396 _c_err("note-out-of-range", NULL, NULL);
397 return;
400 e1.note.type=EV1_NOTE;
401 e1.note.time=_time;
402 e1.note.trk_id=_track;
403 e1.note.note=np;
404 e1.note.len=_length * _staccato;
405 e1.note.vol=_volume;
407 new_event1(&e1);
409 printf("Note(%d): %lf %d %lf %lf\n",
410 _track, _time, np, _length, _volume);
412 /* add arpeggiator repetitions */
413 for(n=0;n < _n_arps;n++)
415 e1.note.time=_time + _arps[n].delay;
416 e1.note.trk_id=_arps[n].track;
417 e1.note.note=np + _arps[n].transpose;
418 e1.note.vol=_volume * _arps[n].volume;
420 new_event1(&e1);
425 static void _add_tempo_event(double tempo)
427 union event1 e1;
429 e1.tempo.type=EV1_TEMPO;
430 e1.tempo.time=_time;
431 e1.tempo.trk_id=_track;
432 e1.tempo.tempo=tempo;
433 new_event1(&e1);
437 static void _add_measure_event(int num, int den)
439 union event1 e1;
441 e1.measure.type=EV1_MEASURE;
442 e1.measure.time=_time;
443 e1.measure.trk_id=_track;
444 e1.measure.num=num;
445 e1.measure.den=den;
446 new_event1(&e1);
452 %union {
453 int i;
454 double d;
455 char * p;
458 %token <i> P_INTEGER S_INTEGER
459 %token <d> P_REAL S_REAL
460 %token <i> NOTE_P NOTE_T3 NOTE_T5
461 %token <p> NEW_MARK GOTO_MARK ASSERT_MARK
463 %token <p> BLOCK BLK_ASSIGN BLK_INSERT FILE_INSERT
465 %token <p> SS_STR
466 %token <i> SS_FRAMES
468 %token SS_SEP SS_WAV SS_PAT SS_SUSTAIN
469 %token SS_EFF_DELAY SS_EFF_ECHO SS_EFF_COMB SS_EFF_ALLPASS
470 %token SS_EFF_FLANGER SS_EFF_WOBBLE SS_EFF_SQWOBBLE SS_EFF_FADER
472 %type <i> integer note note_pitch rest
473 %type <d> real p_number number note_length
475 %type <d> arp_list arp_note
479 script:
480 script stmt { ; }
481 | /* NULL */
484 stmt:
485 note {
486 /* note event */
487 _add_note_event($1);
488 _forward();
490 | rest {
491 /* rest */
492 _forward();
494 | 'z' note_length {
495 /* zero note */
496 _length=$2;
498 | 'o' P_INTEGER {
499 /* absolute octave */
500 _octave=$2;
502 | 'o' S_INTEGER {
503 /* relative octave */
504 _octave += $2;
506 | 'v' P_REAL {
507 /* absolute volume */
508 _volume=(float)$2;
510 | 'v' S_REAL {
511 /* relative volume */
512 _volume += (float)$2;
514 | 't' integer {
515 /* transpose */
516 _transpose=$2;
518 | 's' p_number {
519 /* staccato */
520 _staccato=$2;
523 | '<' {
524 /* start of group */
525 _push_group();
527 | ';' {
528 /* group delimiter */
529 _next_group_part();
531 | '>' {
532 /* end of group */
533 _pop_group();
535 | 'l' note_length {
536 /* glissando */
537 _gliss=$2;
540 | '|' { DEBUGF("Measure mark\n"); }
542 | NEW_MARK {
543 /* add new mark */
544 _add_mark($1);
546 | GOTO_MARK {
547 /* go to mark */
548 _find_mark($1, 1);
550 | ASSERT_MARK {
551 /* assert mark */
552 _find_mark($1, 0);
555 | '\\' {
556 /* new track */
558 _track++;
559 _init_track();
561 | 'T' p_number {
562 /* tempo setting */
563 _add_tempo_event($2);
565 | 'M' P_INTEGER '/' P_INTEGER {
566 /* measure setting */
567 _add_measure_event($2, $4);
570 | BLOCK '*' P_INTEGER {
571 /* repeat block */
572 push_code($1, $3, 1);
574 | BLOCK BLK_ASSIGN {
575 /* assign block */
576 _set_named_block($2, $1);
578 | BLK_INSERT {
579 /* insert named block */
580 _insert_named_block($1);
582 | FILE_INSERT {
583 /* insert file */
584 _insert_file($1);
587 | arp { ; }
589 | ss_cmd { DEBUGF("ss_cmd\n"); }
593 integer:
594 P_INTEGER { $$ = $1; }
595 | S_INTEGER { $$ = $1; }
598 real:
599 P_REAL { $$ = $1; }
600 | S_REAL { $$ = $1; }
603 p_number:
604 P_INTEGER { $$ = (double) $1; }
605 | P_REAL { $$ = $1; }
608 number:
609 integer { $$ = (double) $1; }
610 | real { $$ = $1; }
613 note:
614 note_pitch { $$ = $1; }
615 | note note_length { $$ = $1; _length=$2; }
616 | note '~' number { $$ = $1; DEBUGF("imm volume: %lf\n", $3); }
619 note_pitch:
620 NOTE_P { $$ = $1; }
621 | note_pitch '&' { $$ = $1 - 1; }
622 | note_pitch '#' { $$ = $1 + 1; }
623 | note_pitch '\'' { $$ = $1 + 12; }
624 | note_pitch ',' { $$ = $1 - 12; }
627 note_length:
628 P_INTEGER { $$ = 1 / (double) $1; }
629 | note_length NOTE_T3 { $$ = $1 * 2.0 / 3.0; }
630 | note_length NOTE_T5 { $$ = $1 * 4.0 / 5.0; }
631 | note_length '*' p_number { $$ = $1 * $3; }
632 | note_length '.' { $$ = $1 * 1.5; }
635 rest:
636 'r' { ; }
637 | rest note_length {
638 /* rest with length */
639 _length=$2;
643 arp:
644 'x' {
645 /* empty arpeggiator */
646 _n_arps=0;
647 _arp_default();
649 | 'x' arp_list { ; }
652 arp_list:
653 arp_note {
654 /* first arpeggiator note */
655 _n_arps=0;
656 _add_arp();
658 | arp_list ',' arp_note {
659 /* rest of arpeggiator notes */
660 _add_arp();
664 arp_note:
665 note_length {
666 /* arpeggiator delay */
667 _arp_delay=$1;
669 | arp_note '~' number {
670 /* arpeggiator volume */
671 _arp_volume=(float)$3;
673 | arp_note S_INTEGER {
674 /* arpeggiator transpose */
675 _arp_transpose=$2;
677 | arp_note '@' P_INTEGER {
678 /* arpeggiator track */
679 _arp_track=$3;
683 ss_cmd:
684 SS_WAV SS_STR { DEBUGF("SS_WAV: %s\n", $2); }
685 | SS_PAT SS_STR { DEBUGF("SS_PAT: %s\n", $2); }
686 | SS_SUSTAIN SS_FRAMES { DEBUGF("SS_SUSTAIN: %d\n", $2); }
687 | SS_EFF_DELAY S_INTEGER SS_FRAMES { DEBUGF("delay chan: %d frames: %d\n", $2, $3); }
688 | SS_EFF_ECHO S_INTEGER SS_FRAMES number { DEBUGF("echo chan: %d frames: %d gain: %lf\n", $2, $3, $4); }
689 | SS_EFF_FADER S_INTEGER SS_FRAMES number number { DEBUGF("fader chan: %d frames: %d %lf .. %lf\n", $2, $3, $4, $5); }
694 void yyerror(char * s)
696 printf("yyerror: %s\n", s);
700 int main(void)
702 _init_track();
704 push_code("!this-is-a-mark", 1, 0);
705 push_code("< c1 ; e& ; g>", 1, 0);
706 push_code("^this-is-a-mark", 1, 0);
707 push_code("x4,2-1,2.+4", 1, 0);
708 push_code("a b'' c,, ", 1, 0);
709 push_code("v0.1 (d8 v+0.1)*10", 1, 0);
710 push_code("t1 t-2 t+3", 1, 0);
711 push_code("{ fader -1 100ms 0 1 } r r4. z2 `room_kit.ahs` o4 o+1 o-2 ", 1, 0);
712 push_code("{ sustain 100ms }", 1, 0);
713 push_code("T120.0 M4/4 z8 abcde T80 (edcba)=drum1 $drum1 $drum1 ((a&b)*3 (cd)*2)*10", 2, 0);
715 yyparse();
717 printf("Exiting main...\n");
718 exit(0);