Fixed a bug when processing loop boundaries in SONG_EV_SS_WAV events.
[ahxm.git] / ss_song.c
blobbc90e9e48647762481099aae0b298f88d8317d02
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2005 Angel Ortega <angel@triptico.com>
6 ss_song.c - Software synth 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 "ss_core.h"
34 #include "song.h"
35 #include "ss_gen.h"
36 #include "ss_eff.h"
37 #include "ss_ins.h"
38 #include "ss_input.h"
39 #include "ss_output.h"
41 /*******************
42 Data
43 ********************/
45 struct ss_ev_generic
47 song_ev_type type; /* event type */
48 int frame; /* frame number (time) */
49 int trk_id; /* track id */
52 struct ss_ev_note_off
54 song_ev_type type; /* SONG_EV_NOTE_OFF */
55 int frame;
56 int trk_id;
57 int note_id; /* note id */
60 struct ss_ev_note_on
62 song_ev_type type; /* SONG_EV_NOTE_ON */
63 int frame;
64 int trk_id;
65 int note_id; /* note id */
66 int note; /* MIDI-like note number */
67 float vol; /* volume */
70 struct ss_ev_ss_note_on_by_time
72 song_ev_type type; /* SONG_EV_SS_NOTE_ON_BY_TIME */
73 int frame;
74 int trk_id;
75 int note_id; /* note id */
76 int note; /* MIDI-like note (to find the wave) */
77 double len; /* note length (1: whole) */
78 float vol; /* volume */
81 struct ss_ev_ss_sustain
83 song_ev_type type; /* SONG_EV_SS_SUSTAIN */
84 int frame;
85 int trk_id;
86 double sustain; /* sustain time (in frames) */
89 struct ss_ev_ss_channel_map
91 song_ev_type type; /* SONG_EV_SS_CHANNEL_MAP */
92 int frame;
93 int trk_id;
94 float vol[CHANNELS]; /* volumes for each channel */
97 struct ss_ev_ss_wav
99 song_ev_type type; /* SONG_EV_SS_WAV */
100 int frame;
101 int trk_id;
102 char * file; /* path to .wav file */
103 int base; /* MIDI-like base note */
104 int min; /* MIDI-like minimum note */
105 int max; /* MIDI-like maximum note */
106 double loop_start; /* loop start */
107 double loop_end; /* loop end */
110 struct ss_ev_ss_pat
112 song_ev_type type; /* SONG_EV_SS_PAT */
113 int frame;
114 int trk_id;
115 char * file; /* path to .pat file */
118 struct ss_ev_ss_eff
120 song_ev_type type; /* effect type */
121 int frame;
122 int trk_id;
123 int channel; /* channel */
124 double size; /* size of effect */
125 float gain; /* gain */
126 double depth; /* depth */
127 double freq; /* freq */
128 double phase; /* phase */
129 float initial; /* initial vol */
130 float final; /* final vol */
133 union ss_ev
135 struct ss_ev_generic generic;
136 struct ss_ev_note_on note_on;
137 struct ss_ev_note_off note_off;
138 struct ss_ev_ss_note_on_by_time ss_note_on_by_time;
139 struct ss_ev_ss_sustain ss_sustain;
140 struct ss_ev_ss_channel_map ss_channel_map;
141 struct ss_ev_ss_wav ss_wav;
142 struct ss_ev_ss_pat ss_pat;
143 struct ss_ev_ss_eff ss_eff;
146 /* the softsynth song stream */
148 static union ss_ev * ss_song=NULL;
149 static int n_ss_ev=0;
152 /* the instruments */
154 #define SONG_INS_NUM 256
155 struct ss_ins song_ins[SONG_INS_NUM];
158 /*******************
159 Code
160 ********************/
162 static void add_ss_ev(union ss_ev * e)
163 /* adds a softsynth song event */
165 n_ss_ev++;
167 /* reallocs */
168 ss_song=(union ss_ev *)realloc(ss_song,
169 n_ss_ev * sizeof(union ss_ev));
171 /* store */
172 memcpy(&ss_song[n_ss_ev - 1], e, sizeof(union ss_ev));
176 static int ss_ev_cmp(const void * v1, const void * v2)
177 /* softsynth song event compare function for qsort() */
179 struct ss_ev_generic * e1;
180 struct ss_ev_generic * e2;
182 e1=(struct ss_ev_generic *)v1; e2=(struct ss_ev_generic *)v2;
184 if(e1->frame == e2->frame)
185 return(e1->type - e2->type);
187 return(e1->frame - e2->frame);
191 static int ss_song_convert_events(void)
192 /* converts generic song_ev events to softsynth events */
194 int note_id=1;
195 union song_ev * e;
196 union ss_ev sse;
197 int frame, frame_ac;
198 double fpw, time_ac;
199 int num, den;
200 int n;
201 int b_track=-1;
203 /* resets the ss stream */
204 if(ss_song != NULL)
206 free(ss_song);
207 ss_song=NULL;
210 n_ss_ev=0;
212 /* sorts the song */
213 song_sort();
215 fpw=0;
216 frame_ac=0;
217 time_ac=0;
218 num=den=4;
220 /* travels the song events generating softsynth song events */
221 for(n=0;n < _n_song_ev;n++)
223 /* gets the song event */
224 e=&_song[n];
226 /* calculates the frame */
227 frame=((e->generic.time - time_ac) * fpw) + frame_ac;
229 /* generic event data */
230 sse.generic.type=e->generic.type;
231 sse.generic.frame=frame;
232 sse.generic.trk_id=e->generic.trk_id;
234 /* account the biggest track seen */
235 if(b_track < e->generic.trk_id) b_track=e->generic.trk_id;
237 switch(e->generic.type)
239 case SONG_EV_TEMPO:
241 /* updates accumulations */
242 frame_ac += frame;
243 time_ac += e->generic.time;
245 /* calculates frames-per-whole based on new tempo */
246 fpw=(double) ss_frequency * 60.0;
247 fpw /= e->tempo.tempo / 4.0;
249 break;
251 case SONG_EV_METER:
253 /* just store the values */
254 num=e->meter.num;
255 den=e->meter.den;
257 break;
259 case SONG_EV_MEASURE:
261 printf("measure boundary check (must be 0): %d\n",
262 ((int) e->generic.time * num) % den);
264 break;
266 case SONG_EV_NOTE:
268 /* convert to note on / off pairs */
270 sse.note_on.type=SONG_EV_NOTE_ON;
271 sse.note_on.note_id=note_id++;
272 sse.note_on.note=e->note.note;
273 sse.note_on.vol=e->note.vol;
275 add_ss_ev(&sse);
277 frame += (int)(e->note.len * fpw);
279 sse.note_off.type=SONG_EV_NOTE_OFF;
280 sse.note_off.frame=frame;
282 add_ss_ev(&sse);
283 break;
285 case SONG_EV_SS_NOTE_ON_BY_TIME:
287 sse.ss_note_on_by_time.note_id=note_id++;
288 sse.ss_note_on_by_time.note=e->ss_note_by_time.note;
289 sse.ss_note_on_by_time.len=e->ss_note_by_time.len;
290 sse.ss_note_on_by_time.vol=e->ss_note_by_time.vol;
292 add_ss_ev(&sse);
294 frame += (int)(e->ss_note_by_time.len * fpw);
296 sse.note_off.type=SONG_EV_NOTE_OFF;
297 sse.note_off.frame=frame;
299 add_ss_ev(&sse);
300 break;
302 case SONG_EV_SS_WAV:
304 sse.ss_wav.file=e->ss_wav.file;
305 sse.ss_wav.base=e->ss_wav.base;
306 sse.ss_wav.min=e->ss_wav.min;
307 sse.ss_wav.max=e->ss_wav.max;
308 sse.ss_wav.loop_start=e->ss_wav.loop_start;
309 sse.ss_wav.loop_end=e->ss_wav.loop_end;
311 add_ss_ev(&sse);
312 break;
314 case SONG_EV_SS_PAT:
316 sse.ss_pat.file=e->ss_pat.file;
318 add_ss_ev(&sse);
319 break;
321 case SONG_EV_SS_SUSTAIN:
323 sse.ss_sustain.sustain=e->ss_sustain.sustain;
325 add_ss_ev(&sse);
326 break;
328 case SONG_EV_SS_CHANNEL_MAP:
330 break;
332 case SONG_EV_SS_EFF_DELAY:
333 case SONG_EV_SS_EFF_ECHO:
334 case SONG_EV_SS_EFF_COMB:
335 case SONG_EV_SS_EFF_ALLPASS:
336 case SONG_EV_SS_EFF_FLANGER:
337 case SONG_EV_SS_EFF_WOBBLE:
338 case SONG_EV_SS_EFF_SQWOBBLE:
339 case SONG_EV_SS_EFF_FADER:
340 case SONG_EV_SS_EFF_REVERB:
342 sse.ss_eff.channel=e->ss_eff.channel;
343 sse.ss_eff.size=e->ss_eff.size;
344 sse.ss_eff.gain=e->ss_eff.gain;
345 sse.ss_eff.depth=e->ss_eff.depth;
346 sse.ss_eff.freq=e->ss_eff.freq;
347 sse.ss_eff.phase=e->ss_eff.phase;
348 sse.ss_eff.initial=e->ss_eff.initial;
349 sse.ss_eff.final=e->ss_eff.final;
351 add_ss_ev(&sse);
352 break;
354 case SONG_EV_MIDI_CHANNEL:
355 case SONG_EV_MIDI_PROGRAM:
357 /* ignored */
358 break;
360 case SONG_EV_NOTE_ON:
361 case SONG_EV_NOTE_OFF:
362 case SONG_EV_END:
364 /* never found in generic song streams */
365 break;
369 /* generates an end of event mark, a time after the last one */
370 sse.generic.type=SONG_EV_END;
371 sse.generic.frame=frame + ss_frequency;
372 add_ss_ev(&sse);
374 /* finally sort */
375 qsort(ss_song, n_ss_ev, sizeof(union ss_ev), ss_ev_cmp);
377 /* return the number of tracks */
378 return(b_track + 1);
382 int ss_song_render(void)
384 union ss_ev * e;
385 int frame;
386 int go;
387 int n;
388 float output[CHANNELS];
389 int n_tracks;
390 struct ss_ins * i;
392 /* convert the song to ss events */
393 n_tracks=ss_song_convert_events();
395 frame=0;
396 go=1;
397 e=ss_song;
399 /* init the instruments */
400 for(n=0;n < n_tracks;n++)
401 ss_ins_init(&song_ins[n]);
403 /* loop the events */
404 while(go)
406 /* process all events for this exact frame */
407 while(e->generic.frame == frame)
409 /* take the instrument */
410 if(e->generic.trk_id == -1)
411 i=NULL;
412 else
413 i=&song_ins[e->generic.trk_id];
415 switch(e->generic.type)
417 case SONG_EV_NOTE_ON:
419 ss_ins_note_on(i, e->note_on.note,
420 e->note_on.vol, e->note_on.note_id);
422 break;
424 case SONG_EV_SS_NOTE_ON_BY_TIME:
426 break;
428 case SONG_EV_NOTE_OFF:
430 ss_ins_note_off(i, e->note_off.note_id);
432 break;
434 case SONG_EV_SS_SUSTAIN:
436 ss_ins_set_sustain(i, e->ss_sustain.sustain);
438 break;
440 case SONG_EV_SS_CHANNEL_MAP:
442 break;
444 case SONG_EV_SS_WAV:
447 struct ss_wave w;
449 ss_load_wav_file(&w, e->ss_wav.file,
450 ss_note_frequency(e->ss_wav.base),
451 ss_note_frequency(e->ss_wav.min),
452 ss_note_frequency(e->ss_wav.max));
454 /* set loop boundaries */
455 if(e->ss_wav.loop_start >= 0)
457 w.loop_start=e->ss_wav.loop_start;
458 w.loop_end=e->ss_wav.loop_end;
461 ss_ins_add_layer(i, &w);
464 break;
466 case SONG_EV_SS_PAT:
468 ss_load_pat_file(i, e->ss_pat.file);
469 break;
471 case SONG_EV_SS_EFF_DELAY:
473 ss_eff_delay(&i->effs[e->ss_eff.channel],
474 e->ss_eff.size);
475 break;
477 case SONG_EV_SS_EFF_ECHO:
479 ss_eff_echo(&i->effs[e->ss_eff.channel],
480 e->ss_eff.size, e->ss_eff.gain);
481 break;
483 case SONG_EV_SS_EFF_COMB:
485 ss_eff_comb(&i->effs[e->ss_eff.channel],
486 e->ss_eff.size, e->ss_eff.gain);
487 break;
489 case SONG_EV_SS_EFF_ALLPASS:
491 ss_eff_allpass(&i->effs[e->ss_eff.channel],
492 e->ss_eff.size, e->ss_eff.gain);
493 break;
495 case SONG_EV_SS_EFF_FLANGER:
497 ss_eff_flanger(&i->effs[e->ss_eff.channel],
498 e->ss_eff.size, e->ss_eff.gain,
499 e->ss_eff.depth, e->ss_eff.freq,
500 e->ss_eff.phase);
501 break;
503 case SONG_EV_SS_EFF_WOBBLE:
505 ss_eff_wobble(&i->effs[e->ss_eff.channel],
506 e->ss_eff.freq, e->ss_eff.phase);
508 break;
510 case SONG_EV_SS_EFF_SQWOBBLE:
512 ss_eff_square_wobble(&i->effs[e->ss_eff.channel],
513 e->ss_eff.freq, e->ss_eff.phase);
515 break;
517 case SONG_EV_SS_EFF_FADER:
519 ss_eff_fader(&i->effs[e->ss_eff.channel],
520 e->ss_eff.size, e->ss_eff.initial,
521 e->ss_eff.final);
522 break;
524 case SONG_EV_SS_EFF_REVERB:
526 ss_eff_reverb(&i->effs[e->ss_eff.channel]);
527 break;
529 case SONG_EV_END:
531 go=0;
532 break;
534 case SONG_EV_MIDI_CHANNEL:
535 case SONG_EV_MIDI_PROGRAM:
536 case SONG_EV_NOTE:
537 case SONG_EV_TEMPO:
538 case SONG_EV_METER:
539 case SONG_EV_MEASURE:
541 /* never found in ss song streams */
542 break;
545 /* next event */
546 e++;
549 /* reset frame samples */
550 ss_output_init_frame(output);
552 /* generate output from all instruments */
553 for(n=0;n < n_tracks;n++)
554 ss_ins_frame(&song_ins[n], output);
556 /* dump to sampling driver */
557 ss_output_write(output);
559 /* next frame */
560 frame++;
563 return(0);