Home | History | Annotate | Download | only in test
      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
    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
    184 midifile ()
    185 {
    186   mfread ();
    187 }
    188 
    189 static
    190 int
    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
    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
    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
    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 %d, old_tempo %d]\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 %d, new_tempo %d]\n", revised_time, new_tempo);
    306 #endif
    307   return(new_tempo);
    308 }
    309 
    310 static
    311 int
    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 %d - old %d, div %d, tempo %d) = %.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=%d ticks ( = %d 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 %d - old %d, div %d, tempo %d) = %.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=%d ticks ( = %d 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
    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
    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
    582 sysex ()
    583 {
    584   if (Mf_sysex)
    585     (*Mf_sysex) (msgleng (), msg ());
    586 }
    587 
    588 static
    589 void
    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
    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
    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
    671 to16bit (c1, c2)
    672      int c1, c2;
    673 {
    674   return ((c1 & 0xff) << 8) + (c2 & 0xff);
    675 }
    676 
    677 static long
    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
    690 read16bit ()
    691 {
    692   int c1, c2;
    693   c1 = egetc ();
    694   c2 = egetc ();
    695   return to16bit (c1, c2);
    696 }
    697 
    698 /* static */
    699 void
    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
    719 msginit ()
    720 {
    721   Msgindex = 0;
    722 }
    723 
    724 static char *
    725 msg ()
    726 {
    727   return (Msgbuff);
    728 }
    729 
    730 static
    731 int
    732 msgleng ()
    733 {
    734   return (Msgindex);
    735 }
    736 
    737 static
    738 void
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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
   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
   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
   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
   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
   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