3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
10 * By Shawn Hargreaves,
16 * The core MIDI file player.
18 * Pause and seek functions by George Foot.
20 * See readme.txt for copyright information.
33 /* maximum number of layers in a single voice */
37 typedef struct MIDI_TRACK /* a track in the MIDI file */
39 unsigned char *pos; /* position in track data */
40 long timer; /* time until next event */
41 unsigned char running_status; /* last MIDI event */
45 typedef struct MIDI_CHANNEL /* a MIDI channel */
47 int patch; /* current sound */
48 int volume; /* volume controller */
49 int pan; /* pan position */
50 int pitch_bend; /* pitch bend position */
51 int new_volume; /* cached volume change */
52 int new_pitch_bend; /* cached pitch bend */
53 int note[128][MIDI_LAYERS]; /* status of each note */
57 typedef struct MIDI_VOICE /* a voice on the soundcard */
59 int channel; /* MIDI channel */
60 int note; /* note (-1 = off) */
61 int volume; /* note velocity */
62 long time; /* when note was triggered */
66 typedef struct WAITING_NOTE /* a stored note-on request */
74 typedef struct PATCH_TABLE /* GM -> external synth */
76 int bank1; /* controller #0 */
77 int bank2; /* controller #32 */
78 int prog; /* program change */
79 int pitch; /* pitch shift */
83 volatile long midi_pos = -1; /* position in MIDI file */
84 static long midi_pos_counter; /* delta for midi_pos */
86 volatile long _midi_tick = 0; /* counter for killing notes */
88 static void midi_player(); /* core MIDI player routine */
89 static void prepare_to_play(MIDI *midi);
90 static void midi_lock_mem();
92 static MIDI *midifile = NULL; /* the file that is playing */
94 static int midi_loop = 0; /* repeat at eof? */
96 long midi_loop_start = -1; /* where to loop back to */
97 long midi_loop_end = -1; /* loop at this position */
99 static int midi_semaphore = 0; /* reentrancy flag */
100 static int midi_loaded_patches = FALSE; /* loaded entire patch set? */
102 static int midi_timer_speed; /* midi_player's timer speed */
103 static int midi_pos_speed; /* MIDI delta -> midi_pos */
104 static int midi_speed; /* MIDI delta -> timer */
105 static int midi_new_speed; /* for tempo change events */
107 static int old_midi_volume = -1; /* stored global volume */
109 static int midi_alloc_channel; /* so _midi_allocate_voice */
110 static int midi_alloc_note; /* knows which note the */
111 static int midi_alloc_vol; /* sound is associated with */
113 static MIDI_TRACK midi_track[MIDI_TRACKS]; /* the active tracks */
114 static MIDI_VOICE midi_voice[MIDI_VOICES]; /* synth voice status */
115 static MIDI_CHANNEL midi_channel[16]; /* MIDI channel info */
116 static WAITING_NOTE midi_waiting[MIDI_VOICES]; /* notes still to be played */
117 static PATCH_TABLE patch_table[128]; /* GM -> external synth */
119 static int midi_seeking; /* set during seeks */
120 static int midi_looping; /* set during loops */
123 void (*midi_msg_callback)(int msg, int byte1, int byte2) = NULL;
124 void (*midi_meta_callback)(int type, unsigned char *data, int length) = NULL;
125 void (*midi_sysex_callback)(unsigned char *data, int length) = NULL;
130 * Locks a MIDI file into physical memory. Pretty important, since they
131 * are mostly accessed inside interrupt handlers.
133 void lock_midi(MIDI *midi)
137 _go32_dpmi_lock_data(midi, sizeof(MIDI));
139 for (c=0; c<MIDI_TRACKS; c++)
140 if (midi->track[c].data)
141 _go32_dpmi_lock_data(midi->track[c].data, midi->track[c].len);
147 * Loads a standard MIDI file, returning a pointer to a MIDI structure,
150 MIDI *load_midi(char *filename)
160 fp = pack_fopen(filename, F_READ); /* open the file */
164 midi = malloc(sizeof(MIDI)); /* get some memory */
170 for (c=0; c<MIDI_TRACKS; c++) {
171 midi->track[c].data = NULL;
172 midi->track[c].len = 0;
175 pack_fread(buf, 4, fp); /* read midi header */
176 if (memcmp(buf, "MThd", 4))
179 trashtmp=pack_mgetl(fp); /* skip header chunk length */
181 data = pack_mgetw(fp); /* MIDI file type */
182 if ((data != 0) && (data != 1))
185 num_tracks = pack_mgetw(fp); /* number of tracks */
186 if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS))
189 data = pack_mgetw(fp); /* beat divisions */
190 midi->divisions = ABS(data);
192 for (c=0; c<num_tracks; c++) { /* read each track */
193 pack_fread(buf, 4, fp); /* read track header */
194 if (memcmp(buf, "MTrk", 4))
197 data = pack_mgetl(fp); /* length of track chunk */
198 midi->track[c].len = data;
200 midi->track[c].data = malloc(data); /* allocate memory */
201 if (!midi->track[c].data)
203 /* finally, read track data */
204 if (pack_fread(midi->track[c].data, data, fp) != data)
222 * Frees the memory being used by a MIDI file.
224 void destroy_midi(MIDI *midi)
228 if (midi == midifile)
232 for (c=0; c<MIDI_TRACKS; c++) {
233 if (midi->track[c].data) {
234 _unlock_dpmi_data(midi->track[c].data, midi->track[c].len);
235 free(midi->track[c].data);
238 _unlock_dpmi_data(midi, sizeof(MIDI));
246 * The MIDI file format is a strange thing. Time offsets are only 32 bits,
247 * yet they are compressed in a weird variable length format. This routine
248 * reads a variable length integer from a MIDI data stream. It returns the
249 * number read, and alters the data pointer according to the number of
252 static unsigned long parse_var_len(unsigned char **data)
254 unsigned long val = **data & 0x7F;
256 while (**data & 0x80) {
259 val += (**data & 0x7F);
266 static END_OF_FUNCTION(parse_var_len);
270 /* global_volume_fix:
271 * Converts a note volume, adjusting it according to the global
272 * _midi_volume variable.
274 static inline int global_volume_fix(int vol)
276 if (_midi_volume >= 0)
277 return (vol * _midi_volume) / 256;
285 * Converts a note volume, adjusting it according to the channel volume
286 * and the global _midi_volume variable.
288 static inline int sort_out_volume(int c, int vol)
290 return global_volume_fix((vol * midi_channel[c].volume) / 128);
295 /* raw_program_change:
296 * Sends a program change message to a device capable of handling raw
297 * MIDI data, using patch mapping tables. Assumes that midi_driver->raw_midi
298 * isn't NULL, so check before calling it!
300 static void raw_program_change(int channel, int patch)
304 if (patch_table[patch].bank1 >= 0) {
305 midi_driver->raw_midi(0xB0+channel);
306 midi_driver->raw_midi(0);
307 midi_driver->raw_midi(patch_table[patch].bank1);
311 if (patch_table[patch].bank2 >= 0) {
312 midi_driver->raw_midi(0xB0+channel);
313 midi_driver->raw_midi(32);
314 midi_driver->raw_midi(patch_table[patch].bank2);
318 midi_driver->raw_midi(0xC0+channel);
319 midi_driver->raw_midi(patch_table[patch].prog);
322 midi_driver->raw_midi(0xB0+channel);
323 midi_driver->raw_midi(7);
324 midi_driver->raw_midi(global_volume_fix(midi_channel[channel].volume-1));
328 static END_OF_FUNCTION(raw_program_change);
333 * Processes a MIDI note-off event.
335 static void midi_note_off(int channel, int note)
341 /* can we send raw MIDI data? */
342 if (midi_driver->raw_midi) {
344 note += patch_table[midi_channel[channel].patch].pitch;
346 midi_driver->raw_midi(0x80+channel);
347 midi_driver->raw_midi(note);
348 midi_driver->raw_midi(0);
352 /* oh well, have to do it the long way... */
353 for (layer=0; layer<MIDI_LAYERS; layer++) {
354 voice = midi_channel[channel].note[note][layer];
356 midi_driver->key_off(voice + midi_driver->basevoice);
357 midi_voice[voice].note = -1;
358 midi_voice[voice].time = _midi_tick;
359 midi_channel[channel].note[note][layer] = -1;
364 /* if the note isn't playing, it must still be in the waiting room */
366 for (c=0; c<MIDI_VOICES; c++) {
367 if ((midi_waiting[c].channel == channel) &&
368 (midi_waiting[c].note == note)) {
369 midi_waiting[c].note = -1;
376 static END_OF_FUNCTION(midi_note_off);
380 /* sort_out_pitch_bend:
381 * MIDI pitch bend range is + or - two semitones. The low-level soundcard
382 * drivers can only handle bends up to +1 semitone. This routine converts
383 * pitch bends from MIDI format to our own format.
385 static inline void sort_out_pitch_bend(int *bend, int *note)
387 if (*bend == 0x2000) {
399 while (*bend >= 0x1000) {
407 /* _midi_allocate_voice:
408 * Allocates a MIDI voice in the range min-max (inclusive). This is
409 * intended to be called by the key_on() handlers in the MIDI driver,
410 * and shouldn't be used by any other code.
412 int _midi_allocate_voice(int min, int max)
417 int best_time = LONG_MAX;
423 max = midi_driver->voices-1;
425 /* which layer can we use? */
426 for (layer=0; layer<MIDI_LAYERS; layer++)
427 if (midi_channel[midi_alloc_channel].note[midi_alloc_note][layer] < 0)
430 if (layer >= MIDI_LAYERS)
433 /* find a free voice */
434 for (c=min; c<=max; c++) {
435 if ((midi_voice[c].note < 0) &&
436 (midi_voice[c].time < best_time) &&
437 ((c < midi_driver->xmin) || (c > midi_driver->xmax))) {
439 best_time = midi_voice[c].time;
443 /* if there are no free voices, kill a note to make room */
446 best_time = LONG_MAX;
447 for (c=min; c<=max; c++) {
448 if ((midi_voice[c].time < best_time) &&
449 ((c < midi_driver->xmin) || (c > midi_driver->xmax))) {
451 best_time = midi_voice[c].time;
455 midi_note_off(midi_voice[voice].channel, midi_voice[voice].note);
460 /* ok, we got it... */
461 midi_voice[voice].channel = midi_alloc_channel;
462 midi_voice[voice].note = midi_alloc_note;
463 midi_voice[voice].volume = midi_alloc_vol;
464 midi_voice[voice].time = _midi_tick;
465 midi_channel[midi_alloc_channel].note[midi_alloc_note][layer] = voice;
467 return voice + midi_driver->basevoice;
470 END_OF_FUNCTION(_midi_allocate_voice);
475 * Processes a MIDI note-on event. Tries to find a free soundcard voice,
476 * and if it can't either cuts off an existing note, or if 'polite' is
477 * set, just stores the channel, note and volume in the waiting list.
479 static void midi_note_on(int channel, int note, int vol, int polite)
481 int c, layer, inst, bend, corrected_note;
483 /* it's easy if the driver can handle raw MIDI data */
484 if (midi_driver->raw_midi) {
486 note += patch_table[midi_channel[channel].patch].pitch;
488 midi_driver->raw_midi(0x90+channel);
489 midi_driver->raw_midi(note);
490 midi_driver->raw_midi(vol);
494 /* if the note is already on, turn it off */
495 for (layer=0; layer<MIDI_LAYERS; layer++) {
496 if (midi_channel[channel].note[note][layer] >= 0) {
497 midi_note_off(channel, note);
502 /* if zero volume and the note isn't playing, we can just ignore it */
507 /* are there any free voices? */
508 for (c=0; c<midi_driver->voices; c++)
509 if ((midi_voice[c].note < 0) &&
510 ((c < midi_driver->xmin) || (c > midi_driver->xmax)))
513 /* if there are no free voices, remember the note for later */
514 if ((c >= midi_driver->voices) && (polite)) {
515 for (c=0; c<MIDI_VOICES; c++) {
516 if (midi_waiting[c].note < 0) {
517 midi_waiting[c].channel = channel;
518 midi_waiting[c].note = note;
519 midi_waiting[c].volume = vol;
534 inst = midi_channel[channel].patch;
535 corrected_note = note;
536 bend = midi_channel[channel].pitch_bend;
537 sort_out_pitch_bend(&bend, &corrected_note);
541 midi_alloc_channel = channel;
542 midi_alloc_note = note;
543 midi_alloc_vol = vol;
545 midi_driver->key_on(inst, corrected_note, bend,
546 sort_out_volume(channel, vol),
547 midi_channel[channel].pan);
550 static END_OF_FUNCTION(midi_note_on);
555 * Turns off all active notes.
557 static void all_notes_off(int channel)
559 if (midi_driver->raw_midi) {
560 midi_driver->raw_midi(0xB0+channel);
561 midi_driver->raw_midi(123);
562 midi_driver->raw_midi(0);
568 for (note=0; note<128; note++)
569 for (layer=0; layer<MIDI_LAYERS; layer++)
570 if (midi_channel[channel].note[note][layer] >= 0)
571 midi_note_off(channel, note);
575 static END_OF_FUNCTION(all_notes_off);
579 /* reset_controllers:
580 * Resets volume, pan, pitch bend, etc, to default positions.
582 static void reset_controllers(int channel)
584 midi_channel[channel].new_volume = 128;
585 midi_channel[channel].new_pitch_bend = 0x2000;
587 switch (channel % 3) {
588 case 0: midi_channel[channel].pan = ((channel/3) & 1) ? 60 : 68; break;
589 case 1: midi_channel[channel].pan = 104; break;
590 case 2: midi_channel[channel].pan = 24; break;
593 if (midi_driver->raw_midi) {
594 midi_driver->raw_midi(0xB0+channel);
595 midi_driver->raw_midi(10);
596 midi_driver->raw_midi(midi_channel[channel].pan);
600 static END_OF_FUNCTION(reset_controllers);
604 /* update_controllers:
605 * Checks cached controller information and updates active voices.
607 static void update_controllers()
611 for (c=0; c<16; c++) {
612 /* check for volume controller change */
613 if ((midi_channel[c].volume != midi_channel[c].new_volume) ||
614 (old_midi_volume != _midi_volume)) {
615 midi_channel[c].volume = midi_channel[c].new_volume;
616 if (midi_driver->raw_midi) {
617 midi_driver->raw_midi(0xB0+c);
618 midi_driver->raw_midi(7);
619 midi_driver->raw_midi(global_volume_fix(midi_channel[c].volume-1));
622 for (c2=0; c2<MIDI_VOICES; c2++) {
623 if ((midi_voice[c2].channel == c) &&
624 (midi_voice[c2].note >= 0)) {
625 int vol = sort_out_volume(c, midi_voice[c2].volume);
626 midi_driver->set_volume(c2 + midi_driver->basevoice, vol);
632 /* check for pitch bend change */
633 if (midi_channel[c].pitch_bend != midi_channel[c].new_pitch_bend) {
634 midi_channel[c].pitch_bend = midi_channel[c].new_pitch_bend;
635 if (midi_driver->raw_midi) {
636 midi_driver->raw_midi(0xE0+c);
637 midi_driver->raw_midi(midi_channel[c].pitch_bend & 0x7F);
638 midi_driver->raw_midi(midi_channel[c].pitch_bend >> 7);
641 for (c2=0; c2<MIDI_VOICES; c2++) {
642 if ((midi_voice[c2].channel == c) &&
643 (midi_voice[c2].note >= 0)) {
644 int bend = midi_channel[c].pitch_bend;
645 int note = midi_voice[c2].note;
646 sort_out_pitch_bend(&bend, ¬e);
647 midi_driver->set_pitch(c2 + midi_driver->basevoice, note, bend);
654 old_midi_volume = _midi_volume;
657 static END_OF_FUNCTION(update_controllers);
661 /* process_controller:
662 * Deals with a MIDI controller message on the specified channel.
664 static void process_controller(int channel, int ctrl, int data)
668 case 7: /* main volume */
669 midi_channel[channel].new_volume = data+1;
673 midi_channel[channel].pan = data;
674 if (midi_driver->raw_midi) {
675 midi_driver->raw_midi(0xB0+channel);
676 midi_driver->raw_midi(10);
677 midi_driver->raw_midi(data);
681 case 121: /* reset all controllers */
682 reset_controllers(channel);
685 case 123: /* all notes off */
686 case 124: /* omni mode off */
687 case 125: /* omni mode on */
688 case 126: /* poly mode off */
689 case 127: /* poly mode on */
690 all_notes_off(channel);
695 static END_OF_FUNCTION(process_controller);
699 /* process_meta_event:
700 * Processes the next meta-event on the specified track.
702 static void process_meta_event(unsigned char **pos, long *timer)
704 unsigned char metatype = *((*pos)++);
705 long length = parse_var_len(pos);
708 if (midi_meta_callback)
709 midi_meta_callback(metatype, *pos, length);
711 if (metatype == 0x2F) { /* end of track */
717 if (metatype == 0x51) { /* tempo change */
718 tempo = (*pos)[0] * 0x10000L + (*pos)[1] * 0x100 + (*pos)[2];
719 midi_new_speed = (tempo/1000) * (TIMERS_PER_SECOND/1000);
720 midi_new_speed /= midifile->divisions;
726 static END_OF_FUNCTION(process_meta_event);
730 /* process_midi_event:
731 * Processes the next MIDI event on the specified track.
733 static void process_midi_event(unsigned char **pos, unsigned char *running_status, long *timer)
735 unsigned char byte1, byte2;
742 if (event & 0x80) { /* regular message */
743 /* no running status for sysex and meta-events! */
744 if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF))
745 *running_status = event;
749 else { /* use running status */
752 event = *running_status;
756 /* program callback? */
757 if ((midi_msg_callback) &&
758 (event != 0xF0) && (event != 0xF7) && (event != 0xFF))
759 midi_msg_callback(event, byte1, byte2);
761 channel = event & 0x0F;
765 case 0x08: /* note off */
766 midi_note_off(channel, byte1);
770 case 0x09: /* note on */
771 midi_note_on(channel, byte1, byte2, 1);
775 case 0x0A: /* note aftertouch */
779 case 0x0B: /* control change */
780 process_controller(channel, byte1, byte2);
784 case 0x0C: /* program change */
785 midi_channel[channel].patch = byte1;
786 if (midi_driver->raw_midi)
787 raw_program_change(channel, byte1);
791 case 0x0D: /* channel aftertouch */
795 case 0x0E: /* pitch bend */
796 midi_channel[channel].new_pitch_bend = byte1 + (byte2<<7);
800 case 0x0F: /* special event */
802 case 0xF0: /* sysex */
804 l = parse_var_len(pos);
805 if (midi_sysex_callback)
806 midi_sysex_callback(*pos, l);
810 case 0xF2: /* song position */
814 case 0xF3: /* song select */
818 case 0xFF: /* meta-event */
819 process_meta_event(pos, timer);
823 /* the other special events don't have any data bytes,
824 so we don't need to bother skipping past them */
830 /* something has gone badly wrong if we ever get to here */
835 static END_OF_FUNCTION(process_midi_event);
840 * The core MIDI player: to be used as a timer callback.
842 static void midi_player()
851 if (midi_semaphore) {
852 midi_timer_speed += BPS_TO_TIMER(40);
853 install_int_ex(midi_player, BPS_TO_TIMER(40));
857 midi_semaphore = TRUE;
862 for (c=0; c<MIDI_VOICES; c++)
863 midi_waiting[c].note = -1;
865 /* deal with each track in turn... */
866 for (c=0; c<MIDI_TRACKS; c++) {
867 if (midi_track[c].pos) {
868 midi_track[c].timer -= midi_timer_speed;
870 /* while events are waiting, process them */
871 while (midi_track[c].timer <= 0) {
872 process_midi_event(&midi_track[c].pos,
873 &midi_track[c].running_status,
874 &midi_track[c].timer);
876 /* read next time offset */
877 if (midi_track[c].pos) {
878 l = parse_var_len(&midi_track[c].pos);
880 midi_track[c].timer += l;
886 /* update global position value */
887 midi_pos_counter -= midi_timer_speed;
888 while (midi_pos_counter <= 0) {
889 midi_pos_counter += midi_pos_speed;
894 if (midi_new_speed > 0) {
895 for (c=0; c<MIDI_TRACKS; c++) {
896 if (midi_track[c].pos) {
897 midi_track[c].timer /= midi_speed;
898 midi_track[c].timer *= midi_new_speed;
901 midi_pos_counter /= midi_speed;
902 midi_pos_counter *= midi_new_speed;
904 midi_speed = midi_new_speed;
905 midi_pos_speed = midi_new_speed * midifile->divisions;
909 /* figure out how long until we need to be called again */
911 midi_timer_speed = LONG_MAX;
912 for (c=0; c<MIDI_TRACKS; c++) {
913 if (midi_track[c].pos) {
915 if (midi_track[c].timer < midi_timer_speed)
916 midi_timer_speed = midi_track[c].timer;
920 /* end of the music? */
921 if ((!active) || ((midi_loop_end > 0) && (midi_pos >= midi_loop_end))) {
922 if ((midi_loop) && (!midi_looping)) {
923 if (midi_loop_start > 0) {
924 remove_int(midi_player);
925 midi_semaphore = FALSE;
927 if (midi_seek(midi_loop_start) != 0) {
928 midi_looping = FALSE;
932 midi_looping = FALSE;
933 midi_semaphore = TRUE;
934 goto do_it_all_again;
939 prepare_to_play(midifile);
940 goto do_it_all_again;
945 midi_semaphore = FALSE;
950 /* reprogram the timer */
951 if (midi_timer_speed < BPS_TO_TIMER(40))
952 midi_timer_speed = BPS_TO_TIMER(40);
955 install_int_ex(midi_player, midi_timer_speed);
957 /* controller changes are cached and only processed here, so we can
958 condense streams of controller data into just a few voice updates */
959 update_controllers();
961 /* and deal with any notes that are still waiting to be played */
962 for (c=0; c<MIDI_VOICES; c++)
963 if (midi_waiting[c].note >= 0)
964 midi_note_on(midi_waiting[c].channel, midi_waiting[c].note,
965 midi_waiting[c].volume, 0);
967 midi_semaphore = FALSE;
970 static END_OF_FUNCTION(midi_player);
975 * Sets up the MIDI player ready for use. Returns non-zero on failure.
977 static int midi_init()
984 midi_loaded_patches = FALSE;
988 for (c=0; c<16; c++) {
989 midi_channel[c].volume = 128;
990 midi_channel[c].pitch_bend = 0x2000;
992 for (c2=0; c2<128; c2++)
993 for (c3=0; c3<MIDI_LAYERS; c3++)
994 midi_channel[c].note[c2][c3] = -1;
997 for (c=0; c<MIDI_VOICES; c++) {
998 midi_voice[c].note = -1;
999 midi_voice[c].time = 0;
1002 for (c=0; c<128; c++) {
1003 sprintf(buf, "p%d", c+1);
1004 argv = get_config_argv("midimap", buf, &argc);
1006 if ((argv) && (argc == 4)) {
1007 patch_table[c].bank1 = atoi(argv[0]);
1008 patch_table[c].bank2 = atoi(argv[1]);
1009 patch_table[c].prog = atoi(argv[2]);
1010 patch_table[c].pitch = atoi(argv[3]);
1013 patch_table[c].bank1 = -1;
1014 patch_table[c].bank2 = -1;
1015 patch_table[c].prog = c;
1016 patch_table[c].pitch = 0;
1020 /* register_datafile_object(DAT_MIDI, NULL, (void (*)(void *))destroy_midi);*/
1028 * Turns off all active notes and removes the timer handler.
1030 static void midi_exit()
1038 * Scans through a MIDI file and identifies which patches it uses, passing
1039 * them to the soundcard driver so it can load whatever samples are
1042 static int load_patches(MIDI *midi)
1044 char patches[128], drums[128];
1045 unsigned char *p, *end;
1046 unsigned char running_status, event;
1050 for (c=0; c<128; c++) /* initialise to unused */
1051 patches[c] = drums[c] = FALSE;
1053 patches[0] = TRUE; /* always load the piano */
1055 for (c=0; c<MIDI_TRACKS; c++) { /* for each track... */
1056 p = midi->track[c].data;
1057 end = p + midi->track[c].len;
1060 while (p < end) { /* work through data stream */
1062 if (event & 0x80) { /* regular message */
1064 if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF))
1065 running_status = event;
1067 else /* use running status */
1068 event = running_status;
1072 case 0x0C: /* program change! */
1077 case 0x09: /* note on, is it a drum? */
1078 if ((event & 0x0F) == 9)
1083 case 0x08: /* note off */
1084 case 0x0A: /* note aftertouch */
1085 case 0x0B: /* control change */
1086 case 0x0E: /* pitch bend */
1090 case 0x0D: /* channel aftertouch */
1094 case 0x0F: /* special event */
1096 case 0xF0: /* sysex */
1098 l = parse_var_len(&p);
1102 case 0xF2: /* song position */
1106 case 0xF3: /* song select */
1110 case 0xFF: /* meta-event */
1112 l = parse_var_len(&p);
1117 /* the other special events don't have any data bytes,
1118 so we don't need to bother skipping past them */
1124 /* something has gone badly wrong if we ever get to here */
1128 if (p < end) /* skip time offset */
1133 /* tell the driver to do its stuff */
1134 return midi_driver->load_patches(patches, drums);
1140 * Sets up all the global variables needed to play the specified file.
1142 static void prepare_to_play(MIDI *midi)
1146 for (c=0; c<16; c++)
1147 reset_controllers(c);
1149 update_controllers();
1153 midi_pos_counter = 0;
1154 midi_speed = TIMERS_PER_SECOND / 2 / midifile->divisions; /* 120 bpm */
1155 midi_new_speed = -1;
1156 midi_pos_speed = midi_speed * midifile->divisions;
1157 midi_timer_speed = 0;
1161 for (c=0; c<16; c++) {
1162 midi_channel[c].patch = 0;
1163 if (midi_driver->raw_midi)
1164 raw_program_change(c, 0);
1167 for (c=0; c<MIDI_TRACKS; c++) {
1168 if (midi->track[c].data) {
1169 midi_track[c].pos = midi->track[c].data;
1170 midi_track[c].timer = parse_var_len(&midi_track[c].pos);
1171 midi_track[c].timer *= midi_speed;
1174 midi_track[c].pos = NULL;
1175 midi_track[c].timer = LONG_MAX;
1177 midi_track[c].running_status = 0;
1181 static END_OF_FUNCTION(prepare_to_play);
1186 * Starts playing the specified MIDI file. If loop is set, the MIDI file
1187 * will be repeated until replaced with something else, otherwise it will
1188 * stop at the end of the file. Passing a NULL MIDI file will stop whatever
1189 * music is currently playing: allegro.h defines the macro stop_midi() to
1190 * be play_midi(NULL, FALSE); Returns non-zero if an error occurs (this
1191 * may happen if a patch-caching wavetable driver is unable to load the
1192 * required samples).
1194 int play_midi(MIDI *midi, int loop)
1198 remove_int(midi_player);
1200 for (c=0; c<16; c++)
1204 if (!midi_loaded_patches)
1205 if (load_patches(midi) != 0)
1209 midi_loop_start = -1;
1212 prepare_to_play(midi);
1214 /* arbitrary speed, midi_player() will adjust it */
1215 install_int(midi_player, 20);
1225 END_OF_FUNCTION(play_midi);
1229 /* play_looped_midi:
1230 * Like play_midi(), but the file loops from the specified end position
1231 * back to the specified start position (the end position can be -1 to
1232 * indicate the end of the file).
1234 int play_looped_midi(MIDI *midi, int loop_start, int loop_end)
1236 if (play_midi(midi, TRUE) != 0)
1239 midi_loop_start = loop_start;
1240 midi_loop_end = loop_end;
1248 * Stops whatever MIDI file is currently playing.
1252 play_midi(NULL, FALSE);
1255 END_OF_FUNCTION(stop_midi);
1260 * Pauses the currently playing MIDI file.
1269 remove_int(midi_player);
1271 for (c=0; c<16; c++)
1275 END_OF_FUNCTION(midi_pause);
1280 * Resumes playing a paused MIDI file.
1287 install_int_ex(midi_player, midi_timer_speed);
1290 END_OF_FUNCTION(midi_resume);
1295 * Seeks to the given midi_pos in the current MIDI file. If the target
1296 * is earlier in the file than the current midi_pos it seeks from the
1297 * beginning; otherwise it seeks from the current position. Returns zero
1298 * if successful, non-zero if it hit the end of the file (1 means it
1299 * stopped playing, 2 means it looped back to the start).
1301 int midi_seek(int target)
1305 MIDI_DRIVER *old_driver;
1309 int old_pitch_bend[16];
1315 /* first stop the player */
1318 /* store current settings */
1319 for (c=0; c<16; c++) {
1320 old_patch[c] = midi_channel[c].patch;
1321 old_volume[c] = midi_channel[c].volume;
1322 old_pan[c] = midi_channel[c].pan;
1323 old_pitch_bend[c] = midi_channel[c].pitch_bend;
1326 /* save some variables and give temporary values */
1327 old_driver = midi_driver;
1328 midi_driver = &midi_none;
1329 old_midi_loop = midi_loop;
1331 old_midifile = midifile;
1333 /* set flag to tell midi_player not to reinstall itself */
1336 /* are we seeking backwards? If so, skip back to the start of the file */
1337 if (target <= midi_pos)
1338 prepare_to_play(midifile);
1340 /* now sit back and let midi_player get to the position */
1341 while ((midi_pos < target) && (midi_pos != -1)) {
1342 int mmpc = midi_pos_counter;
1345 mmpc -= midi_timer_speed;
1347 mmpc += midi_pos_speed;
1357 /* restore previously saved variables */
1358 midi_loop = old_midi_loop;
1359 midi_driver = old_driver;
1362 if (midi_pos != -1) {
1363 /* refresh the driver with any changed parameters */
1364 if (midi_driver->raw_midi) {
1365 for (c=0; c<16; c++) {
1366 /* program change (this sets the volume as well) */
1367 if ((midi_channel[c].patch != old_patch[c]) ||
1368 (midi_channel[c].volume != old_volume[c]))
1369 raw_program_change(c, midi_channel[c].patch);
1372 if (midi_channel[c].pan != old_pan[c]) {
1373 midi_driver->raw_midi(0xB0+c);
1374 midi_driver->raw_midi(10);
1375 midi_driver->raw_midi(midi_channel[c].pan);
1379 if (midi_channel[c].pitch_bend != old_pitch_bend[c]) {
1380 midi_driver->raw_midi(0xE0+c);
1381 midi_driver->raw_midi(midi_channel[c].pitch_bend & 0x7F);
1382 midi_driver->raw_midi(midi_channel[c].pitch_bend >> 7);
1387 /* if we didn't hit the end of the file, continue playing */
1389 install_int(midi_player, 20);
1394 if ((midi_loop) && (!midi_looping)) { /* was file was looped? */
1395 prepare_to_play(old_midifile);
1396 install_int(midi_player, 20);
1397 return 2; /* seek past EOF => file restarted */
1400 return 1; /* seek past EOF => file stopped */
1403 END_OF_FUNCTION(midi_seek);
1408 * Inserts MIDI command bytes into the output stream, in realtime.
1410 void midi_out(unsigned char *data, int length)
1412 unsigned char *pos = data;
1413 unsigned char running_status = 0;
1416 midi_semaphore = TRUE;
1419 while (pos < data+length)
1420 process_midi_event(&pos, &running_status, &timer);
1422 midi_semaphore = FALSE;
1427 /* load_midi_patches:
1428 * Tells the MIDI driver to preload the entire sample set.
1430 int load_midi_patches()
1432 char patches[128], drums[128];
1435 for (c=0; c<128; c++)
1436 patches[c] = drums[c] = TRUE;
1438 midi_semaphore = TRUE;
1439 ret = midi_driver->load_patches(patches, drums);
1440 midi_semaphore = FALSE;
1442 midi_loaded_patches = TRUE;
1450 * Locks all the memory that the midi player touches inside the timer
1451 * interrupt handler (which is most of it).
1453 static void midi_lock_mem()
1455 LOCK_VARIABLE(midi_pos);
1456 LOCK_VARIABLE(midi_pos_counter);
1457 LOCK_VARIABLE(_midi_tick);
1458 LOCK_VARIABLE(midifile);
1459 LOCK_VARIABLE(midi_semaphore);
1460 LOCK_VARIABLE(midi_loop);
1461 LOCK_VARIABLE(midi_loop_start);
1462 LOCK_VARIABLE(midi_loop_end);
1463 LOCK_VARIABLE(midi_timer_speed);
1464 LOCK_VARIABLE(midi_pos_speed);
1465 LOCK_VARIABLE(midi_speed);
1466 LOCK_VARIABLE(midi_new_speed);
1467 LOCK_VARIABLE(old_midi_volume);
1468 LOCK_VARIABLE(midi_alloc_channel);
1469 LOCK_VARIABLE(midi_alloc_note);
1470 LOCK_VARIABLE(midi_alloc_vol);
1471 LOCK_VARIABLE(midi_track);
1472 LOCK_VARIABLE(midi_voice);
1473 LOCK_VARIABLE(midi_channel);
1474 LOCK_VARIABLE(midi_waiting);
1475 LOCK_VARIABLE(patch_table);
1476 LOCK_VARIABLE(midi_msg_callback);
1477 LOCK_VARIABLE(midi_meta_callback);
1478 LOCK_VARIABLE(midi_sysex_callback);
1479 LOCK_VARIABLE(midi_seeking);
1480 LOCK_VARIABLE(midi_looping);
1481 LOCK_FUNCTION(parse_var_len);
1482 LOCK_FUNCTION(raw_program_change);
1483 LOCK_FUNCTION(midi_note_off);
1484 LOCK_FUNCTION(_midi_allocate_voice);
1485 LOCK_FUNCTION(midi_note_on);
1486 LOCK_FUNCTION(all_notes_off);
1487 LOCK_FUNCTION(reset_controllers);
1488 LOCK_FUNCTION(update_controllers);
1489 LOCK_FUNCTION(process_controller);
1490 LOCK_FUNCTION(process_meta_event);
1491 LOCK_FUNCTION(process_midi_event);
1492 LOCK_FUNCTION(midi_player);
1493 LOCK_FUNCTION(prepare_to_play);
1494 LOCK_FUNCTION(play_midi);
1495 LOCK_FUNCTION(stop_midi);
1496 LOCK_FUNCTION(midi_pause);
1497 LOCK_FUNCTION(midi_resume);
1498 LOCK_FUNCTION(midi_seek);
1503 /* midi_constructor:
1504 * Register my functions with the code in sound.c.
1506 static void midi_constructor() __attribute__ ((constructor));
1507 static void midi_constructor()
1509 _midi_init = midi_init;
1510 _midi_exit = midi_exit;