From 0c51dbced5a5a7f96c74fe8616d84a50406a51a4 Mon Sep 17 00:00:00 2001 From: angel Date: Mon, 2 May 2005 10:46:37 +0000 Subject: [PATCH] Added some event conversion code to midi_song.c (doesn't even compile). git-svn-id: file:///home/angel/tmp/svn-triptico/ahxm/trunk@522 c87de0a0-a11c-0410-a1e5-866214bc28b2 --- midi_song.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 154 insertions(+), 6 deletions(-) diff --git a/midi_song.c b/midi_song.c index 1dd5681..5121f9e 100644 --- a/midi_song.c +++ b/midi_song.c @@ -42,6 +42,7 @@ struct midi_ev_generic song_ev_type type; /* event type */ int time; /* time in milliseconds */ int trk_id; /* track id */ + int channel; /* MIDI channel */ }; struct midi_ev_program @@ -49,6 +50,7 @@ struct midi_ev_program song_ev_type type; /* SONG_EV_MIDI_PROGRAM */ int time; int trk_id; + int channel; int program; /* MIDI program number */ }; @@ -57,6 +59,7 @@ struct midi_ev_note_off song_ev_type type; /* SONG_EV_NOTE_OFF */ int time; int trk_id; + int channel; int note; /* MIDI note */ }; @@ -65,6 +68,7 @@ struct midi_ev_note_on song_ev_type type; /* SONG_EV_NOTE_ON */ int time; int trk_id; + int channel; int note; /* MIDI note */ int vol; /* volume */ }; @@ -80,8 +84,8 @@ union midi_ev /* the MIDI song stream */ -static union midi_ev * _midi_song=NULL; -static int _n_midi_ev=0; +static union midi_ev * midi_song=NULL; +static int n_midi_ev=0; /******************* @@ -91,14 +95,158 @@ static int _n_midi_ev=0; static void add_midi_ev(union midi_ev * e) /* adds a MIDI song event */ { - _n_midi_ev++; + n_midi_ev++; /* reallocs */ - _midi_song=(union midi_ev *)realloc(_midi_song, - _n_midi_ev * sizeof(union midi_ev)); + midi_song=(union midi_ev *)realloc(midi_song, + n_midi_ev * sizeof(union midi_ev)); /* store */ - memcpy(&_midi_song[_n_midi_ev - 1], e, sizeof(union midi_ev)); + memcpy(&midi_song[n_midi_ev - 1], e, sizeof(union midi_ev)); } +static int midi_ev_cmp_by_time(const void * v1, const void * v2) +/* MIDI song event compare function for qsort(), by time */ +{ + struct midi_ev_generic * e1; + struct midi_ev_generic * e2; + + e1=(struct midi_ev_generic *)v1; e2=(struct midi_ev_generic *)v2; + + if(e1->time == e2->time) + return(e1->type - e2->type); + + return(e1->time - e2->time); +} + + +static int midi_song_convert_events(void) +/* converts generic song_ev events to MIDI events */ +{ + union song_ev * e; + union midi_ev me; + int time, time_ac; + int num, den; + int b_track=-1; + + /* resets the ss stream */ + if(midi_song != NULL) + { + free(midi_song); + midi_song=NULL; + } + + n_midi_ev=0; + + /* sorts the song */ + song_sort(); + + time_ac=0; + num=den=4; + + /* travels the song events generating softsynth song events */ + for(n=0;n < _n_song_ev;n++) + { + /* gets the song event */ + e=&_song[n]; + + /* calculates the frame */ + frame=((e->generic.time - time_ac) * fpw) + frame_ac; + + /* generic event data */ + me.generic.type=e->generic.type; + me.generic.frame=frame; + me.generic.trk_id=e->generic.trk_id; + + /* account the biggest track seen */ + if(b_track < e->generic.trk_id) b_track=e->generic.trk_id; + + switch(e->generic.type) + { + case SONG_EV_TEMPO: + + /* updates accumulations */ + frame_ac += frame; + time_ac += e->generic.time; + + /* calculates frames-per-whole based on new tempo */ + fpw=(double) ss_frequency * 60.0; + fpw /= e->tempo.tempo / 4.0; + + break; + + case SONG_EV_METER: + + /* just store the values */ + num=e->meter.num; + den=e->meter.den; + + break; + + case SONG_EV_MEASURE: + + printf("measure boundary check (must be 0): %d\n", + ((int) e->generic.time * num) % den); + + break; + + case SONG_EV_NOTE: + + /* convert to note on / off pairs */ + + me.note_on.type=SONG_EV_NOTE_ON; + me.note_on.note_id=note_id++; + me.note_on.note=e->note.note; + me.note_on.vol=e->note.vol; + + add_midi_ev(&me); + + frame += (int)(e->note.len * fpw); + + me.note_off.type=SONG_EV_NOTE_OFF; + me.note_off.frame=frame; + + add_midi_ev(&me); + break; + + case SONG_EV_MIDI_CHANNEL: + case SONG_EV_MIDI_PROGRAM: + + break; + + case SONG_EV_SS_NOTE_ON_BY_TIME: + case SONG_EV_SS_WAV: + case SONG_EV_SS_PAT: + case SONG_EV_SS_SUSTAIN: + case SONG_EV_SS_CHANNEL_MAP: + case SONG_EV_SS_EFF_DELAY: + case SONG_EV_SS_EFF_ECHO: + case SONG_EV_SS_EFF_COMB: + case SONG_EV_SS_EFF_ALLPASS: + case SONG_EV_SS_EFF_FLANGER: + case SONG_EV_SS_EFF_WOBBLE: + case SONG_EV_SS_EFF_SQWOBBLE: + case SONG_EV_SS_EFF_FADER: + case SONG_EV_SS_EFF_REVERB: + + /* softsynth events are ignored */ + break; + + case SONG_EV_NOTE_ON: + case SONG_EV_NOTE_OFF: + case SONG_EV_END: + + /* never found in generic song streams */ + break; + } + } + + /* generates an end of event mark, a time after the last one */ + me.generic.type=SONG_EV_END; + me.generic.time=time + 1000; + add_ss_ev(&me); + + /* return the number of tracks */ + return(b_track + 1); +} -- 2.11.4.GIT