Added named block and file insertion code to lexer/parser.
[ahxm.git] / event.c
blob57152d20310507030df10eb38a0963838cd10e7d
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2004 Angel Ortega <angel@triptico.com>
6 event.c - Music events
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
26 #include "config.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <math.h>
33 #include "core.h"
34 #include "event.h"
37 /*******************
38 Data
39 ********************/
41 /* stage 1 events */
42 union event1 * _events_1=NULL;
44 /* number of events */
45 int _n_events_1=0;
47 /* stage 2 events */
48 union event2 * _events_2=NULL;
50 /* number of events */
51 int _n_events_2=0;
54 /*******************
55 Code
56 ********************/
58 void new_event1(union event1 * ev)
60 _n_events_1++;
62 /* reallocs */
63 _events_1=(union event1 *)realloc(_events_1,
64 _n_events_1 * sizeof(union event1));
66 /* store */
67 memcpy(&_events_1[_n_events_1 - 1], ev, sizeof(union event1));
71 void event1_clear(void)
73 union event1 e1;
75 if(_events_1 != NULL)
77 free(_events_1);
78 _events_1=NULL;
81 _n_events_1=0;
83 /* adds a default tempo */
84 e1.tempo.type=EV1_TEMPO;
85 e1.tempo.time=0;
86 e1.tempo.trk_id=-2;
87 e1.tempo.tempo=120.0;
89 new_event1(&e1);
93 static int _event1_cmp(const void * v1, const void * v2)
95 struct ev1_generic * e1;
96 struct ev1_generic * e2;
98 e1=(struct ev1_generic *)v1; e2=(struct ev1_generic *)v2;
100 if(e1->time == e2->time)
101 return(e1->type - e2->type);
103 return(e1->time - e2->time);
107 void event1_sort(void)
109 struct ev1_generic e;
111 qsort(_events_1, _n_events_1, sizeof(union event1), _event1_cmp);
113 e.type=EV1_END;
114 new_event1((union event1 *) &e);
118 /* stage 2 events */
120 void event2_clear(void)
122 if(_events_2 != NULL)
124 free(_events_2);
125 _events_2=NULL;
128 _n_events_2=0;
132 void new_event2(union event2 * ev)
134 _n_events_2++;
136 /* reallocs */
137 _events_2=(union event2 *)realloc(_events_2,
138 _n_events_2 * sizeof(union event2));
140 /* store */
141 memcpy(&_events_2[_n_events_2 - 1], ev, sizeof(union event2));
145 static int _event2_cmp(const void * v1, const void * v2)
147 struct ev2_generic * e1;
148 struct ev2_generic * e2;
150 e1=(struct ev2_generic *)v1; e2=(struct ev2_generic *)v2;
152 if(e1->frame == e2->frame)
153 return(e1->type - e2->type);
155 return(e1->frame - e2->frame);
159 void event2_sort(void)
161 struct ev2_generic e;
163 qsort(_events_2, _n_events_2, sizeof(union event2), _event2_cmp);
165 e.type=EV2_END;
166 new_event2((union event2 *) &e);
170 void event1_to_event2(void)
172 int note_id=1;
173 union event1 * e1;
174 union event2 e2;
175 int frame, frame_ac;
176 double tempo, time_ac;
178 event1_sort();
180 event2_clear();
182 tempo=0;
183 frame_ac=0;
184 time_ac=0;
186 for(e1=_events_1;e1->generic.type != EV1_END;e1++)
188 frame=((e1->generic.time - time_ac) * tempo) + frame_ac;
190 switch(e1->generic.type)
192 case EV1_TEMPO:
194 /* updates accumulations */
195 frame_ac += frame;
196 time_ac += e1->generic.time;
198 tempo=(double) _frequency * 60.0;
199 tempo /= e1->tempo.tempo / 4.0;
201 break;
203 case EV1_MEASURE:
205 break;
207 case EV1_NOTE:
209 e2.note_on.type=EV2_NOTE_ON;
210 e2.note_on.frame=frame;
211 e2.note_on.trk_id=e1->note.trk_id;
212 e2.note_on.note_id=note_id;
213 e2.note_on.note=e1->note.note;
214 e2.note_on.vol=e1->note.vol;
216 new_event2(&e2);
218 e2.note_off.type=EV2_NOTE_OFF;
219 e2.note_off.frame += (int)(e1->note.len * tempo);
221 new_event2(&e2);
223 note_id++;
227 event2_sort();