More coding style changes.
[ahxm.git] / ss_song.c
blobfd018c4b8b9bc7ae6fa542d8e624b1dec20db0de
1 /*
3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2007 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 "ahxm.h"
35 /*******************
36 Data
37 ********************/
39 struct ss_ev_generic {
40 song_ev_type type; /* event type */
41 int frame; /* frame number (time) */
42 int trk_id; /* track id */
43 int event_id; /* event id */
46 struct ss_ev_note_off {
47 song_ev_type type; /* SONG_EV_NOTE_OFF */
48 int frame;
49 int trk_id;
50 int event_id;
51 int note_id; /* note id */
54 struct ss_ev_note_on {
55 song_ev_type type; /* SONG_EV_NOTE_ON */
56 int frame;
57 int trk_id;
58 int event_id;
59 int note_id; /* note id */
60 int note; /* MIDI-like note */
61 sample_t vol; /* volume */
64 struct ss_ev_ss_sustain {
65 song_ev_type type; /* SONG_EV_SS_SUSTAIN */
66 int frame;
67 int trk_id;
68 int event_id;
69 double sustain; /* sustain time (in frames) */
72 struct ss_ev_ss_attack {
73 song_ev_type type; /* SONG_EV_SS_ATTACK */
74 int frame;
75 int trk_id;
76 int event_id;
77 double attack; /* attack time (in frames) */
80 struct ss_ev_ss_vibrato {
81 song_ev_type type; /* SONG_EV_SS_VIBRATO */
82 int frame;
83 int trk_id;
84 int event_id;
85 double vib_depth; /* vibrato depth (in msecs) */
86 double vib_freq; /* vibrato frequency (in Hzs) */
89 struct ss_ev_ss_portamento {
90 song_ev_type type; /* SONG_EV_SS_PORTAMENTO */
91 int frame;
92 int trk_id;
93 int event_id;
94 double portamento; /* portamento */
97 struct ss_ev_ss_channel {
98 song_ev_type type; /* SONG_EV_SS_CHANNEL */
99 int frame;
100 int trk_id;
101 int event_id;
102 int channel; /* channel */
103 sample_t vol; /* volume */
106 struct ss_ev_ss_wav {
107 song_ev_type type; /* SONG_EV_SS_WAV */
108 int frame;
109 int trk_id;
110 int event_id;
111 char *file; /* path to .wav file */
112 int base; /* MIDI-like base note */
113 int min; /* MIDI-like minimum note */
114 int max; /* MIDI-like maximum note */
115 double loop_start; /* loop start */
116 double loop_end; /* loop end */
117 int first_channel; /* first channel to start spreading */
118 int skip_channels; /* channels to skip when spreading */
121 struct ss_ev_ss_pat {
122 song_ev_type type; /* SONG_EV_SS_PAT */
123 int frame;
124 int trk_id;
125 int event_id;
126 char *file; /* path to .pat file */
129 struct ss_ev_tempo {
130 song_ev_type type; /* SONG_EV_TEMPO */
131 int frame;
132 int trk_id;
133 int event_id;
134 double tempo; /* tempo in bmp */
137 struct ss_ev_pitch_stretch {
138 song_ev_type type; /* SONG_EV_SS_PITCH_STRETCH */
139 int frame;
140 int trk_id;
141 int event_id;
142 int note_id; /* note id */
143 int note; /* MIDI-like note (to find the wave) */
144 double len; /* note length (1: whole note) */
145 sample_t vol; /* note volume (1: full volume) */
148 struct ss_ev_print_wave_tempo {
149 song_ev_type type; /* SONG_EV_SS_PRINT_WAVE_TEMPO */
150 int frame;
151 int trk_id;
152 int event_id;
153 int note_id; /* note id */
154 int note; /* MIDI-like note (to find the wave) */
155 double len; /* note length (1: whole note) */
158 struct ss_ev_ss_eff {
159 song_ev_type type; /* effect type */
160 int frame;
161 int trk_id;
162 int event_id;
163 int channel; /* channel */
164 double size; /* size of effect */
165 sample_t gain; /* gain */
166 double depth; /* depth */
167 double freq; /* freq */
168 double phase; /* phase */
169 sample_t initial; /* initial vol */
170 sample_t final; /* final vol */
173 struct ss_ev_song_info {
174 song_ev_type type; /* SONG_EV_SONG_INFO */
175 int frame;
176 int trk_id;
177 int event_id;
178 char *author; /* track author */
179 char *name; /* track name */
182 union ss_ev {
183 struct ss_ev_generic generic;
184 struct ss_ev_note_on note_on;
185 struct ss_ev_note_off note_off;
186 struct ss_ev_ss_sustain ss_sustain;
187 struct ss_ev_ss_attack ss_attack;
188 struct ss_ev_ss_vibrato ss_vibrato;
189 struct ss_ev_ss_portamento ss_portamento;
190 struct ss_ev_ss_channel ss_channel;
191 struct ss_ev_ss_wav ss_wav;
192 struct ss_ev_ss_pat ss_pat;
193 struct ss_ev_ss_eff ss_eff;
194 struct ss_ev_tempo tempo;
195 struct ss_ev_pitch_stretch ss_pitch_stretch;
196 struct ss_ev_print_wave_tempo ss_print_wave_tempo;
197 struct ss_ev_song_info song_info;
200 /* the softsynth song stream */
202 static union ss_ev *ss_song = NULL;
203 static int n_ss_ev = 0;
206 /* the instruments */
208 struct ss_ins ss_song_ins[SS_MAX_INSTRUMENTS];
210 /*******************
211 Code
212 ********************/
214 static void add_ss_ev(union ss_ev *e)
215 /* adds a softsynth song event */
217 GROW(ss_song, n_ss_ev, union ss_ev);
219 /* store */
220 memcpy(&ss_song[n_ss_ev], e, sizeof(union ss_ev));
222 n_ss_ev++;
226 static int ss_ev_cmp(const void *v1, const void *v2)
227 /* softsynth song event compare function for qsort() */
229 struct ss_ev_generic *e1;
230 struct ss_ev_generic *e2;
231 int ret;
233 e1 = (struct ss_ev_generic *) v1;
234 e2 = (struct ss_ev_generic *) v2;
236 ret = e1->frame - e2->frame;
238 if (ret == 0)
239 ret = e1->type - e2->type;
241 if (ret == 0)
242 ret = e1->event_id - e2->event_id;
244 return ret;
248 static void ss_song_convert_events(int *n_channels)
249 /* converts generic song_ev events to softsynth events */
251 int note_id = 1;
252 union song_ev *e;
253 union ss_ev sse;
254 int frame, frame_ac, f_frame;
255 double fpw, time_ac, time_ac_m;
256 int num, den;
257 int n;
259 *n_channels = -1;
261 /* resets the ss stream */
262 if (ss_song != NULL) {
263 free(ss_song);
264 ss_song = NULL;
267 n_ss_ev = 0;
269 /* sorts the song */
270 song_sort();
272 fpw = 0;
273 frame = frame_ac = f_frame = 0;
274 time_ac = time_ac_m = 0;
275 num = den = 4;
277 /* travels the song events generating softsynth song events */
278 for (n = 0; n < n_song_ev; n++) {
279 /* gets the song event */
280 e = &song[n];
282 /* calculates the frame */
283 frame = ((e->generic.time - time_ac) * fpw) + frame_ac;
285 /* generic event data */
286 sse.generic.type = e->generic.type;
287 sse.generic.frame = frame;
288 sse.generic.trk_id = e->generic.trk_id;
289 sse.generic.event_id = e->generic.event_id;
291 switch (e->generic.type) {
292 case SONG_EV_TEMPO:
294 /* updates accumulations */
295 frame_ac = frame;
296 time_ac = e->generic.time;
298 /* calculates frames-per-whole based on new tempo */
299 fpw = (double) ss_frequency *60.0;
300 fpw /= e->tempo.tempo / 4.0;
302 /* adds an event */
303 sse.tempo.tempo = e->tempo.tempo;
304 add_ss_ev(&sse);
306 break;
308 case SONG_EV_METER:
310 /* just store the values */
311 num = e->meter.num;
312 den = e->meter.den;
313 time_ac_m = e->meter.time;
315 break;
317 case SONG_EV_MEASURE:
319 song_test_measure_boundary(e->measure.time - time_ac_m,
320 num, den, e->measure.line);
321 break;
323 case SONG_EV_NOTE:
325 /* convert to note on / off pairs */
327 sse.note_on.type = SONG_EV_NOTE_ON;
328 sse.note_on.note_id = note_id++;
329 sse.note_on.note = e->note.note;
330 sse.note_on.vol = e->note.vol;
332 add_ss_ev(&sse);
334 frame += (int) (e->note.len * fpw);
336 sse.note_off.type = SONG_EV_NOTE_OFF;
337 sse.note_off.frame = frame;
339 add_ss_ev(&sse);
340 break;
342 case SONG_EV_BACK:
344 /* move the cursor back */
346 frame_ac -= (int) (e->back.len * fpw);
348 break;
350 case SONG_EV_SS_PITCH_STRETCH:
352 sse.ss_pitch_stretch.note_id = note_id++;
353 sse.ss_pitch_stretch.note = e->ss_pitch_stretch.note;
354 sse.ss_pitch_stretch.len = e->ss_pitch_stretch.len;
355 sse.ss_pitch_stretch.vol = e->ss_pitch_stretch.vol;
357 add_ss_ev(&sse);
359 frame += (int) (e->ss_pitch_stretch.len * fpw);
361 sse.note_off.type = SONG_EV_NOTE_OFF;
362 sse.note_off.frame = frame;
364 add_ss_ev(&sse);
365 break;
367 case SONG_EV_SS_PRINT_WAVE_TEMPO:
369 sse.ss_print_wave_tempo.note = e->ss_print_wave_tempo.note;
370 sse.ss_print_wave_tempo.len = e->ss_print_wave_tempo.len;
372 add_ss_ev(&sse);
373 break;
375 case SONG_EV_SS_WAV:
377 sse.ss_wav.file = e->ss_wav.file;
378 sse.ss_wav.base = e->ss_wav.base;
379 sse.ss_wav.min = e->ss_wav.min;
380 sse.ss_wav.max = e->ss_wav.max;
381 sse.ss_wav.loop_start = e->ss_wav.loop_start;
382 sse.ss_wav.loop_end = e->ss_wav.loop_end;
383 sse.ss_wav.first_channel = e->ss_wav.first_channel;
384 sse.ss_wav.skip_channels = e->ss_wav.skip_channels;
386 add_ss_ev(&sse);
387 break;
389 case SONG_EV_SS_PAT:
391 sse.ss_pat.file = e->ss_pat.file;
393 add_ss_ev(&sse);
394 break;
396 case SONG_EV_SS_SUSTAIN:
398 sse.ss_sustain.sustain = e->ss_sustain.sustain;
400 add_ss_ev(&sse);
401 break;
403 case SONG_EV_SS_ATTACK:
405 sse.ss_attack.attack = e->ss_attack.attack;
407 add_ss_ev(&sse);
408 break;
410 case SONG_EV_SS_VIBRATO:
412 sse.ss_vibrato.vib_depth = e->ss_vibrato.vib_depth;
413 sse.ss_vibrato.vib_freq = e->ss_vibrato.vib_freq;
415 add_ss_ev(&sse);
416 break;
418 case SONG_EV_SS_PORTAMENTO:
420 sse.ss_portamento.portamento = e->ss_portamento.portamento;
422 add_ss_ev(&sse);
423 break;
425 case SONG_EV_SS_CHANNEL:
427 sse.ss_channel.channel = e->ss_channel.channel;
428 sse.ss_channel.vol = e->ss_channel.vol;
430 /* count channels */
431 if (*n_channels < e->ss_channel.channel)
432 *n_channels = e->ss_channel.channel;
434 add_ss_ev(&sse);
435 break;
437 case SONG_EV_SS_EFF_DELAY:
438 case SONG_EV_SS_EFF_ECHO:
439 case SONG_EV_SS_EFF_COMB:
440 case SONG_EV_SS_EFF_ALLPASS:
441 case SONG_EV_SS_EFF_FLANGER:
442 case SONG_EV_SS_EFF_WOBBLE:
443 case SONG_EV_SS_EFF_SQWOBBLE:
444 case SONG_EV_SS_EFF_HFWOBBLE:
445 case SONG_EV_SS_EFF_FADER:
446 case SONG_EV_SS_EFF_REVERB:
447 case SONG_EV_SS_EFF_FOLDBACK:
448 case SONG_EV_SS_EFF_ATAN:
449 case SONG_EV_SS_EFF_DISTORT:
450 case SONG_EV_SS_EFF_OVERDRIVE:
451 case SONG_EV_SS_EFF_OFF:
453 sse.ss_eff.channel = e->ss_eff.channel;
454 sse.ss_eff.size = e->ss_eff.size;
455 sse.ss_eff.gain = e->ss_eff.gain;
456 sse.ss_eff.depth = e->ss_eff.depth;
457 sse.ss_eff.freq = e->ss_eff.freq;
458 sse.ss_eff.phase = e->ss_eff.phase;
459 sse.ss_eff.initial = e->ss_eff.initial;
460 sse.ss_eff.final = e->ss_eff.final;
462 add_ss_ev(&sse);
463 break;
465 case SONG_EV_SONG_INFO:
467 sse.song_info.author = e->song_info.author;
468 sse.song_info.name = e->song_info.name;
470 add_ss_ev(&sse);
471 break;
473 case SONG_EV_EOT:
475 add_ss_ev(&sse);
476 break;
478 case SONG_EV_MIDI_CHANNEL:
479 case SONG_EV_MIDI_PROGRAM:
481 /* ignored */
482 break;
484 case SONG_EV_NOTE_ON:
485 case SONG_EV_NOTE_OFF:
486 case SONG_EV_END:
488 /* never found in generic song streams */
489 break;
492 /* store the further frame seen */
493 if (f_frame < frame)
494 f_frame = frame;
497 /* generates an end of event mark, a time after the last one */
498 sse.generic.type = SONG_EV_END;
499 sse.generic.frame = f_frame + ss_frequency;
500 sse.generic.event_id = -1;
501 add_ss_ev(&sse);
503 /* finally sort */
504 qsort(ss_song, n_ss_ev, sizeof(union ss_ev), ss_ev_cmp);
506 /* count one more */
507 (*n_channels)++;
511 static void ss_song_trace_events(void)
513 union ss_ev *e;
514 int n;
516 printf("** SOFTWARE SYNTHESIZER EVENT DUMP **\n\n");
517 printf("%10s %5s %5s Event and information\n", "Frame", "Track", "Ev.ID");
518 printf("------------------------------------------------------------\n");
520 for (n = 0, e = ss_song; n < n_ss_ev; n++, e++) {
521 printf("%10d %5d %5d ",
522 e->generic.frame, e->generic.trk_id, e->generic.event_id);
524 switch (e->generic.type) {
525 case SONG_EV_TEMPO:
527 printf("SONG_EV_TEMPO ");
528 printf("%lf", e->tempo.tempo);
529 break;
531 case SONG_EV_SS_SUSTAIN:
533 printf("SONG_EV_SS_SUSTAIN ");
534 printf("SUSTAIN:%lf", e->ss_sustain.sustain);
535 break;
537 case SONG_EV_SS_ATTACK:
539 printf("SONG_EV_SS_ATTACK ");
540 printf("ATTACK:%lf", e->ss_attack.attack);
541 break;
543 case SONG_EV_SS_VIBRATO:
545 printf("SONG_EV_SS_VIBRATO ");
546 printf("DEPTH:%lf FREQ:%lf",
547 e->ss_vibrato.vib_depth, e->ss_vibrato.vib_freq);
548 break;
550 case SONG_EV_SS_PORTAMENTO:
552 printf("SONG_EV_SS_PORTAMENTO ");
553 printf("VALUE:%lf", e->ss_portamento.portamento);
554 break;
556 case SONG_EV_SS_CHANNEL:
558 printf("SONG_EV_SS_CHANNEL ");
559 printf("CHANNEL:%d VOL:%lf", e->ss_channel.channel, e->ss_channel.vol);
560 break;
562 case SONG_EV_SS_WAV:
564 printf("SONG_EV_SS_WAV ");
565 printf("FILE:'%s' BASE:%d MIN:%d MAX:%d START:%lf END:%lf",
566 e->ss_wav.file, e->ss_wav.base,
567 e->ss_wav.min, e->ss_wav.max,
568 e->ss_wav.loop_start, e->ss_wav.loop_end);
569 break;
571 case SONG_EV_SS_PAT:
573 printf("SONG_EV_SS_PAT ");
574 printf("FILE:'%s'", e->ss_pat.file);
575 break;
577 case SONG_EV_SS_EFF_DELAY:
579 printf("SONG_EV_SS_EFF_DELAY ");
580 printf("CHANNEL:%d ", e->ss_eff.channel);
581 printf("SIZE:%lf ", e->ss_eff.size);
582 break;
584 case SONG_EV_SS_EFF_ECHO:
586 printf("SONG_EV_SS_EFF_ECHO ");
587 printf("CHANNEL:%d ", e->ss_eff.channel);
588 printf("SIZE:%lf ", e->ss_eff.size);
589 printf("GAIN:%f ", e->ss_eff.gain);
590 break;
592 case SONG_EV_SS_EFF_COMB:
594 printf("SONG_EV_SS_EFF_COMB ");
595 printf("CHANNEL:%d ", e->ss_eff.channel);
596 printf("SIZE:%lf ", e->ss_eff.size);
597 printf("GAIN:%f ", e->ss_eff.gain);
598 break;
600 case SONG_EV_SS_EFF_ALLPASS:
602 printf("SONG_EV_SS_EFF_ALLPASS ");
603 printf("CHANNEL:%d ", e->ss_eff.channel);
604 printf("SIZE:%lf ", e->ss_eff.size);
605 printf("GAIN:%f ", e->ss_eff.gain);
606 break;
608 case SONG_EV_SS_EFF_FLANGER:
610 printf("SONG_EV_SS_EFF_FLANGER ");
611 printf("CHANNEL:%d ", e->ss_eff.channel);
612 printf("SIZE:%lf ", e->ss_eff.size);
613 printf("GAIN:%f ", e->ss_eff.gain);
614 printf("DEPTH:%lf ", e->ss_eff.depth);
615 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq, e->ss_eff.phase);
616 break;
618 case SONG_EV_SS_EFF_WOBBLE:
620 printf("SONG_EV_SS_EFF_WOBBLE ");
621 printf("CHANNEL:%d ", e->ss_eff.channel);
622 printf("FREQ:%lf PHASE:%lf GAIN:%lf", e->ss_eff.freq,
623 e->ss_eff.phase, e->ss_eff.gain);
624 break;
626 case SONG_EV_SS_EFF_SQWOBBLE:
628 printf("SONG_EV_SS_EFF_SQWOBBLE ");
629 printf("CHANNEL:%d ", e->ss_eff.channel);
630 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq, e->ss_eff.phase);
631 break;
633 case SONG_EV_SS_EFF_HFWOBBLE:
635 printf("SONG_EV_SS_EFF_HFWOBBLE ");
636 printf("CHANNEL:%d ", e->ss_eff.channel);
637 printf("FREQ:%lf PHASE:%lf", e->ss_eff.freq, e->ss_eff.phase);
638 break;
640 case SONG_EV_SS_EFF_FADER:
642 printf("SONG_EV_SS_EFF_FADER ");
643 printf("CHANNEL:%d ", e->ss_eff.channel);
644 printf("SIZE:%lf ", e->ss_eff.size);
645 printf("INITIAL:%f FINAL:%f", e->ss_eff.initial, e->ss_eff.final);
646 break;
648 case SONG_EV_SS_EFF_REVERB:
650 printf("SONG_EV_SS_EFF_REVERB ");
651 printf("CHANNEL:%d ", e->ss_eff.channel);
652 break;
654 case SONG_EV_SS_EFF_FOLDBACK:
656 printf("SONG_EV_SS_EFF_FOLDBACK ");
657 printf("CHANNEL:%d THRESHOLD:%f", e->ss_eff.channel, e->ss_eff.gain);
658 break;
660 case SONG_EV_SS_EFF_ATAN:
662 printf("SONG_EV_SS_EFF_ATAN ");
663 printf("CHANNEL:%d GAIN:%f", e->ss_eff.channel, e->ss_eff.gain);
664 break;
666 case SONG_EV_SS_EFF_DISTORT:
668 printf("SONG_EV_SS_EFF_DISTORT ");
669 printf("CHANNEL:%d GAIN:%f", e->ss_eff.channel, e->ss_eff.gain);
670 break;
672 case SONG_EV_SS_EFF_OVERDRIVE:
674 printf("SONG_EV_SS_EFF_OVERDRIVE ");
675 printf("CHANNEL:%d GAIN:%f", e->ss_eff.channel, e->ss_eff.gain);
676 break;
678 case SONG_EV_SS_EFF_OFF:
680 printf("SONG_EV_SS_EFF_OFF ");
681 printf("CHANNEL:%d ", e->ss_eff.channel);
682 break;
684 case SONG_EV_SS_PITCH_STRETCH:
686 printf("SONG_EV_SS_PITCH_STRETCH ");
687 printf("MIDI:%d LEN:%lf VOL:%f",
688 e->ss_pitch_stretch.note,
689 e->ss_pitch_stretch.len, e->ss_pitch_stretch.vol);
691 break;
693 case SONG_EV_SS_PRINT_WAVE_TEMPO:
695 printf("SONG_EV_SS_PRINT_WAVE_TEMPO ");
696 printf("MIDI:%d LEN:%lf",
697 e->ss_print_wave_tempo.note, e->ss_print_wave_tempo.len);
698 break;
700 case SONG_EV_SONG_INFO:
702 printf("SONG_EV_SONG_INFO ");
703 printf("AUTHOR:'%s' NAME:'%s'",
704 e->song_info.author, e->song_info.name);
705 break;
707 case SONG_EV_NOTE_ON:
709 printf("SONG_EV_NOTE_ON ");
710 printf("ID:%d MIDI:%d VOL:%f",
711 e->note_on.note_id, e->note_on.note, e->note_on.vol);
712 break;
714 case SONG_EV_NOTE_OFF:
716 printf("SONG_EV_NOTE_OFF ");
717 printf("ID:%d", e->note_off.note_id);
718 break;
720 case SONG_EV_EOT:
722 printf("SONG_EV_EOT ");
723 break;
725 case SONG_EV_END:
727 printf("SONG_EV_END ");
728 break;
730 default:
731 printf("** Unexpected type: %d", e->generic.type);
734 printf("\n");
737 printf("\n");
741 static union ss_ev *process_this_frame_events(union ss_ev *e, int skip_frames)
742 /* process the events attached to this frame */
744 static double tempo = 120.0;
745 static int frame = 0;
747 /* from the beginning? */
748 if (e == NULL) {
749 e = ss_song;
750 tempo = 120.0;
751 frame = 0;
754 if (verbose >= 1) {
755 if (frame % ss_frequency == 0) {
756 int m = frame / ss_frequency;
757 printf("[%02d:%02d]\r", m / 60, m % 60);
758 fflush(stdout);
762 while (e != NULL && e->generic.frame == frame) {
763 struct ss_ins *i;
764 struct ss_wave *w;
765 double freq;
767 if (e->generic.type == SONG_EV_NOTE_ON ||
768 e->generic.type == SONG_EV_NOTE_OFF ||
769 e->generic.type == SONG_EV_SS_PITCH_STRETCH) {
770 if (frame < skip_frames) {
771 e++;
772 frame = e->generic.frame;
773 continue;
777 /* take the instrument */
778 if (e->generic.trk_id < 0)
779 i = NULL;
780 else
781 i = &ss_song_ins[e->generic.trk_id];
783 switch (e->generic.type) {
784 case SONG_EV_NOTE_ON:
786 if (ss_ins_note_on(i, e->note_on.note,
787 e->note_on.vol, e->note_on.note_id) < 0 &&
788 verbose >= 1)
789 printf("ss_ins_note_on error: track %d note %d\n",
790 e->note_on.trk_id, e->note_on.note);
792 break;
794 case SONG_EV_NOTE_OFF:
796 ss_ins_note_off(i, e->note_off.note_id);
798 break;
800 case SONG_EV_SS_SUSTAIN:
802 ss_ins_set_sustain(i, e->ss_sustain.sustain);
804 break;
806 case SONG_EV_SS_ATTACK:
808 ss_ins_set_attack(i, e->ss_attack.attack);
810 break;
812 case SONG_EV_SS_VIBRATO:
814 ss_ins_set_vibrato(i, e->ss_vibrato.vib_depth, e->ss_vibrato.vib_freq);
816 break;
818 case SONG_EV_SS_PORTAMENTO:
820 ss_ins_set_portamento(i, (e->ss_portamento.portamento * 44100.0)
821 / ((double) ss_frequency * 1000000.0));
823 break;
825 case SONG_EV_SS_CHANNEL:
827 ss_ins_set_channel(i, e->ss_channel.channel, e->ss_channel.vol);
829 break;
831 case SONG_EV_SS_WAV:
833 w = ss_load_wav_file(e->ss_wav.file,
834 ss_note_frequency(e->ss_wav.base),
835 ss_note_frequency(e->ss_wav.min),
836 ss_note_frequency(e->ss_wav.max),
837 e->ss_wav.loop_start, e->ss_wav.loop_end,
838 e->ss_wav.first_channel, e->ss_wav.skip_channels);
840 /* fail if can't open wav */
841 if (w == NULL) {
842 printf("Can't load wav '%s'\n", e->ss_wav.file);
843 e = NULL;
845 else
846 ss_ins_add_layer(i, w);
848 break;
850 case SONG_EV_SS_PAT:
852 if (ss_load_pat_file(i, e->ss_pat.file) < 0) {
853 printf("Can't load pat '%s'\n", e->ss_pat.file);
854 e = NULL;
857 break;
859 case SONG_EV_SS_EFF_DELAY:
861 ss_eff_delay(&i->effs[e->ss_eff.channel], e->ss_eff.size);
862 break;
864 case SONG_EV_SS_EFF_ECHO:
866 ss_eff_echo(&i->effs[e->ss_eff.channel],
867 e->ss_eff.size, e->ss_eff.gain);
868 break;
870 case SONG_EV_SS_EFF_COMB:
872 ss_eff_comb(&i->effs[e->ss_eff.channel],
873 e->ss_eff.size, e->ss_eff.gain);
874 break;
876 case SONG_EV_SS_EFF_ALLPASS:
878 ss_eff_allpass(&i->effs[e->ss_eff.channel],
879 e->ss_eff.size, e->ss_eff.gain);
880 break;
882 case SONG_EV_SS_EFF_FLANGER:
884 ss_eff_flanger(&i->effs[e->ss_eff.channel],
885 e->ss_eff.size, e->ss_eff.gain,
886 e->ss_eff.depth, e->ss_eff.freq, e->ss_eff.phase);
887 break;
889 case SONG_EV_SS_EFF_WOBBLE:
891 ss_eff_wobble(&i->effs[e->ss_eff.channel],
892 e->ss_eff.freq, e->ss_eff.phase, e->ss_eff.gain);
894 break;
896 case SONG_EV_SS_EFF_SQWOBBLE:
898 ss_eff_square_wobble(&i->effs[e->ss_eff.channel],
899 e->ss_eff.freq, e->ss_eff.phase);
901 break;
903 case SONG_EV_SS_EFF_HFWOBBLE:
905 ss_eff_half_wobble(&i->effs[e->ss_eff.channel],
906 e->ss_eff.freq, e->ss_eff.phase);
908 break;
910 case SONG_EV_SS_EFF_FADER:
912 ss_eff_fader(&i->effs[e->ss_eff.channel],
913 e->ss_eff.size, e->ss_eff.initial, e->ss_eff.final);
914 break;
916 case SONG_EV_SS_EFF_REVERB:
918 ss_eff_reverb(&i->effs[e->ss_eff.channel]);
919 break;
921 case SONG_EV_SS_EFF_FOLDBACK:
923 ss_eff_foldback(&i->effs[e->ss_eff.channel], e->ss_eff.gain);
924 break;
926 case SONG_EV_SS_EFF_ATAN:
928 ss_eff_atan(&i->effs[e->ss_eff.channel], e->ss_eff.gain);
929 break;
931 case SONG_EV_SS_EFF_DISTORT:
933 ss_eff_distort(&i->effs[e->ss_eff.channel], e->ss_eff.gain);
934 break;
936 case SONG_EV_SS_EFF_OVERDRIVE:
938 ss_eff_overdrive(&i->effs[e->ss_eff.channel], e->ss_eff.gain);
939 break;
941 case SONG_EV_SS_EFF_OFF:
943 ss_eff_off(&i->effs[e->ss_eff.channel]);
944 break;
946 case SONG_EV_TEMPO:
948 /* just store the last tempo */
949 tempo = e->tempo.tempo;
950 break;
952 case SONG_EV_SS_PITCH_STRETCH:
954 /* find the wave */
955 freq = ss_note_frequency(e->ss_pitch_stretch.note);
956 w = ss_ins_find_layer(i, freq, NULL);
958 /* calculate optimal frequency */
959 freq = ss_pitch_from_tempo(w, tempo, e->ss_pitch_stretch.len);
961 /* play the note */
962 if (ss_ins_play(i, freq, e->ss_pitch_stretch.vol,
963 e->ss_pitch_stretch.note_id, w) < 0 && verbose >= 1)
964 printf("ss_ins_play error: track %d freq %f\n",
965 e->ss_pitch_stretch.trk_id, freq);
967 break;
969 case SONG_EV_SS_PRINT_WAVE_TEMPO:
971 /* find the wave */
972 freq = ss_note_frequency(e->ss_print_wave_tempo.note);
973 w = ss_ins_find_layer(i, freq, NULL);
975 /* print the optimal tempo */
976 printf("Optimal tempo: %lf\n",
977 ss_tempo_from_wave(w,
978 e->ss_print_wave_tempo.note,
979 e->ss_print_wave_tempo.len));
981 break;
983 case SONG_EV_SONG_INFO:
985 /* add a new song (track) */
986 cue_file_song_info(frame, e->song_info.author, e->song_info.name);
987 break;
989 case SONG_EV_EOT:
991 /* end of track; trigger possible cleaning */
992 ss_ins_disable(i);
993 break;
995 case SONG_EV_END:
997 e = NULL;
998 break;
1000 case SONG_EV_BACK:
1001 case SONG_EV_MIDI_CHANNEL:
1002 case SONG_EV_MIDI_PROGRAM:
1003 case SONG_EV_NOTE:
1004 case SONG_EV_METER:
1005 case SONG_EV_MEASURE:
1007 /* never found in ss song streams */
1008 break;
1011 /* next event */
1012 if (e)
1013 e++;
1016 frame++;
1018 return e;
1022 int ss_song_render(int skip_secs, char *driver, char *devfile)
1024 int n, i = 0;
1025 sample_t output[SS_MAX_CHANNELS];
1026 int skip_frames;
1027 int n_channels;
1028 union ss_ev *e = NULL;
1030 /* convert the song to ss events */
1031 ss_song_convert_events(&n_channels);
1033 if (verbose >= 2)
1034 printf("Tracks: %d Channels: %d Events: %d\n",
1035 n_song_tracks, n_channels, n_ss_ev);
1037 if (trace) {
1038 ss_song_trace_events();
1039 return 0;
1042 /* set the number of channels, unless forced */
1043 if (ss_nchannels == -1)
1044 ss_nchannels = n_channels > 0 ? n_channels : 2;
1046 if (ss_output_open(driver, devfile) < 0) {
1047 printf("Error: can't init driver\n");
1048 return 2;
1051 /* init the generators */
1052 ss_gen_init();
1054 /* init the instruments */
1055 for (n = 0; n < n_song_tracks; n++)
1056 ss_ins_init(&ss_song_ins[n]);
1058 /* calculate the frame to start playing */
1059 skip_frames = skip_secs * ss_frequency;
1061 /* main loop */
1062 do {
1063 /* process all events in this frame */
1064 /* if((e = process_this_frame_events(e, skip_frames)) == NULL)
1065 break;*/
1066 e = process_this_frame_events(e, skip_frames);
1068 /* reset frame samples */
1069 ss_output_init_frame(output);
1071 /* generate output from all instruments */
1072 for (n = i = 0; n < n_song_tracks; n++)
1073 i += ss_ins_frame(&ss_song_ins[n], output);
1075 /* dump to sampling driver */
1076 ss_output_write(output);
1077 } while (i);
1079 if (verbose >= 1)
1080 printf("\n");
1082 ss_output_close();
1084 return 0;