• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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