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