Updated TODO.
[ahxm.git] / song.c
blob5788769986cfb542ebaf20a3cc64e09ef7a46a2b
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2006 Angel Ortega <angel@triptico.com>
6 song.c - Device-independent song event stream management
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 "ahxm.h"
35 /*******************
36 Data
37 ********************/
39 /* the song event stream */
40 union song_ev * song = NULL;
42 /* number of song events */
43 int n_song_ev = 0;
45 /* solo track (-1, no solo) */
46 int solo_track = -1;
48 /*******************
49 Code
50 ********************/
52 /**
53 * song_clear - Clears the song stream
55 * Clears the song stream.
57 void song_clear(void)
59 if(song != NULL)
61 free(song);
62 song = NULL;
65 n_song_ev = 0;
69 /**
70 * add_song_ev - Adds a song event to the song stream
71 * @type: event type
72 * @time: event time
73 * @ev: the event
75 * Adds a song event to the song stream.
77 void add_song_ev(song_ev_type type, double time, union song_ev * ev)
79 /* skip tracks if a solo is requested */
80 if(solo_track != -1 && ev->generic.trk_id >= 0 &&
81 ev->generic.trk_id != solo_track)
82 return;
84 GROW(song, n_song_ev, union song_ev);
86 ev->generic.type = type;
87 ev->generic.time = time;
88 ev->generic.event_id = n_song_ev;
90 /* store */
91 memcpy(&song[n_song_ev], ev, sizeof(union song_ev));
93 n_song_ev++;
97 static int song_ev_cmp(const void * v1, const void * v2)
99 struct song_ev_generic * e1;
100 struct song_ev_generic * e2;
101 int ret;
103 e1 = (struct song_ev_generic *)v1; e2 = (struct song_ev_generic *)v2;
105 ret = (int) ((e1->time * 10000.0) - (e2->time * 10000.0));
107 /* same time? order by type of event */
108 if(ret == 0)
109 ret = e1->type - e2->type;
111 /* same time and same event? order by event id */
112 if(ret == 0)
113 ret = e1->event_id - e2->event_id;
115 return(ret);
119 static void song_trace_events(void)
121 union song_ev * e;
122 int n;
124 printf("** GENERIC SONG EVENT DUMP **\n\n");
125 printf("%9s %5s %5s Event and information\n",
126 "Time", "Track", "Ev.ID");
127 printf("---------------------------------------------------------------\n");
129 for(n = 0, e = song;n < n_song_ev;n++, e++)
131 printf("%9.4lf %5d %5d ",
132 e->generic.time, e->generic.trk_id,
133 e->generic.event_id);
135 switch(e->generic.type)
137 case SONG_EV_TEMPO:
139 printf("SONG_EV_TEMPO ");
140 printf("TEMPO:%lf", e->tempo.tempo);
141 break;
143 case SONG_EV_METER:
145 printf("SONG_EV_METER ");
146 printf("METER:%d/%d", e->meter.num, e->meter.den);
147 break;
149 case SONG_EV_MEASURE:
151 printf("SONG_EV_MEASURE ");
152 printf("LINE:%d", e->measure.line);
153 break;
155 case SONG_EV_SS_SUSTAIN:
157 printf("SONG_EV_SS_SUSTAIN ");
158 printf("SUSTAIN:%lf", e->ss_sustain.sustain);
159 break;
161 case SONG_EV_SS_VIBRATO:
163 printf("SONG_EV_SS_VIBRATO ");
164 printf("DEPTH:%lf FREQ:%lf",
165 e->ss_vibrato.vib_depth,
166 e->ss_vibrato.vib_freq);
167 break;
169 case SONG_EV_SS_PORTAMENTO:
171 printf("SONG_EV_SS_PORTAMENTO ");
172 printf("VALUE: %lf", e->ss_portamento.portamento);
173 break;
175 case SONG_EV_SS_CHANNEL:
177 printf("SONG_EV_SS_CHANNEL ");
178 printf("CHANNEL:%d VOL:%lf",
179 e->ss_channel.channel,
180 e->ss_channel.vol);
181 break;
183 case SONG_EV_SS_WAV:
185 printf("SONG_EV_SS_WAV ");
186 printf("FILE:'%s' BASE:%d MIN:%d MAX:%d START:%lf END:%lf",
187 e->ss_wav.file, e->ss_wav.base,
188 e->ss_wav.min, e->ss_wav.max,
189 e->ss_wav.loop_start, e->ss_wav.loop_end);
190 break;
192 case SONG_EV_SS_PAT:
194 printf("SONG_EV_SS_PAT ");
195 printf("FILE:'%s'", e->ss_pat.file);
196 break;
198 case SONG_EV_SS_EFF_DELAY:
200 printf("SONG_EV_SS_EFF_DELAY ");
201 printf("CHANNEL:%d ", e->ss_eff.channel);
202 printf("SIZE:%lf ", e->ss_eff.size);
203 break;
205 case SONG_EV_SS_EFF_ECHO:
207 printf("SONG_EV_SS_EFF_ECHO ");
208 printf("CHANNEL:%d ", e->ss_eff.channel);
209 printf("SIZE:%lf ", e->ss_eff.size);
210 printf("GAIN:%f ", e->ss_eff.gain);
211 break;
213 case SONG_EV_SS_EFF_COMB:
215 printf("SONG_EV_SS_EFF_COMB ");
216 printf("CHANNEL:%d ", e->ss_eff.channel);
217 printf("SIZE:%lf ", e->ss_eff.size);
218 printf("GAIN:%f ", e->ss_eff.gain);
219 break;
221 case SONG_EV_SS_EFF_ALLPASS:
223 printf("SONG_EV_SS_EFF_ALLPASS ");
224 printf("CHANNEL:%d ", e->ss_eff.channel);
225 printf("SIZE:%lf ", e->ss_eff.size);
226 printf("GAIN:%f ", e->ss_eff.gain);
227 break;
229 case SONG_EV_SS_EFF_FLANGER:
231 printf("SONG_EV_SS_EFF_FLANGER ");
232 printf("CHANNEL:%d ", e->ss_eff.channel);
233 printf("SIZE:%lf ", e->ss_eff.size);
234 printf("GAIN:%f ", e->ss_eff.gain);
235 printf("DEPTH:%lf ", e->ss_eff.depth);
236 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq,
237 e->ss_eff.phase);
238 break;
240 case SONG_EV_SS_EFF_WOBBLE:
242 printf("SONG_EV_SS_EFF_WOBBLE ");
243 printf("CHANNEL:%d ", e->ss_eff.channel);
244 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq,
245 e->ss_eff.phase);
246 break;
248 case SONG_EV_SS_EFF_SQWOBBLE:
250 printf("SONG_EV_SS_EFF_SQWOBBLE ");
251 printf("CHANNEL:%d ", e->ss_eff.channel);
252 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq,
253 e->ss_eff.phase);
254 break;
256 case SONG_EV_SS_EFF_HFWOBBLE:
258 printf("SONG_EV_SS_EFF_HFWOBBLE ");
259 printf("CHANNEL:%d ", e->ss_eff.channel);
260 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq,
261 e->ss_eff.phase);
262 break;
264 case SONG_EV_SS_EFF_FADER:
266 printf("SONG_EV_SS_EFF_FADER ");
267 printf("CHANNEL:%d ", e->ss_eff.channel);
268 printf("SIZE:%lf ", e->ss_eff.size);
269 printf("INITIAL:%f FINAL:%f", e->ss_eff.initial,
270 e->ss_eff.final);
271 break;
273 case SONG_EV_SS_EFF_REVERB:
275 printf("SONG_EV_SS_EFF_REVERB ");
276 printf("CHANNEL:%d ", e->ss_eff.channel);
277 break;
279 case SONG_EV_SS_EFF_OFF:
281 printf("SONG_EV_SS_EFF_OFF ");
282 printf("CHANNEL:%d ", e->ss_eff.channel);
283 break;
285 case SONG_EV_MIDI_CHANNEL:
287 printf("SONG_EV_MIDI_CHANNEL ");
288 printf("CHANNEL:%d ", e->midi_channel.channel);
289 break;
291 case SONG_EV_MIDI_PROGRAM:
293 printf("SONG_EV_MIDI_PROGRAM ");
294 printf("PROGRAM:%d ", e->midi_program.program);
295 break;
297 case SONG_EV_BACK:
299 printf("SONG_EV_BACK ");
300 printf("LEN:%lf", e->back.len);
301 break;
303 case SONG_EV_NOTE:
305 printf("SONG_EV_NOTE ");
306 printf("MIDI:%d LEN:%lf VOL:%f",
307 e->note.note, e->note.len, e->note.vol);
308 break;
310 case SONG_EV_SS_PITCH_STRETCH:
312 printf("SONG_EV_SS_PITCH_STRETCH ");
313 printf("MIDI:%d LEN:%lf VOL:%f",
314 e->ss_pitch_stretch.note,
315 e->ss_pitch_stretch.len,
316 e->ss_pitch_stretch.vol);
317 break;
319 case SONG_EV_SS_PRINT_WAVE_TEMPO:
321 printf("SONG_EV_SS_PRINT_WAVE_TEMPO ");
322 printf("MIDI:%d LEN:%lf",
323 e->ss_print_wave_tempo.note,
324 e->ss_print_wave_tempo.len);
325 break;
327 case SONG_EV_SONG_INFO:
329 printf("SONG_EV_SONG_INFO ");
330 printf("AUTHOR:'%s' NAME:'%s'",
331 e->song_info.author,
332 e->song_info.name);
333 break;
335 default:
336 printf("** Unexpected event type: %d",
337 e->generic.type);
340 printf("\n");
343 printf("\n");
348 * song_sort - Sorts the song stream
350 * Sorts the song stream.
352 void song_sort(void)
354 qsort(song, n_song_ev, sizeof(union song_ev), song_ev_cmp);
356 if(trace) song_trace_events();
361 * song_test_measure_boundary - Does a measure boundary check
362 * @ev_time: event time
363 * @num: meter numerator
364 * @den: meter denominator
366 * Does a measure boundary check. Returns 0 if the event time falls
367 * exactly between two measures, or nonzero otherwise.
369 int song_test_measure_boundary(double ev_time, int num, int den, int line)
371 int ret;
373 if((ret = ((int)(ev_time * (double) den)) % num))
374 printf("Measure boundary check failed in line %d\n", line);
376 return(ret);