1 /*
2 * midifile 1.11
3 *
4 * Read and write a MIDI file. Externally-assigned function pointers are
5 * called upon recognizing things in the file.
6 *
7 * Original release ?
8 * June 1989 - Added writing capability, M. Czeiszperger.
9 *
10 * The file format implemented here is called
11 * Standard MIDI Files, and is part of the Musical
12 * instrument Digital Interface specification.
13 * The spec is available from:
14 *
15 * International MIDI Association
16 * 5316 West 57th Street
17 * Los Angeles, CA 90056
18 *
19 * An in-depth description of the spec can also be found
20 * in the article "Introducing Standard MIDI Files", published
21 * in Electronic Musician magazine, April, 1989.
22 *
23 * February 1993 - Minor adjustments, Greg Lee:
24 * (1) can now set the global variable Mf_interactive to 1 to prevent the
25 * reading functions from looking for file and track headers
26 * (2) can now write system exclusive data with
27 * mf_write_midi_event(delta_time, system_exclusive, 0, data, size)
28 * (3) changed definition of 'sequencer_specific' in midifile.h to 0x7f
29 * (4) changed mf_write_tempo to take additional delta_time as first argument
30 * (since delta need not be zero)
31 * (5) added function mf_write_seqnum(unsigned long delta_time, unsigned seqnum)
32 * (6) changed mf_write_midi_event to use running status
33 * (7) removed the code to write an end of track meta event automatically
34 * -- this must now be done by the user of the library (I changed
35 * it because I need to be able to control the time delta of this
36 * meta event)
37 * (8) added global variables Mf_division, Mf_currtempo, Mf_realtime, which
38 * are updated by the reading functions. Mf_realtime is useful,
39 * because Mf_currtime does not really measure time at all, since
40 * its units change value at every tempo change. Mf_realtime is
41 * the midi-time elapsed in units of 1/16 of a centisecond (but it
42 * does not handle SMPTE times)
43 * (9) maintains a history of tempo settings to update Mf_currtempo,
44 * to handle tempo tracks.
45 * (10) if there is an Mf_error function, the error routine no longer
46 * exits, leaving it to the application to do this.
47 * (11) chanmessage skips over invalid c1 command bytes > 127 and
48 * adjusts invalid c2 argument byte > 127 to 127.
49 * (12) readmt returns EOF when it encounters a 0 or 0x1a byte instead of an expected
50 * header string (some midi files have padding at end).
51 */
52 #define NO_LC_DEFINES
53 #include "midifile.h"
54 #ifdef NO_LC_DEFINES
55 #define system_exclusive 0xf0
56 #define meta_event 0xFF
57 #define set_tempo 0x51
58 #define lowerbyte(x) ((unsigned char)(x & 0xff))
59 #define upperbyte(x) ((unsigned char)((x & 0xff00)>>8))
60 #endif
61
62 #define NULLFUNC 0
63 #if 0
64 #define NULL 0
65 #endif
66
67 #define THINK
68
69 #ifdef THINK
70 #include <stdlib.h>
71 #endif
72
73 #include <stdio.h>
74 #include <values.h>
75
76 #include <string.h>
77 /*void exit(), free();*/
78
79 /* public stuff */
80
81 /* Functions to be called while processing the MIDI file. */
82 int (*Mf_getc) () = NULLFUNC;
83 void (*Mf_error) () = NULLFUNC;
84 void (*Mf_header) () = NULLFUNC;
85 void (*Mf_trackstart) () = NULLFUNC;
86 void (*Mf_trackend) () = NULLFUNC;
87 void (*Mf_noteon) () = NULLFUNC;
88 void (*Mf_noteoff) () = NULLFUNC;
89 void (*Mf_pressure) () = NULLFUNC;
90 void (*Mf_parameter) () = NULLFUNC;
91 void (*Mf_pitchbend) () = NULLFUNC;
92 void (*Mf_program) () = NULLFUNC;
93 void (*Mf_chanpressure) () = NULLFUNC;
94 void (*Mf_sysex) () = NULLFUNC;
95 void (*Mf_arbitrary) () = NULLFUNC;
96 void (*Mf_metamisc) () = NULLFUNC;
97 void (*Mf_seqnum) () = NULLFUNC;
98 void (*Mf_eot) () = NULLFUNC;
99 void (*Mf_smpte) () = NULLFUNC;
100 void (*Mf_tempo) () = NULLFUNC;
101 void (*Mf_timesig) () = NULLFUNC;
102 void (*Mf_keysig) () = NULLFUNC;
103 void (*Mf_seqspecific) () = NULLFUNC;
104 void (*Mf_text) () = NULLFUNC;
105
106 /* Functions to implement in order to write a MIDI file */
107 int (*Mf_putc) () = NULLFUNC;
108 int (*Mf_writetrack) () = NULLFUNC;
109 int (*Mf_writetempotrack) () = NULLFUNC;
110
111 int Mf_nomerge = 0; /* 1 => continue'ed system exclusives are */
112 /* not collapsed. */
113 int Mf_interactive = 0; /* 1 => file and track headers are not required */
114 unsigned long Mf_currtime = 0L; /* current time in delta-time units */
115 unsigned long Mf_realtime = 0L; /* current time in 1/16 centisecond-time units */
116 static double Mf_f_realtime = 0;/* as above, floating */
117 static double old_f_realtime = 0;
118 int Mf_division = 96;
119 unsigned long Mf_currtempo = 500000;
120 static unsigned long old_currtempo = 500000;
121 static unsigned long old_realtime = 0;
122 static unsigned long old_currtime = 0;
123 static unsigned long revised_time = 0;
124 static unsigned long tempo_change_time = 0;
125
126 #define MAX_HISTORY 512
127 static unsigned long tempo_history[MAX_HISTORY];
128 static unsigned long tempo_history_time[MAX_HISTORY];
129 static int tempo_history_count = 0;
130
131 /* private stuff */
132 static long Mf_toberead = 0L;
133 static long Mf_numbyteswritten = 0L;
134
135 static long readvarinum ();
136 static long read32bit ();
137 static long to32bit ();
138 static int read16bit ();
139 static int to16bit ();
140 static char *msg ();
141 static void readheader ();
142 static int readtrack ();
143 static void badbyte ();
144 static void metaevent ();
145 static void sysex ();
146 static void chanmessage ();
147 static void msginit ();
148 static int msgleng ();
149 static void msgadd ();
150 static void biggermsg ();
151 static int eputc (unsigned char c);
152
153 double mf_ticks2sec (unsigned long ticks, int division, unsigned long tempo);
154 int mf_write_meta_event ();
155 void mf_write_tempo ();
156 void mf_write_seqnum ();
157 void WriteVarLen ();
158
159 #ifdef READ_MODS
160 #include "mp_mod.c"
161 static int mod_file_flag = 0;
162 #endif /* READ_MODS */
163 static int force_exit;
164
165 void
mfread()166 mfread ()
167 {
168 force_exit = 0;
169 if (Mf_getc == NULLFUNC)
170 mferror ("mfread() called without setting Mf_getc");
171
172 readheader ();
173 #ifdef READ_MODS
174 if (mod_file_flag)
175 do_module();
176 else
177 #endif
178 while (readtrack () && !force_exit)
179 ;
180 }
181
182 /* for backward compatibility with the original lib */
183 void
midifile()184 midifile ()
185 {
186 mfread ();
187 }
188
189 static
190 int
readmt(s)191 readmt (s) /* read through the "MThd" or "MTrk" header string */
192 char *s;
193 {
194 int n = 0;
195 char *p = s;
196 int c;
197
198 while (n++ < 4 && (c = (*Mf_getc) ()) != EOF)
199 {
200 if (c != *p++)
201 {
202 char buff[32];
203 if (!c) return(EOF);
204 if (c == 0x1a) return(EOF);
205 (void) strcpy (buff, "expecting ");
206 (void) strcat (buff, s);
207 mferror (buff);
208 break;
209 }
210 }
211 return (c);
212 }
213
214 static
215 int
egetc()216 egetc () /* read a single character and abort on EOF */
217 {
218 int c = (*Mf_getc) ();
219
220 if (c == EOF) {
221 mferror ("premature EOF");
222 force_exit = 1;
223 }
224 Mf_toberead--;
225 return (c);
226 }
227
228 static
229 void
readheader()230 readheader () /* read a header chunk */
231 {
232 int format, ntrks, division;
233
234
235 Mf_division = 96;
236 Mf_currtempo = 500000;
237 old_currtempo = 500000;
238 tempo_history_count = 0;
239 tempo_history[tempo_history_count] = Mf_currtempo;
240 tempo_history_time[tempo_history_count] = 0;
241
242 if (Mf_interactive)
243 {
244 Mf_toberead = 0;
245 format = 0;
246 ntrks = 1;
247 division = 96;
248 }
249 else
250 #ifdef READ_MODS
251 if (!strncmp(Mf_file_contents, "MThd", 4))
252 #endif
253 {
254 if (readmt ("MThd") == EOF)
255 return;
256
257 Mf_toberead = read32bit ();
258 format = read16bit ();
259 ntrks = read16bit ();
260 Mf_division = division = read16bit ();
261 }
262 #ifdef READ_MODS
263 else
264 {
265 format = 0;
266 ntrks = 1;
267 division = Mf_division;
268 Mf_toberead = 0;
269 mod_file_flag = 1;
270 }
271 #endif
272
273 if (Mf_header)
274 (*Mf_header) (format, ntrks, division);
275
276 /* flush any extra stuff, in case the length of header is not 6 */
277 while (Mf_toberead > 0 && !force_exit)
278 (void) egetc ();
279 }
280
281
282 /*#define DEBUG_TIMES*/
283 static
284 unsigned long
find_tempo()285 find_tempo()
286 {
287 int i;
288 unsigned long old_tempo = Mf_currtempo;
289 unsigned long new_tempo = Mf_currtempo;
290
291 for (i = 0; i <= tempo_history_count; i++) {
292 if (tempo_history_time[i] <= Mf_currtime) old_tempo = tempo_history[i];
293 new_tempo = tempo_history[i];
294 if (tempo_history_time[i] > revised_time) break;
295 }
296 if (i > tempo_history_count || tempo_history_time[i] > Mf_currtime) {
297 #ifdef DEBUG_TIMES
298 printf("[past %lu, old_tempo %lu]\n", tempo_history_time[i], old_tempo);
299 #endif
300 revised_time = Mf_currtime;
301 return(old_tempo);
302 }
303 tempo_change_time = revised_time = tempo_history_time[i];
304 #ifdef DEBUG_TIMES
305 printf("[revised_time %lu, new_tempo %lu]\n", revised_time, new_tempo);
306 #endif
307 return(new_tempo);
308 }
309
310 static
311 int
readtrack()312 readtrack () /* read a track chunk */
313 {
314 /* This array is indexed by the high half of a status byte. It's */
315 /* value is either the number of bytes needed (1 or 2) for a channel */
316 /* message, or 0 (meaning it's not a channel message). */
317 static int chantype[] =
318 {
319 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 through 0x70 */
320 2, 2, 2, 2, 1, 1, 2, 0 /* 0x80 through 0xf0 */
321 };
322 long lookfor;
323 int c, c1, type;
324 int sysexcontinue = 0; /* 1 if last message was an unfinished sysex */
325 int running = 0; /* 1 when running status used */
326 int status = 0; /* status value (e.g. 0x90==note-on) */
327 int needed;
328
329 if (Mf_interactive)
330 {
331 Mf_toberead = MAXINT;
332 }
333 else
334 {
335 if (readmt ("MTrk") == EOF)
336 return (0);
337
338 Mf_toberead = read32bit ();
339 }
340 Mf_currtime = Mf_realtime = 0;
341 Mf_f_realtime = old_f_realtime = 0;
342 old_currtime = old_realtime = 0;
343 Mf_currtempo = find_tempo();
344
345 if (Mf_trackstart)
346 (*Mf_trackstart) ();
347
348 while (!force_exit && (Mf_interactive || Mf_toberead > 0))
349 {
350
351 if (Mf_interactive)
352 Mf_currtime += 1;
353 else
354 {
355 double delta_secs;
356 unsigned long delta_ticks = readvarinum ();
357 revised_time = Mf_currtime;
358 Mf_currtime += delta_ticks; /* delta time */
359
360 /*
361 * Step through each tempo change from old_currtime up to now,
362 * revising Mf_realtime after each change.
363 */
364
365 while (revised_time < Mf_currtime) {
366 unsigned long save_time = revised_time;
367 unsigned long save_tempo = Mf_currtempo;
368 Mf_currtempo = find_tempo();
369
370 if (Mf_currtempo != old_currtempo) {
371 old_currtempo = Mf_currtempo;
372 old_realtime = Mf_realtime;
373 if (revised_time != tempo_change_time) {
374 old_f_realtime = Mf_f_realtime;
375 old_currtime = save_time;
376 }
377 delta_secs = mf_ticks2sec (revised_time-old_currtime, Mf_division, save_tempo);
378 #ifdef DEBUG_TIMES
379 printf("d(rev %lu - old %lu, div %d, tempo %lu) = %.3f\n",
380 revised_time, old_currtime, Mf_division, save_tempo, delta_secs * 1600.0);
381 #endif
382 Mf_f_realtime = old_f_realtime + delta_secs * 1600.0;
383 Mf_realtime = (unsigned long)(0.5 + Mf_f_realtime);
384 #ifdef DEBUG_TIMES
385 printf("\tt=%lu ticks ( = %lu csec/16 < old %.2f + %.2f)\n", Mf_currtime, Mf_realtime,
386 old_f_realtime, delta_secs * 1600.0);
387 #endif
388 if (revised_time == tempo_change_time) {
389 old_currtime = revised_time;
390 old_f_realtime = Mf_f_realtime;
391 }
392 }
393 else {
394 delta_secs = mf_ticks2sec (revised_time-old_currtime, Mf_division, Mf_currtempo);
395 #ifdef DEBUG_TIMES
396 printf("d(rev %lu - old %lu, div %d, tempo %lu) = %.3f\n",
397 revised_time, old_currtime, Mf_division, Mf_currtempo, delta_secs * 1600.0);
398 #endif
399 Mf_f_realtime = old_f_realtime + delta_secs * 1600.0;
400 Mf_realtime = (unsigned long)(0.5 + Mf_f_realtime);
401 #ifdef DEBUG_TIMES
402 printf("\tt=%lu ticks ( = %lu csec/16 < old %.2f + %.2f)\n", Mf_currtime, Mf_realtime,
403 old_f_realtime, delta_secs * 1600.0);
404 #endif
405 }
406
407
408 }
409 }
410
411 c = egetc ();
412
413 if (sysexcontinue && c != 0xf7)
414 mferror ("didn't find expected continuation of a sysex");
415
416 if ((c & 0x80) == 0)
417 { /* running status? */
418 if (status == 0)
419 mferror ("unexpected running status");
420 running = 1;
421 }
422 else
423 {
424 status = c;
425 running = 0;
426 }
427
428 needed = chantype[(status >> 4) & 0xf];
429
430 if (needed)
431 { /* ie. is it a channel message? */
432
433 if (running)
434 c1 = c;
435 else
436 c1 = egetc ();
437 chanmessage (status, c1, (needed > 1) ? egetc () : 0);
438 continue;;
439 }
440
441 switch (c)
442 {
443
444 case 0xff: /* meta event */
445
446 type = egetc ();
447 lookfor = Mf_toberead - readvarinum ();
448 msginit ();
449
450 while (Mf_toberead > lookfor)
451 msgadd (egetc ());
452
453 metaevent (type);
454 break;
455
456 case 0xf0: /* start of system exclusive */
457
458 lookfor = Mf_toberead - readvarinum ();
459 msginit ();
460 msgadd (0xf0);
461
462 while (Mf_toberead > lookfor)
463 msgadd (c = egetc ());
464
465 if (c == 0xf7 || Mf_nomerge == 0)
466 sysex ();
467 else
468 sysexcontinue = 1; /* merge into next msg */
469 break;
470
471 case 0xf7: /* sysex continuation or arbitrary stuff */
472
473 lookfor = Mf_toberead - readvarinum ();
474
475 if (!sysexcontinue)
476 msginit ();
477
478 while (Mf_toberead > lookfor)
479 msgadd (c = egetc ());
480
481 if (!sysexcontinue)
482 {
483 if (Mf_arbitrary)
484 (*Mf_arbitrary) (msgleng (), msg ());
485 }
486 else if (c == 0xf7)
487 {
488 sysex ();
489 sysexcontinue = 0;
490 }
491 break;
492 default:
493 badbyte (c);
494 break;
495 }
496 }
497 if (Mf_trackend)
498 (*Mf_trackend) ();
499 return (1);
500 }
501
502 static
503 void
badbyte(c)504 badbyte (c)
505 int c;
506 {
507 char buff[32];
508
509 (void) sprintf (buff, "unexpected byte: 0x%02x", c);
510 mferror (buff);
511 }
512
513 static
514 void
metaevent(int type)515 metaevent (int type)
516 {
517 int leng = msgleng ();
518 char *m = msg ();
519
520 switch (type)
521 {
522 case 0x00:
523 if (Mf_seqnum)
524 (*Mf_seqnum) (to16bit (m[0], m[1]));
525 break;
526 case 0x01: /* Text event */
527 case 0x02: /* Copyright notice */
528 case 0x03: /* Sequence/Track name */
529 case 0x04: /* Instrument name */
530 case 0x05: /* Lyric */
531 case 0x06: /* Marker */
532 case 0x07: /* Cue point */
533 case 0x08:
534 case 0x09:
535 case 0x0a:
536 case 0x0b:
537 case 0x0c:
538 case 0x0d:
539 case 0x0e:
540 case 0x0f:
541 /* These are all text events */
542 if (Mf_text)
543 (*Mf_text) (type, leng, m);
544 break;
545 case 0x2f: /* End of Track */
546 if (Mf_eot)
547 (*Mf_eot) ();
548 break;
549 case 0x51: /* Set tempo */
550 if (Mf_tempo)
551 (*Mf_tempo) (Mf_currtempo = to32bit (0, m[0], m[1], m[2]));
552 if (tempo_history[tempo_history_count] == Mf_currtempo) break;
553 if (tempo_history_time[tempo_history_count] > Mf_currtime) break;
554 if (tempo_history_count < MAX_HISTORY - 1) tempo_history_count++;
555 tempo_history[tempo_history_count] = Mf_currtempo;
556 tempo_history_time[tempo_history_count] = Mf_currtime;
557 break;
558 case 0x54:
559 if (Mf_smpte)
560 (*Mf_smpte) (m[0], m[1], m[2], m[3], m[4]);
561 break;
562 case 0x58:
563 if (Mf_timesig)
564 (*Mf_timesig) (m[0], m[1], m[2], m[3]);
565 break;
566 case 0x59:
567 if (Mf_keysig)
568 (*Mf_keysig) (m[0], m[1]);
569 break;
570 case 0x7f:
571 if (Mf_seqspecific)
572 (*Mf_seqspecific) (leng, m);
573 break;
574 default:
575 if (Mf_metamisc)
576 (*Mf_metamisc) (type, leng, m);
577 }
578 }
579
580 static
581 void
sysex()582 sysex ()
583 {
584 if (Mf_sysex)
585 (*Mf_sysex) (msgleng (), msg ());
586 }
587
588 static
589 void
chanmessage(status,c1,c2)590 chanmessage (status, c1, c2)
591 int status;
592 int c1, c2;
593 {
594 int chan = status & 0xf;
595
596 /* I found a midi file with Mod Wheel values 128. --gl */
597
598 if (c1 > 127) /*mferror("chanmessage: bad c1") ??*/ return;
599 if (c2 > 127) c2 = 127;
600
601 switch (status & 0xf0)
602 {
603 case 0x80:
604 if (Mf_noteoff)
605 (*Mf_noteoff) (chan, c1, c2);
606 break;
607 case 0x90:
608 if (Mf_noteon)
609 (*Mf_noteon) (chan, c1, c2);
610 break;
611 case 0xa0:
612 if (Mf_pressure)
613 (*Mf_pressure) (chan, c1, c2);
614 break;
615 case 0xb0:
616 if (Mf_parameter)
617 (*Mf_parameter) (chan, c1, c2);
618 break;
619 case 0xe0:
620 if (Mf_pitchbend)
621 (*Mf_pitchbend) (chan, c1, c2);
622 break;
623 case 0xc0:
624 if (Mf_program)
625 (*Mf_program) (chan, c1);
626 break;
627 case 0xd0:
628 if (Mf_chanpressure)
629 (*Mf_chanpressure) (chan, c1);
630 break;
631 }
632 }
633
634 /* readvarinum - read a varying-length number, and return the */
635 /* number of characters it took. */
636
637 static long
readvarinum()638 readvarinum ()
639 {
640 long value;
641 int c;
642
643 c = egetc ();
644 value = c;
645 if (c & 0x80)
646 {
647 value &= 0x7f;
648 do
649 {
650 c = egetc ();
651 value = (value << 7) + (c & 0x7f);
652 }
653 while (c & 0x80);
654 }
655 return (value);
656 }
657
658 static long
to32bit(int c1,int c2,int c3,int c4)659 to32bit (int c1, int c2, int c3, int c4)
660 {
661 long value = 0L;
662
663 value = (c1 & 0xff);
664 value = (value << 8) + (c2 & 0xff);
665 value = (value << 8) + (c3 & 0xff);
666 value = (value << 8) + (c4 & 0xff);
667 return (value);
668 }
669
670 static int
to16bit(c1,c2)671 to16bit (c1, c2)
672 int c1, c2;
673 {
674 return ((c1 & 0xff) << 8) + (c2 & 0xff);
675 }
676
677 static long
read32bit()678 read32bit ()
679 {
680 int c1, c2, c3, c4;
681
682 c1 = egetc ();
683 c2 = egetc ();
684 c3 = egetc ();
685 c4 = egetc ();
686 return to32bit (c1, c2, c3, c4);
687 }
688
689 static int
read16bit()690 read16bit ()
691 {
692 int c1, c2;
693 c1 = egetc ();
694 c2 = egetc ();
695 return to16bit (c1, c2);
696 }
697
698 /* static */
699 void
mferror(s)700 mferror (s)
701 char *s;
702 {
703 if (Mf_error)
704 (*Mf_error) (s);
705 else exit (1);
706 }
707
708 /* The code below allows collection of a system exclusive message of */
709 /* arbitrary length. The Msgbuff is expanded as necessary. The only */
710 /* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
711
712 #define MSGINCREMENT 128
713 static char *Msgbuff = NULL; /* message buffer */
714 static int Msgsize = 0; /* Size of currently allocated Msg */
715 static int Msgindex = 0; /* index of next available location in Msg */
716
717 static
718 void
msginit()719 msginit ()
720 {
721 Msgindex = 0;
722 }
723
724 static char *
msg()725 msg ()
726 {
727 return (Msgbuff);
728 }
729
730 static
731 int
msgleng()732 msgleng ()
733 {
734 return (Msgindex);
735 }
736
737 static
738 void
msgadd(c)739 msgadd (c)
740 int c;
741 {
742 /* If necessary, allocate larger message buffer. */
743 if (Msgindex >= Msgsize)
744 biggermsg ();
745 Msgbuff[Msgindex++] = c;
746 }
747
748 static
749 void
biggermsg()750 biggermsg ()
751 {
752 /* char *malloc(); */
753 char *newmess;
754 char *oldmess = Msgbuff;
755 int oldleng = Msgsize;
756
757 Msgsize += MSGINCREMENT;
758 newmess = (char *) malloc ((unsigned) (sizeof (char) * Msgsize));
759
760 if (newmess == NULL)
761 mferror ("malloc error!");
762
763 /* copy old message into larger new one */
764 if (oldmess != NULL)
765 {
766 register char *p = newmess;
767 register char *q = oldmess;
768 register char *endq = &oldmess[oldleng];
769
770 for (; q != endq; p++, q++)
771 *p = *q;
772 free (oldmess);
773 }
774 Msgbuff = newmess;
775 }
776
777 static int laststatus = 0;
778
779 /*
780 * mfwrite() - The only function you'll need to call to write out
781 * a midi file.
782 *
783 * format 0 - Single multi-channel track
784 * 1 - Multiple simultaneous tracks
785 * 2 - One or more sequentially independent
786 * single track patterns
787 * ntracks The number of tracks in the file.
788 * division This is kind of tricky, it can represent two
789 * things, depending on whether it is positive or negative
790 * (bit 15 set or not). If bit 15 of division is zero,
791 * bits 14 through 0 represent the number of delta-time
792 * "ticks" which make up a quarter note. If bit 15 of
793 * division is a one, delta-times in a file correspond to
794 * subdivisions of a second similar to SMPTE and MIDI
795 * time code. In this format bits 14 through 8 contain
796 * one of four values - 24, -25, -29, or -30,
797 * corresponding to the four standard SMPTE and MIDI
798 * time code frame per second formats, where -29
799 * represents 30 drop frame. The second byte
800 * consisting of bits 7 through 0 corresponds the the
801 * resolution within a frame. Refer the Standard MIDI
802 * Files 1.0 spec for more details.
803 * fp This should be the open file pointer to the file you
804 * want to write. It will have be a global in order
805 * to work with Mf_putc.
806 */
807 void
mfwrite(format,ntracks,division,fp)808 mfwrite (format, ntracks, division, fp)
809 int format, ntracks, division;
810 FILE *fp;
811 {
812 int i;
813 void mf_write_track_chunk (), mf_write_header_chunk ();
814
815 if (Mf_putc == NULLFUNC)
816 mferror ("mfmf_write() called without setting Mf_putc");
817
818 if (Mf_writetrack == NULLFUNC)
819 mferror ("mfmf_write() called without setting Mf_mf_writetrack");
820
821 laststatus = 0;
822
823 /* every MIDI file starts with a header */
824 mf_write_header_chunk (format, ntracks, division);
825
826 laststatus = 0;
827
828 /* In format 1 files, the first track is a tempo map */
829 if (format == 1 && (Mf_writetempotrack))
830 {
831 (*Mf_writetempotrack) ();
832 }
833
834 /* The rest of the file is a series of tracks */
835 for (i = 0; i < ntracks; i++)
836 mf_write_track_chunk (i, fp);
837 }
838
839 void
mf_write_track_chunk(which_track,fp)840 mf_write_track_chunk (which_track, fp)
841 int which_track;
842 FILE *fp;
843 {
844 unsigned long trkhdr, trklength;
845 long offset, place_marker;
846 void write16bit (), write32bit ();
847
848
849 laststatus = 0;
850
851 trkhdr = MTrk;
852 trklength = 0;
853
854 /* Remember where the length was written, because we don't
855 know how long it will be until we've finished writing */
856 offset = ftell (fp);
857
858 #ifdef DEBUG
859 printf ("offset = %d\n", (int) offset);
860 #endif
861
862 /* Write the track chunk header */
863 write32bit (trkhdr);
864 write32bit (trklength);
865
866 Mf_numbyteswritten = 0L; /* the header's length doesn't count */
867
868 if (Mf_writetrack)
869 {
870 (*Mf_writetrack) (which_track);
871 }
872
873 /* mf_write End of track meta event */
874 /* but this does not necessarily have a delta of 0, so
875 * I don't want to do it -- leave it up to the user of the
876 * library functions to do
877 * --gl
878 eputc(0);
879 eputc(laststatus = meta_event);
880 eputc(end_of_track);
881
882 eputc(0);
883 */
884
885 /* It's impossible to know how long the track chunk will be beforehand,
886 so the position of the track length data is kept so that it can
887 be written after the chunk has been generated */
888 place_marker = ftell (fp);
889
890 /* This method turned out not to be portable because the
891 parameter returned from ftell is not guaranteed to be
892 in bytes on every machine */
893 /* track.length = place_marker - offset - (long) sizeof(track); */
894
895 #ifdef DEBUG
896 printf ("length = %d\n", (int) trklength);
897 #endif
898
899 if (fseek (fp, offset, 0) < 0)
900 mferror ("error seeking during final stage of write");
901
902 trklength = Mf_numbyteswritten;
903
904 /* Re-mf_write the track chunk header with right length */
905 write32bit (trkhdr);
906 write32bit (trklength);
907
908 fseek (fp, place_marker, 0);
909 } /* End gen_track_chunk() */
910
911
912 void
mf_write_header_chunk(format,ntracks,division)913 mf_write_header_chunk (format, ntracks, division)
914 int format, ntracks, division;
915 {
916 unsigned long ident, length;
917 void write16bit (), write32bit ();
918
919 ident = MThd; /* Head chunk identifier */
920 length = 6; /* Chunk length */
921
922 /* individual bytes of the header must be written separately
923 to preserve byte order across cpu types :-( */
924 write32bit (ident);
925 write32bit (length);
926 write16bit (format);
927 write16bit (ntracks);
928 write16bit (division);
929 } /* end gen_header_chunk() */
930
931
932 /*
933 * mf_write_midi_event()
934 *
935 * Library routine to mf_write a single MIDI track event in the standard MIDI
936 * file format. The format is:
937 *
938 * <delta-time><event>
939 *
940 * In this case, event can be any multi-byte midi message, such as
941 * "note on", "note off", etc.
942 *
943 * delta_time - the time in ticks since the last event.
944 * type - the type of meta event.
945 * chan - The midi channel.
946 * data - A pointer to a block of chars containing the META EVENT,
947 * data.
948 * size - The length of the meta-event data.
949 */
950 int
mf_write_midi_event(delta_time,type,chan,data,size)951 mf_write_midi_event (delta_time, type, chan, data, size)
952 unsigned long delta_time;
953 int chan, type;
954 unsigned long size;
955 char *data;
956 {
957 int i;
958 unsigned char c;
959
960 WriteVarLen (delta_time);
961
962 /* all MIDI events start with the type in the first four bits,
963 and the channel in the lower four bits */
964 if (type == system_exclusive || type == 0xf7)
965 {
966 c = type;
967 laststatus = 0;
968 }
969 else
970 c = type | chan;
971
972 if (chan > 15)
973 perror ("error: MIDI channel greater than 16\n");
974
975 if (laststatus != c)
976 eputc (laststatus = c);
977
978 if (type == system_exclusive || type == 0xf7)
979 WriteVarLen (size);
980
981 /* write out the data bytes */
982 for (i = 0; i < (int)size; i++)
983 eputc (data[i]);
984
985 return (size);
986 } /* end mf_write MIDI event */
987
988 /*
989 * mf_write_meta_event()
990 *
991 * Library routine to mf_write a single meta event in the standard MIDI
992 * file format. The format of a meta event is:
993 *
994 * <delta-time><FF><type><length><bytes>
995 *
996 * delta_time - the time in ticks since the last event.
997 * type - the type of meta event.
998 * data - A pointer to a block of chars containing the META EVENT,
999 * data.
1000 * size - The length of the meta-event data.
1001 */
1002 int
mf_write_meta_event(delta_time,type,data,size)1003 mf_write_meta_event (delta_time, type, data, size)
1004 unsigned long delta_time;
1005 unsigned char *data, type;
1006 unsigned long size;
1007 {
1008 int i;
1009
1010 WriteVarLen (delta_time);
1011
1012 /* This marks the fact we're writing a meta-event */
1013 eputc (laststatus = meta_event);
1014
1015 /* The type of meta event */
1016 eputc (type);
1017
1018 /* The length of the data bytes to follow */
1019 WriteVarLen (size);
1020
1021 for (i = 0; i < (int)size; i++)
1022 {
1023 if (eputc (data[i]) != data[i])
1024 return (-1);
1025 }
1026 return (size);
1027 } /* end mf_write_meta_event */
1028
1029 void
mf_write_tempo(delta_time,tempo)1030 mf_write_tempo (delta_time, tempo)
1031 unsigned long delta_time;
1032 unsigned long tempo;
1033 {
1034 /* Write tempo */
1035 /* all tempos are written as 120 beats/minute, */
1036 /* expressed in microseconds/quarter note */
1037
1038 WriteVarLen (delta_time);
1039 eputc (laststatus = meta_event);
1040 eputc (set_tempo);
1041
1042 eputc (3);
1043 eputc ((unsigned) (0xff & (tempo >> 16)));
1044 eputc ((unsigned) (0xff & (tempo >> 8)));
1045 eputc ((unsigned) (0xff & tempo));
1046 }
1047
1048 void
mf_write_seqnum(delta_time,seqnum)1049 mf_write_seqnum (delta_time, seqnum)
1050 unsigned long delta_time;
1051 unsigned seqnum;
1052 {
1053
1054 WriteVarLen (delta_time);
1055 eputc (laststatus = meta_event);
1056 eputc (0);
1057
1058 eputc ((unsigned) (0xff & (seqnum >> 8)));
1059 eputc ((unsigned) (0xff & seqnum));
1060 }
1061
1062 unsigned long
mf_sec2ticks(secs,division,tempo)1063 mf_sec2ticks (secs, division, tempo)
1064 int division;
1065 unsigned long tempo;
1066 double secs;
1067 {
1068 return (unsigned long) (((secs * 1000.0) / 4.0 * division) / tempo);
1069 }
1070
1071 /*
1072 * Write multi-length bytes to MIDI format files
1073 */
1074 void
WriteVarLen(value)1075 WriteVarLen (value)
1076 unsigned long value;
1077 {
1078 unsigned long buffer;
1079
1080 buffer = value & 0x7f;
1081 while ((value >>= 7) > 0)
1082 {
1083 buffer <<= 8;
1084 buffer |= 0x80;
1085 buffer += (value & 0x7f);
1086 }
1087 while (1)
1088 {
1089 eputc ((unsigned) (buffer & 0xff));
1090
1091 if (buffer & 0x80)
1092 buffer >>= 8;
1093 else
1094 return;
1095 }
1096 } /* end of WriteVarLen */
1097
1098 /*
1099 * This routine converts delta times in ticks into seconds. The
1100 * else statement is needed because the formula is different for tracks
1101 * based on notes and tracks based on SMPTE times.
1102 *
1103 */
1104 double
mf_ticks2sec(ticks,division,tempo)1105 mf_ticks2sec (ticks, division, tempo)
1106 int division;
1107 unsigned long tempo;
1108 unsigned long ticks;
1109 {
1110 double smpte_format, smpte_resolution;
1111
1112 if (division > 0)
1113 return ((double) (((double) (ticks) * (double) (tempo)) / ((double) (division) * 1000000.0)));
1114 else
1115 {
1116 smpte_format = upperbyte (division);
1117 smpte_resolution = lowerbyte (division);
1118 return (double) ((double) ticks / (smpte_format * smpte_resolution * 1000000.0));
1119 }
1120 } /* end of ticks2sec() */
1121
1122
1123 /*
1124 * write32bit()
1125 * write16bit()
1126 *
1127 * These routines are used to make sure that the byte order of
1128 * the various data types remains constant between machines. This
1129 * helps make sure that the code will be portable from one system
1130 * to the next. It is slightly dangerous that it assumes that longs
1131 * have at least 32 bits and ints have at least 16 bits, but this
1132 * has been true at least on PCs, UNIX machines, and Macintosh's.
1133 *
1134 */
1135 void
write32bit(data)1136 write32bit (data)
1137 unsigned long data;
1138 {
1139 eputc ((unsigned) ((data >> 24) & 0xff));
1140 eputc ((unsigned) ((data >> 16) & 0xff));
1141 eputc ((unsigned) ((data >> 8) & 0xff));
1142 eputc ((unsigned) (data & 0xff));
1143 }
1144
1145 void
write16bit(data)1146 write16bit (data)
1147 int data;
1148 {
1149 eputc ((unsigned) ((data & 0xff00) >> 8));
1150 eputc ((unsigned) (data & 0xff));
1151 }
1152
1153 /* write a single character and abort on error */
1154 static int
eputc(c)1155 eputc (c)
1156 unsigned char c;
1157 {
1158 int return_val;
1159
1160 if ((Mf_putc) == NULLFUNC)
1161 {
1162 mferror ("Mf_putc undefined");
1163 return (-1);
1164 }
1165
1166 return_val = (*Mf_putc) (c);
1167
1168 if (return_val == EOF)
1169 mferror ("error writing");
1170
1171 Mf_numbyteswritten++;
1172 return (return_val);
1173 }
1174