1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 * By Shawn Hargreaves,
11 * 1 Salisbury Road,
12 * Market Drayton,
13 * Shropshire,
14 * England, TF9 1AJ.
15 *
16 * The core MIDI file player.
17 *
18 * Pause and seek functions by George Foot.
19 *
20 * See readme.txt for copyright information.
21 */
22
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <limits.h>
28
29 #include "allegro.h"
30 #include "internal.h"
31
32
33 /* maximum number of layers in a single voice */
34 #define MIDI_LAYERS 4
35
36
37 typedef struct MIDI_TRACK /* a track in the MIDI file */
38 {
39 unsigned char *pos; /* position in track data */
40 long timer; /* time until next event */
41 unsigned char running_status; /* last MIDI event */
42 } MIDI_TRACK;
43
44
45 typedef struct MIDI_CHANNEL /* a MIDI channel */
46 {
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 */
54 } MIDI_CHANNEL;
55
56
57 typedef struct MIDI_VOICE /* a voice on the soundcard */
58 {
59 int channel; /* MIDI channel */
60 int note; /* note (-1 = off) */
61 int volume; /* note velocity */
62 long time; /* when note was triggered */
63 } MIDI_VOICE;
64
65
66 typedef struct WAITING_NOTE /* a stored note-on request */
67 {
68 int channel;
69 int note;
70 int volume;
71 } WAITING_NOTE;
72
73
74 typedef struct PATCH_TABLE /* GM -> external synth */
75 {
76 int bank1; /* controller #0 */
77 int bank2; /* controller #32 */
78 int prog; /* program change */
79 int pitch; /* pitch shift */
80 } PATCH_TABLE;
81
82
83 volatile long midi_pos = -1; /* position in MIDI file */
84 static long midi_pos_counter; /* delta for midi_pos */
85
86 volatile long _midi_tick = 0; /* counter for killing notes */
87
88 static void midi_player(); /* core MIDI player routine */
89 static void prepare_to_play(MIDI *midi);
90 static void midi_lock_mem();
91
92 static MIDI *midifile = NULL; /* the file that is playing */
93
94 static int midi_loop = 0; /* repeat at eof? */
95
96 long midi_loop_start = -1; /* where to loop back to */
97 long midi_loop_end = -1; /* loop at this position */
98
99 static int midi_semaphore = 0; /* reentrancy flag */
100 static int midi_loaded_patches = FALSE; /* loaded entire patch set? */
101
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 */
106
107 static int old_midi_volume = -1; /* stored global volume */
108
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 */
112
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 */
118
119 static int midi_seeking; /* set during seeks */
120 static int midi_looping; /* set during loops */
121
122 /* hook functions */
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;
126
127
128
129 /* lock_midi:
130 * Locks a MIDI file into physical memory. Pretty important, since they
131 * are mostly accessed inside interrupt handlers.
132 */
lock_midi(MIDI * midi)133 void lock_midi(MIDI *midi)
134 {
135 int c;
136
137 _go32_dpmi_lock_data(midi, sizeof(MIDI));
138
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);
142 }
143
144
145
146 /* load_midi:
147 * Loads a standard MIDI file, returning a pointer to a MIDI structure,
148 * or NULL on error.
149 */
load_midi(char * filename)150 MIDI *load_midi(char *filename)
151 {
152 int trashtmp;
153 int c;
154 char buf[256];
155 long data;
156 PACKFILE *fp;
157 MIDI *midi;
158 int num_tracks;
159
160 fp = pack_fopen(filename, F_READ); /* open the file */
161 if (!fp)
162 return NULL;
163
164 midi = malloc(sizeof(MIDI)); /* get some memory */
165 if (!midi) {
166 pack_fclose(fp);
167 return NULL;
168 }
169
170 for (c=0; c<MIDI_TRACKS; c++) {
171 midi->track[c].data = NULL;
172 midi->track[c].len = 0;
173 }
174
175 pack_fread(buf, 4, fp); /* read midi header */
176 if (memcmp(buf, "MThd", 4))
177 goto err;
178
179 trashtmp=pack_mgetl(fp); /* skip header chunk length */
180
181 data = pack_mgetw(fp); /* MIDI file type */
182 if ((data != 0) && (data != 1))
183 goto err;
184
185 num_tracks = pack_mgetw(fp); /* number of tracks */
186 if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS))
187 goto err;
188
189 data = pack_mgetw(fp); /* beat divisions */
190 midi->divisions = ABS(data);
191
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))
195 goto err;
196
197 data = pack_mgetl(fp); /* length of track chunk */
198 midi->track[c].len = data;
199
200 midi->track[c].data = malloc(data); /* allocate memory */
201 if (!midi->track[c].data)
202 goto err;
203 /* finally, read track data */
204 if (pack_fread(midi->track[c].data, data, fp) != data)
205 goto err;
206 }
207
208 pack_fclose(fp);
209 lock_midi(midi);
210 return midi;
211
212 /* oh dear... */
213 err:
214 pack_fclose(fp);
215 destroy_midi(midi);
216 return NULL;
217 }
218
219
220
221 /* destroy_midi:
222 * Frees the memory being used by a MIDI file.
223 */
destroy_midi(MIDI * midi)224 void destroy_midi(MIDI *midi)
225 {
226 int c;
227
228 if (midi == midifile)
229 stop_midi();
230
231 if (midi) {
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);
236 }
237 }
238 _unlock_dpmi_data(midi, sizeof(MIDI));
239 free(midi);
240 }
241 }
242
243
244
245 /* parse_var_len:
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
250 * bytes it used.
251 */
parse_var_len(unsigned char ** data)252 static unsigned long parse_var_len(unsigned char **data)
253 {
254 unsigned long val = **data & 0x7F;
255
256 while (**data & 0x80) {
257 (*data)++;
258 val <<= 7;
259 val += (**data & 0x7F);
260 }
261
262 (*data)++;
263 return val;
264 }
265
266 static END_OF_FUNCTION(parse_var_len);
267
268
269
270 /* global_volume_fix:
271 * Converts a note volume, adjusting it according to the global
272 * _midi_volume variable.
273 */
global_volume_fix(int vol)274 static inline int global_volume_fix(int vol)
275 {
276 if (_midi_volume >= 0)
277 return (vol * _midi_volume) / 256;
278
279 return vol;
280 }
281
282
283
284 /* sort_out_volume:
285 * Converts a note volume, adjusting it according to the channel volume
286 * and the global _midi_volume variable.
287 */
sort_out_volume(int c,int vol)288 static inline int sort_out_volume(int c, int vol)
289 {
290 return global_volume_fix((vol * midi_channel[c].volume) / 128);
291 }
292
293
294
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!
299 */
raw_program_change(int channel,int patch)300 static void raw_program_change(int channel, int patch)
301 {
302 if (channel != 9) {
303 /* bank change #1 */
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);
308 }
309
310 /* bank change #2 */
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);
315 }
316
317 /* program change */
318 midi_driver->raw_midi(0xC0+channel);
319 midi_driver->raw_midi(patch_table[patch].prog);
320
321 /* update volume */
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));
325 }
326 }
327
328 static END_OF_FUNCTION(raw_program_change);
329
330
331
332 /* midi_note_off:
333 * Processes a MIDI note-off event.
334 */
midi_note_off(int channel,int note)335 static void midi_note_off(int channel, int note)
336 {
337 int done = FALSE;
338 int voice, layer;
339 int c;
340
341 /* can we send raw MIDI data? */
342 if (midi_driver->raw_midi) {
343 if (channel != 9)
344 note += patch_table[midi_channel[channel].patch].pitch;
345
346 midi_driver->raw_midi(0x80+channel);
347 midi_driver->raw_midi(note);
348 midi_driver->raw_midi(0);
349 return;
350 }
351
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];
355 if (voice >= 0) {
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;
360 done = TRUE;
361 }
362 }
363
364 /* if the note isn't playing, it must still be in the waiting room */
365 if (!done) {
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;
370 break;
371 }
372 }
373 }
374 }
375
376 static END_OF_FUNCTION(midi_note_off);
377
378
379
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.
384 */
sort_out_pitch_bend(int * bend,int * note)385 static inline void sort_out_pitch_bend(int *bend, int *note)
386 {
387 if (*bend == 0x2000) {
388 *bend = 0;
389 return;
390 }
391
392 (*bend) -= 0x2000;
393
394 while (*bend < 0) {
395 (*note)--;
396 (*bend) += 0x1000;
397 }
398
399 while (*bend >= 0x1000) {
400 (*note)++;
401 (*bend) -= 0x1000;
402 }
403 }
404
405
406
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.
411 */
_midi_allocate_voice(int min,int max)412 int _midi_allocate_voice(int min, int max)
413 {
414 int c;
415 int layer;
416 int voice = -1;
417 int best_time = LONG_MAX;
418
419 if (min < 0)
420 min = 0;
421
422 if (max < 0)
423 max = midi_driver->voices-1;
424
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)
428 break;
429
430 if (layer >= MIDI_LAYERS)
431 return -1;
432
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))) {
438 voice = c;
439 best_time = midi_voice[c].time;
440 }
441 }
442
443 /* if there are no free voices, kill a note to make room */
444 if (voice < 0) {
445 voice = -1;
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))) {
450 voice = c;
451 best_time = midi_voice[c].time;
452 }
453 }
454 if (voice >= 0)
455 midi_note_off(midi_voice[voice].channel, midi_voice[voice].note);
456 else
457 return -1;
458 }
459
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;
466
467 return voice + midi_driver->basevoice;
468 }
469
470 END_OF_FUNCTION(_midi_allocate_voice);
471
472
473
474 /* midi_note_on:
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.
478 */
midi_note_on(int channel,int note,int vol,int polite)479 static void midi_note_on(int channel, int note, int vol, int polite)
480 {
481 int c, layer, inst, bend, corrected_note;
482
483 /* it's easy if the driver can handle raw MIDI data */
484 if (midi_driver->raw_midi) {
485 if (channel != 9)
486 note += patch_table[midi_channel[channel].patch].pitch;
487
488 midi_driver->raw_midi(0x90+channel);
489 midi_driver->raw_midi(note);
490 midi_driver->raw_midi(vol);
491 return;
492 }
493
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);
498 return;
499 }
500 }
501
502 /* if zero volume and the note isn't playing, we can just ignore it */
503 if (vol == 0)
504 return;
505
506 if (channel != 9) {
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)))
511 break;
512
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;
520 break;
521 }
522 }
523 return;
524 }
525 }
526
527 /* drum sound? */
528 if (channel == 9) {
529 inst = 128+note;
530 corrected_note = 60;
531 bend = 0;
532 }
533 else {
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);
538 }
539
540 /* play the note */
541 midi_alloc_channel = channel;
542 midi_alloc_note = note;
543 midi_alloc_vol = vol;
544
545 midi_driver->key_on(inst, corrected_note, bend,
546 sort_out_volume(channel, vol),
547 midi_channel[channel].pan);
548 }
549
550 static END_OF_FUNCTION(midi_note_on);
551
552
553
554 /* all_notes_off:
555 * Turns off all active notes.
556 */
all_notes_off(int channel)557 static void all_notes_off(int channel)
558 {
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);
563 return;
564 }
565 else {
566 int note, layer;
567
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);
572 }
573 }
574
575 static END_OF_FUNCTION(all_notes_off);
576
577
578
579 /* reset_controllers:
580 * Resets volume, pan, pitch bend, etc, to default positions.
581 */
reset_controllers(int channel)582 static void reset_controllers(int channel)
583 {
584 midi_channel[channel].new_volume = 128;
585 midi_channel[channel].new_pitch_bend = 0x2000;
586
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;
591 }
592
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);
597 }
598 }
599
600 static END_OF_FUNCTION(reset_controllers);
601
602
603
604 /* update_controllers:
605 * Checks cached controller information and updates active voices.
606 */
update_controllers()607 static void update_controllers()
608 {
609 int c, c2;
610
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));
620 }
621 else {
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);
627 }
628 }
629 }
630 }
631
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);
639 }
640 else {
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);
648 }
649 }
650 }
651 }
652 }
653
654 old_midi_volume = _midi_volume;
655 }
656
657 static END_OF_FUNCTION(update_controllers);
658
659
660
661 /* process_controller:
662 * Deals with a MIDI controller message on the specified channel.
663 */
process_controller(int channel,int ctrl,int data)664 static void process_controller(int channel, int ctrl, int data)
665 {
666 switch (ctrl) {
667
668 case 7: /* main volume */
669 midi_channel[channel].new_volume = data+1;
670 break;
671
672 case 10: /* pan */
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);
678 }
679 break;
680
681 case 121: /* reset all controllers */
682 reset_controllers(channel);
683 break;
684
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);
691 break;
692 }
693 }
694
695 static END_OF_FUNCTION(process_controller);
696
697
698
699 /* process_meta_event:
700 * Processes the next meta-event on the specified track.
701 */
process_meta_event(unsigned char ** pos,long * timer)702 static void process_meta_event(unsigned char **pos, long *timer)
703 {
704 unsigned char metatype = *((*pos)++);
705 long length = parse_var_len(pos);
706 long tempo;
707
708 if (midi_meta_callback)
709 midi_meta_callback(metatype, *pos, length);
710
711 if (metatype == 0x2F) { /* end of track */
712 *pos = NULL;
713 *timer = LONG_MAX;
714 return;
715 }
716
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;
721 }
722
723 (*pos) += length;
724 }
725
726 static END_OF_FUNCTION(process_meta_event);
727
728
729
730 /* process_midi_event:
731 * Processes the next MIDI event on the specified track.
732 */
process_midi_event(unsigned char ** pos,unsigned char * running_status,long * timer)733 static void process_midi_event(unsigned char **pos, unsigned char *running_status, long *timer)
734 {
735 unsigned char byte1, byte2;
736 int channel;
737 unsigned char event;
738 long l;
739
740 event = *((*pos)++);
741
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;
746 byte1 = (*pos)[0];
747 byte2 = (*pos)[1];
748 }
749 else { /* use running status */
750 byte1 = event;
751 byte2 = (*pos)[0];
752 event = *running_status;
753 (*pos)--;
754 }
755
756 /* program callback? */
757 if ((midi_msg_callback) &&
758 (event != 0xF0) && (event != 0xF7) && (event != 0xFF))
759 midi_msg_callback(event, byte1, byte2);
760
761 channel = event & 0x0F;
762
763 switch (event>>4) {
764
765 case 0x08: /* note off */
766 midi_note_off(channel, byte1);
767 (*pos) += 2;
768 break;
769
770 case 0x09: /* note on */
771 midi_note_on(channel, byte1, byte2, 1);
772 (*pos) += 2;
773 break;
774
775 case 0x0A: /* note aftertouch */
776 (*pos) += 2;
777 break;
778
779 case 0x0B: /* control change */
780 process_controller(channel, byte1, byte2);
781 (*pos) += 2;
782 break;
783
784 case 0x0C: /* program change */
785 midi_channel[channel].patch = byte1;
786 if (midi_driver->raw_midi)
787 raw_program_change(channel, byte1);
788 (*pos) += 1;
789 break;
790
791 case 0x0D: /* channel aftertouch */
792 (*pos) += 1;
793 break;
794
795 case 0x0E: /* pitch bend */
796 midi_channel[channel].new_pitch_bend = byte1 + (byte2<<7);
797 (*pos) += 2;
798 break;
799
800 case 0x0F: /* special event */
801 switch (event) {
802 case 0xF0: /* sysex */
803 case 0xF7:
804 l = parse_var_len(pos);
805 if (midi_sysex_callback)
806 midi_sysex_callback(*pos, l);
807 (*pos) += l;
808 break;
809
810 case 0xF2: /* song position */
811 (*pos) += 2;
812 break;
813
814 case 0xF3: /* song select */
815 (*pos)++;
816 break;
817
818 case 0xFF: /* meta-event */
819 process_meta_event(pos, timer);
820 break;
821
822 default:
823 /* the other special events don't have any data bytes,
824 so we don't need to bother skipping past them */
825 break;
826 }
827 break;
828
829 default:
830 /* something has gone badly wrong if we ever get to here */
831 break;
832 }
833 }
834
835 static END_OF_FUNCTION(process_midi_event);
836
837
838
839 /* midi_player:
840 * The core MIDI player: to be used as a timer callback.
841 */
midi_player()842 static void midi_player()
843 {
844 int c;
845 long l;
846 int active;
847
848 if (!midifile)
849 return;
850
851 if (midi_semaphore) {
852 midi_timer_speed += BPS_TO_TIMER(40);
853 install_int_ex(midi_player, BPS_TO_TIMER(40));
854 return;
855 }
856
857 midi_semaphore = TRUE;
858 _midi_tick++;
859
860 do_it_all_again:
861
862 for (c=0; c<MIDI_VOICES; c++)
863 midi_waiting[c].note = -1;
864
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;
869
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);
875
876 /* read next time offset */
877 if (midi_track[c].pos) {
878 l = parse_var_len(&midi_track[c].pos);
879 l *= midi_speed;
880 midi_track[c].timer += l;
881 }
882 }
883 }
884 }
885
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;
890 midi_pos++;
891 }
892
893 /* tempo change? */
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;
899 }
900 }
901 midi_pos_counter /= midi_speed;
902 midi_pos_counter *= midi_new_speed;
903
904 midi_speed = midi_new_speed;
905 midi_pos_speed = midi_new_speed * midifile->divisions;
906 midi_new_speed = -1;
907 }
908
909 /* figure out how long until we need to be called again */
910 active = 0;
911 midi_timer_speed = LONG_MAX;
912 for (c=0; c<MIDI_TRACKS; c++) {
913 if (midi_track[c].pos) {
914 active = 1;
915 if (midi_track[c].timer < midi_timer_speed)
916 midi_timer_speed = midi_track[c].timer;
917 }
918 }
919
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;
926 midi_looping = TRUE;
927 if (midi_seek(midi_loop_start) != 0) {
928 midi_looping = FALSE;
929 stop_midi();
930 return;
931 }
932 midi_looping = FALSE;
933 midi_semaphore = TRUE;
934 goto do_it_all_again;
935 }
936 else {
937 for (c=0; c<16; c++)
938 all_notes_off(c);
939 prepare_to_play(midifile);
940 goto do_it_all_again;
941 }
942 }
943 else {
944 stop_midi();
945 midi_semaphore = FALSE;
946 return;
947 }
948 }
949
950 /* reprogram the timer */
951 if (midi_timer_speed < BPS_TO_TIMER(40))
952 midi_timer_speed = BPS_TO_TIMER(40);
953
954 if (!midi_seeking)
955 install_int_ex(midi_player, midi_timer_speed);
956
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();
960
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);
966
967 midi_semaphore = FALSE;
968 }
969
970 static END_OF_FUNCTION(midi_player);
971
972
973
974 /* midi_init:
975 * Sets up the MIDI player ready for use. Returns non-zero on failure.
976 */
midi_init()977 static int midi_init()
978 {
979 int c, c2, c3;
980 int argc;
981 char **argv;
982 char buf[16];
983
984 midi_loaded_patches = FALSE;
985
986 midi_lock_mem();
987
988 for (c=0; c<16; c++) {
989 midi_channel[c].volume = 128;
990 midi_channel[c].pitch_bend = 0x2000;
991
992 for (c2=0; c2<128; c2++)
993 for (c3=0; c3<MIDI_LAYERS; c3++)
994 midi_channel[c].note[c2][c3] = -1;
995 }
996
997 for (c=0; c<MIDI_VOICES; c++) {
998 midi_voice[c].note = -1;
999 midi_voice[c].time = 0;
1000 }
1001
1002 for (c=0; c<128; c++) {
1003 sprintf(buf, "p%d", c+1);
1004 argv = get_config_argv("midimap", buf, &argc);
1005
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]);
1011 }
1012 else {
1013 patch_table[c].bank1 = -1;
1014 patch_table[c].bank2 = -1;
1015 patch_table[c].prog = c;
1016 patch_table[c].pitch = 0;
1017 }
1018 }
1019
1020 /* register_datafile_object(DAT_MIDI, NULL, (void (*)(void *))destroy_midi);*/
1021
1022 return 0;
1023 }
1024
1025
1026
1027 /* midi_exit:
1028 * Turns off all active notes and removes the timer handler.
1029 */
midi_exit()1030 static void midi_exit()
1031 {
1032 stop_midi();
1033 }
1034
1035
1036
1037 /* load_patches:
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
1040 * neccessary.
1041 */
load_patches(MIDI * midi)1042 static int load_patches(MIDI *midi)
1043 {
1044 char patches[128], drums[128];
1045 unsigned char *p, *end;
1046 unsigned char running_status, event;
1047 long l;
1048 int c;
1049
1050 for (c=0; c<128; c++) /* initialise to unused */
1051 patches[c] = drums[c] = FALSE;
1052
1053 patches[0] = TRUE; /* always load the piano */
1054
1055 for (c=0; c<MIDI_TRACKS; c++) { /* for each track... */
1056 p = midi->track[c].data;
1057 end = p + midi->track[c].len;
1058 running_status = 0;
1059
1060 while (p < end) { /* work through data stream */
1061 event = *p;
1062 if (event & 0x80) { /* regular message */
1063 p++;
1064 if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF))
1065 running_status = event;
1066 }
1067 else /* use running status */
1068 event = running_status;
1069
1070 switch (event>>4) {
1071
1072 case 0x0C: /* program change! */
1073 patches[*p] = TRUE;
1074 p++;
1075 break;
1076
1077 case 0x09: /* note on, is it a drum? */
1078 if ((event & 0x0F) == 9)
1079 drums[*p] = TRUE;
1080 p += 2;
1081 break;
1082
1083 case 0x08: /* note off */
1084 case 0x0A: /* note aftertouch */
1085 case 0x0B: /* control change */
1086 case 0x0E: /* pitch bend */
1087 p += 2;
1088 break;
1089
1090 case 0x0D: /* channel aftertouch */
1091 p += 1;
1092 break;
1093
1094 case 0x0F: /* special event */
1095 switch (event) {
1096 case 0xF0: /* sysex */
1097 case 0xF7:
1098 l = parse_var_len(&p);
1099 p += l;
1100 break;
1101
1102 case 0xF2: /* song position */
1103 p += 2;
1104 break;
1105
1106 case 0xF3: /* song select */
1107 p++;
1108 break;
1109
1110 case 0xFF: /* meta-event */
1111 p++;
1112 l = parse_var_len(&p);
1113 p += l;
1114 break;
1115
1116 default:
1117 /* the other special events don't have any data bytes,
1118 so we don't need to bother skipping past them */
1119 break;
1120 }
1121 break;
1122
1123 default:
1124 /* something has gone badly wrong if we ever get to here */
1125 break;
1126 }
1127
1128 if (p < end) /* skip time offset */
1129 parse_var_len(&p);
1130 }
1131 }
1132
1133 /* tell the driver to do its stuff */
1134 return midi_driver->load_patches(patches, drums);
1135 }
1136
1137
1138
1139 /* prepare_to_play:
1140 * Sets up all the global variables needed to play the specified file.
1141 */
prepare_to_play(MIDI * midi)1142 static void prepare_to_play(MIDI *midi)
1143 {
1144 int c;
1145
1146 for (c=0; c<16; c++)
1147 reset_controllers(c);
1148
1149 update_controllers();
1150
1151 midifile = midi;
1152 midi_pos = 0;
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;
1158 midi_seeking = 0;
1159 midi_looping = 0;
1160
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);
1165 }
1166
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;
1172 }
1173 else {
1174 midi_track[c].pos = NULL;
1175 midi_track[c].timer = LONG_MAX;
1176 }
1177 midi_track[c].running_status = 0;
1178 }
1179 }
1180
1181 static END_OF_FUNCTION(prepare_to_play);
1182
1183
1184
1185 /* play_midi:
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).
1193 */
play_midi(MIDI * midi,int loop)1194 int play_midi(MIDI *midi, int loop)
1195 {
1196 int c;
1197
1198 remove_int(midi_player);
1199
1200 for (c=0; c<16; c++)
1201 all_notes_off(c);
1202
1203 if (midi) {
1204 if (!midi_loaded_patches)
1205 if (load_patches(midi) != 0)
1206 return -1;
1207
1208 midi_loop = loop;
1209 midi_loop_start = -1;
1210 midi_loop_end = -1;
1211
1212 prepare_to_play(midi);
1213
1214 /* arbitrary speed, midi_player() will adjust it */
1215 install_int(midi_player, 20);
1216 }
1217 else {
1218 midifile = NULL;
1219 midi_pos = -1;
1220 }
1221
1222 return 0;
1223 }
1224
1225 END_OF_FUNCTION(play_midi);
1226
1227
1228
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).
1233 */
play_looped_midi(MIDI * midi,int loop_start,int loop_end)1234 int play_looped_midi(MIDI *midi, int loop_start, int loop_end)
1235 {
1236 if (play_midi(midi, TRUE) != 0)
1237 return -1;
1238
1239 midi_loop_start = loop_start;
1240 midi_loop_end = loop_end;
1241
1242 return 0;
1243 }
1244
1245
1246
1247 /* stop_midi:
1248 * Stops whatever MIDI file is currently playing.
1249 */
stop_midi()1250 void stop_midi()
1251 {
1252 play_midi(NULL, FALSE);
1253 }
1254
1255 END_OF_FUNCTION(stop_midi);
1256
1257
1258
1259 /* midi_pause:
1260 * Pauses the currently playing MIDI file.
1261 */
midi_pause()1262 void midi_pause()
1263 {
1264 int c;
1265
1266 if (!midifile)
1267 return;
1268
1269 remove_int(midi_player);
1270
1271 for (c=0; c<16; c++)
1272 all_notes_off(c);
1273 }
1274
1275 END_OF_FUNCTION(midi_pause);
1276
1277
1278
1279 /* midi_resume:
1280 * Resumes playing a paused MIDI file.
1281 */
midi_resume()1282 void midi_resume()
1283 {
1284 if (!midifile)
1285 return;
1286
1287 install_int_ex(midi_player, midi_timer_speed);
1288 }
1289
1290 END_OF_FUNCTION(midi_resume);
1291
1292
1293
1294 /* midi_seek:
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).
1300 */
midi_seek(int target)1301 int midi_seek(int target)
1302 {
1303 int old_midi_loop;
1304 MIDI *old_midifile;
1305 MIDI_DRIVER *old_driver;
1306 int old_patch[16];
1307 int old_volume[16];
1308 int old_pan[16];
1309 int old_pitch_bend[16];
1310 int c;
1311
1312 if (!midifile)
1313 return -1;
1314
1315 /* first stop the player */
1316 midi_pause();
1317
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;
1324 }
1325
1326 /* save some variables and give temporary values */
1327 old_driver = midi_driver;
1328 midi_driver = &midi_none;
1329 old_midi_loop = midi_loop;
1330 midi_loop = 0;
1331 old_midifile = midifile;
1332
1333 /* set flag to tell midi_player not to reinstall itself */
1334 midi_seeking = 1;
1335
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);
1339
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;
1343 int mmp = midi_pos;
1344
1345 mmpc -= midi_timer_speed;
1346 while (mmpc <= 0) {
1347 mmpc += midi_pos_speed;
1348 mmp++;
1349 }
1350
1351 if (mmp >= target)
1352 break;
1353
1354 midi_player();
1355 }
1356
1357 /* restore previously saved variables */
1358 midi_loop = old_midi_loop;
1359 midi_driver = old_driver;
1360 midi_seeking = 0;
1361
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);
1370
1371 /* pan */
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);
1376 }
1377
1378 /* pitch bend */
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);
1383 }
1384 }
1385 }
1386
1387 /* if we didn't hit the end of the file, continue playing */
1388 if (!midi_looping)
1389 install_int(midi_player, 20);
1390
1391 return 0;
1392 }
1393
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 */
1398 }
1399
1400 return 1; /* seek past EOF => file stopped */
1401 }
1402
1403 END_OF_FUNCTION(midi_seek);
1404
1405
1406
1407 /* midi_out:
1408 * Inserts MIDI command bytes into the output stream, in realtime.
1409 */
midi_out(unsigned char * data,int length)1410 void midi_out(unsigned char *data, int length)
1411 {
1412 unsigned char *pos = data;
1413 unsigned char running_status = 0;
1414 long timer = 0;
1415
1416 midi_semaphore = TRUE;
1417 _midi_tick++;
1418
1419 while (pos < data+length)
1420 process_midi_event(&pos, &running_status, &timer);
1421
1422 midi_semaphore = FALSE;
1423 }
1424
1425
1426
1427 /* load_midi_patches:
1428 * Tells the MIDI driver to preload the entire sample set.
1429 */
load_midi_patches()1430 int load_midi_patches()
1431 {
1432 char patches[128], drums[128];
1433 int c, ret;
1434
1435 for (c=0; c<128; c++)
1436 patches[c] = drums[c] = TRUE;
1437
1438 midi_semaphore = TRUE;
1439 ret = midi_driver->load_patches(patches, drums);
1440 midi_semaphore = FALSE;
1441
1442 midi_loaded_patches = TRUE;
1443
1444 return ret;
1445 }
1446
1447
1448
1449 /* midi_lock_mem:
1450 * Locks all the memory that the midi player touches inside the timer
1451 * interrupt handler (which is most of it).
1452 */
midi_lock_mem()1453 static void midi_lock_mem()
1454 {
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);
1499 }
1500
1501
1502
1503 /* midi_constructor:
1504 * Register my functions with the code in sound.c.
1505 */
1506 static void midi_constructor() __attribute__ ((constructor));
midi_constructor()1507 static void midi_constructor()
1508 {
1509 _midi_init = midi_init;
1510 _midi_exit = midi_exit;
1511 }
1512
1513