home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / msdos / convrtrs / mf2rol / midifile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-04  |  8.8 KB  |  490 lines

  1. /*
  2.  * midifile
  3.  * 
  4.  * Read a MIDI file.  Externally-assigned function pointers are called
  5.  * upon recognizing things in the file.
  6.  */
  7.  
  8. #include "midifile.h"
  9.  
  10. #define NULLFUNC 0
  11. #define NULL 0
  12. #define EOF (-1)
  13.  
  14. char *strcpy(), *strcat();
  15. void exit(), free();
  16.  
  17. /* public stuff */
  18.  
  19. /* Functions to be called while processing the MIDI file. */
  20. int (*Mf_getc)() = NULLFUNC;
  21. int (*Mf_error)() = NULLFUNC;
  22. int (*Mf_header)() = NULLFUNC;
  23. int (*Mf_trackstart)() = NULLFUNC;
  24. int (*Mf_trackend)() = NULLFUNC;
  25. int (*Mf_noteon)() = NULLFUNC;
  26. int (*Mf_noteoff)() = NULLFUNC;
  27. int (*Mf_pressure)() = NULLFUNC;
  28. int (*Mf_parameter)() = NULLFUNC;
  29. int (*Mf_pitchbend)() = NULLFUNC;
  30. int (*Mf_program)() = NULLFUNC;
  31. int (*Mf_chanpressure)() = NULLFUNC;
  32. int (*Mf_sysex)() = NULLFUNC;
  33. int (*Mf_arbitrary)() = NULLFUNC;
  34. int (*Mf_metamisc)() = NULLFUNC;
  35. int (*Mf_seqnum)() = NULLFUNC;
  36. int (*Mf_eot)() = NULLFUNC;
  37. int (*Mf_smpte)() = NULLFUNC;
  38. int (*Mf_tempo)() = NULLFUNC;
  39. int (*Mf_timesig)() = NULLFUNC;
  40. int (*Mf_keysig)() = NULLFUNC;
  41. int (*Mf_seqspecific)() = NULLFUNC;
  42. int (*Mf_text)() = NULLFUNC;
  43.  
  44. int Mf_nomerge = 0;        /* 1 => continue'ed system exclusives are */
  45.                 /* not collapsed. */
  46. long Mf_currtime = 0L;        /* current time in delta-time units */
  47.  
  48. /* private stuff */
  49.  
  50. static long Mf_toberead = 0L;
  51.  
  52. static long readvarinum();
  53. static long read32bit();
  54. static long to32bit();
  55. static int read16bit();
  56. static int to16bit();
  57. static char *msg();
  58.  
  59. midifile()         /* The only non-static function in this file. */
  60. {
  61.     if ( Mf_getc == NULLFUNC )
  62.         mferror(""); 
  63.  
  64.     readheader();
  65.     while ( readtrack() )
  66.         ;
  67. }
  68.  
  69. static
  70. readmt(s)        /* read through the "MThd" or "MTrk" header string */
  71. char *s;
  72. {
  73.     int n = 0;
  74.     char *p = s;
  75.     int c;
  76.  
  77.     while ( n++<4 && (c=(*Mf_getc)()) != EOF ) {
  78.         if ( c != *p++ ) {
  79.             char buff[32];
  80.             (void) strcpy(buff,"expecting ");
  81.             (void) strcat(buff,s);
  82.             if (strcmp(s, "MTrk") == 0) {
  83.                 if ( Mf_error )
  84.                     (*Mf_error)("expecting MTrk - assuming EOF");
  85.                 return(EOF);
  86.             }
  87.             mferror(buff);
  88.         }
  89.     }
  90.     return(c);
  91. }
  92.  
  93. static
  94. egetc()            /* read a single character and abort on EOF */
  95. {
  96.     int c = (*Mf_getc)();
  97.  
  98.     if ( c == EOF )
  99.         mferror("unexpected EOF");
  100.     Mf_toberead--;
  101.     return(c);
  102. }
  103.  
  104. static
  105. readheader()        /* read a header chunk */
  106. {
  107.     int format, ntrks, division;
  108.  
  109.     if ( readmt("MThd") == EOF )
  110.         return(0);
  111.  
  112.     Mf_toberead = read32bit();
  113.     format = read16bit();
  114.     ntrks = read16bit();
  115.     division = read16bit();
  116.  
  117.     if ( Mf_header )
  118.         (*Mf_header)(format,ntrks,division);
  119.  
  120.     /* flush any extra stuff, in case the length of header is not 6 */
  121.     while ( Mf_toberead > 0 )
  122.         (void) egetc();
  123.     return(0);
  124. }
  125.  
  126. static
  127. readtrack()         /* read a track chunk */
  128. {
  129.     /* This array is indexed by the high half of a status byte.  It's */
  130.     /* value is either the number of bytes needed (1 or 2) for a channel */
  131.     /* message, or 0 (meaning it's not  a channel message). */
  132.     static int chantype[] = {
  133.         0, 0, 0, 0, 0, 0, 0, 0,        /* 0x00 through 0x70 */
  134.         2, 2, 2, 2, 1, 1, 2, 0        /* 0x80 through 0xf0 */
  135.     };
  136.     long lookfor, lng;
  137.     int c, c1, type;
  138.     int sysexcontinue = 0;    /* 1 if last message was an unfinished sysex */
  139.     int running = 0;    /* 1 when running status used */
  140.     int status = 0;        /* (possibly running) status byte */
  141.     int needed;
  142.  
  143.     if ( readmt("MTrk") == EOF )
  144.         return(0);
  145.  
  146.     Mf_toberead = read32bit();
  147.     Mf_currtime = 0;
  148.  
  149.     if ( Mf_trackstart )
  150.         (*Mf_trackstart)();
  151.  
  152.     while ( Mf_toberead > 0 ) {
  153.  
  154.         Mf_currtime += readvarinum();    /* delta time */
  155.  
  156.         c = egetc();
  157.  
  158.         if ( sysexcontinue && c != 0xf7 )
  159.             mferror("didn't find expected continuation of a sysex");
  160.  
  161.         if ( (c & 0x80) == 0 ) {     /* running status? */
  162.             if ( status == 0 )
  163.                 mferror("unexpected running status");
  164.             running = 1;
  165.         }
  166.         else {
  167.             status = c;
  168.             running = 0;
  169.         }
  170.  
  171.         needed = chantype[ (status>>4) & 0xf ];
  172.  
  173.         if ( needed ) {        /* ie. is it a channel message? */
  174.  
  175.             if ( running )
  176.                 c1 = c;
  177.             else
  178.                 c1 = egetc();
  179.             chanmessage( status, c1, (needed>1) ? egetc() : 0 );
  180.             continue;;
  181.         }
  182.  
  183.         switch ( c ) {
  184.  
  185.         case 0xff:            /* meta event */
  186.  
  187.             type = egetc();
  188.             lng = readvarinum();
  189.             lookfor = Mf_toberead - lng;
  190.             msginit();
  191.  
  192.             while ( Mf_toberead > lookfor )
  193.                 msgadd(egetc());
  194.  
  195.             metaevent(type);
  196.             break;
  197.  
  198.         case 0xf0:        /* start of system exclusive */
  199.  
  200.             lng = readvarinum();
  201.             lookfor = Mf_toberead - lng;
  202.             msginit();
  203.             msgadd(0xf0);
  204.  
  205.             while ( Mf_toberead > lookfor )
  206.                 msgadd(c=egetc());
  207.  
  208.             if ( c==0xf7 || Mf_nomerge==0 )
  209.                 sysex();
  210.             else
  211.                 sysexcontinue = 1;  /* merge into next msg */
  212.             break;
  213.  
  214.         case 0xf7:    /* sysex continuation or arbitrary stuff */
  215.  
  216.             lng = readvarinum();
  217.             lookfor = Mf_toberead - lng;
  218.  
  219.             if ( ! sysexcontinue )
  220.                 msginit();
  221.  
  222.             while ( Mf_toberead > lookfor )
  223.                 msgadd(c=egetc());
  224.  
  225.             if ( ! sysexcontinue ) {
  226.                 if ( Mf_arbitrary )
  227.                     (*Mf_arbitrary)(msgleng(),msg());
  228.             }
  229.             else if ( c == 0xf7 ) {
  230.                 sysex();
  231.                 sysexcontinue = 0;
  232.             }
  233.             break;
  234.         default:
  235.             badbyte(c);
  236.             break;
  237.         }
  238.     }
  239.     if ( Mf_trackend )
  240.         (*Mf_trackend)();
  241.     return(1);
  242. }
  243.  
  244. static
  245. badbyte(c)
  246. int c;
  247. {
  248.     char buff[32];
  249.  
  250.     (void) sprintf(buff,"unexpected byte: 0x%02x",c);
  251.     mferror(buff);
  252. }
  253.  
  254. static
  255. metaevent(type)
  256. {
  257.     int leng = msgleng();
  258.     char *m = msg();
  259.  
  260.     switch  ( type ) {
  261.     case 0x00:
  262.         if ( Mf_seqnum )
  263.             (*Mf_seqnum)(to16bit(m[0],m[1]));
  264.         break;
  265.     case 0x01:    /* Text event */
  266.     case 0x02:    /* Copyright notice */
  267.     case 0x03:    /* Sequence/Track name */
  268.     case 0x04:    /* Instrument name */
  269.     case 0x05:    /* Lyric */
  270.     case 0x06:    /* Marker */
  271.     case 0x07:    /* Cue point */
  272.     case 0x08:
  273.     case 0x09:
  274.     case 0x0a:
  275.     case 0x0b:
  276.     case 0x0c:
  277.     case 0x0d:
  278.     case 0x0e:
  279.     case 0x0f:
  280.         /* These are all text events */
  281.         if ( Mf_text )
  282.             (*Mf_text)(type,leng,m);
  283.         break;
  284.     case 0x2f:    /* End of Track */
  285.         if ( Mf_eot )
  286.             (*Mf_eot)();
  287.         break;
  288.     case 0x51:    /* Set tempo */
  289.         if ( Mf_tempo )
  290.             (*Mf_tempo)(to32bit(0,m[0],m[1],m[2]));
  291.         break;
  292.     case 0x54:
  293.         if ( Mf_smpte )
  294.             (*Mf_smpte)(m[0],m[1],m[2],m[3],m[4]);
  295.         break;
  296.     case 0x58:
  297.         if ( Mf_timesig )
  298.             (*Mf_timesig)(m[0],m[1],m[2],m[3]);
  299.         break;
  300.     case 0x59:
  301.         if ( Mf_keysig )
  302.             (*Mf_keysig)(m[0],m[1]);
  303.         break;
  304.     case 0x7f:
  305.         if ( Mf_seqspecific )
  306.             (*Mf_seqspecific)(leng,m);
  307.         break;
  308.     default:
  309.         if ( Mf_metamisc )
  310.             (*Mf_metamisc)(type,leng,m);
  311.     }
  312. }
  313.  
  314. static
  315. sysex()
  316. {
  317.     if ( Mf_sysex )
  318.         (*Mf_sysex)(msgleng(),msg());
  319. }
  320.  
  321. static
  322. chanmessage(status,c1,c2)
  323. int status;
  324. int c1, c2;
  325. {
  326.     int chan = status & 0xf;
  327.  
  328.     switch ( status & 0xf0 ) {
  329.     case NOTEOFF:
  330.         if ( Mf_noteoff )
  331.             (*Mf_noteoff)(chan,c1,c2);
  332.         break;
  333.     case NOTEON:
  334.         if ( Mf_noteon )
  335.             (*Mf_noteon)(chan,c1,c2);
  336.         break;
  337.     case PRESSURE:
  338.         if ( Mf_pressure )
  339.             (*Mf_pressure)(chan,c1,c2);
  340.         break;
  341.     case PARAMETER:
  342.         if ( Mf_parameter )
  343.             (*Mf_parameter)(chan,c1,c2);
  344.         break;
  345.     case PITCHBEND:
  346.         if ( Mf_pitchbend )
  347.             (*Mf_pitchbend)(chan,c1,c2);
  348.         break;
  349.     case PROGRAM:
  350.         if ( Mf_program )
  351.             (*Mf_program)(chan,c1);
  352.         break;
  353.     case CHANPRESSURE:
  354.         if ( Mf_chanpressure )
  355.             (*Mf_chanpressure)(chan,c1);
  356.         break;
  357.     }
  358. }
  359.  
  360. /* readvarinum - read a varying-length number, and return the */
  361. /* number of characters it took. */
  362.  
  363. static long
  364. readvarinum()
  365. {
  366.     long value;
  367.     int c;
  368.  
  369.     c = egetc();
  370.     value = c;
  371.     if ( c & 0x80 ) {
  372.         value &= 0x7f;
  373.         do {
  374.             c = egetc();
  375.             value = (value << 7) + (c & 0x7f);
  376.         } while (c & 0x80);
  377.     }
  378.     return (value);
  379. }
  380.  
  381. static long
  382. to32bit(c1,c2,c3,c4)
  383. {
  384.     long value = 0L;
  385.  
  386.     value = (c1 & 0xff);
  387.     value = (value<<8) + (c2 & 0xff);
  388.     value = (value<<8) + (c3 & 0xff);
  389.     value = (value<<8) + (c4 & 0xff);
  390.     return (value);
  391. }
  392.  
  393. static
  394. to16bit(c1,c2)
  395. int c1, c2;
  396. {
  397.     return ((c1 & 0xff ) << 8) + (c2 & 0xff);
  398. }
  399.  
  400. static long
  401. read32bit()
  402. {
  403.     int c1, c2, c3, c4;
  404.  
  405.     c1 = egetc();
  406.     c2 = egetc();
  407.     c3 = egetc();
  408.     c4 = egetc();
  409.     return to32bit(c1,c2,c3,c4);
  410. }
  411.  
  412. static
  413. read16bit()
  414. {
  415.     int c1, c2;
  416.     c1 = egetc();
  417.     c2 = egetc();
  418.     return to16bit(c1,c2);
  419. }
  420.  
  421. static
  422. mferror(s)
  423. char *s;
  424. {
  425.     if ( Mf_error )
  426.         (*Mf_error)(s);
  427.     exit(1);
  428. }
  429.  
  430. /* The code below allows collection of a system exclusive message of */
  431. /* arbitrary length.  The Msgbuff is expanded as necessary.  The only */
  432. /* visible data/routines are msginit(), msgadd(), msg(), msgleng(). */
  433.  
  434. #define MSGINCREMENT 256
  435. static char *Msgbuff = NULL;    /* message buffer */
  436. static int Msgsize = 0;        /* Size of currently allocated Msg */
  437. static int Msgindex = 0;    /* index of next available location in Msg */
  438.  
  439. static
  440. msginit()
  441. {
  442.     Msgindex = 0;
  443. }
  444.  
  445. static char *
  446. msg()
  447. {
  448.     return(Msgbuff);
  449. }
  450.  
  451. static
  452. msgleng()
  453. {
  454.     return(Msgindex);
  455. }
  456.  
  457. static
  458. msgadd(c)
  459. int c;
  460. {
  461.     /* If necessary, allocate larger message buffer. */
  462.     if ( Msgindex >= Msgsize )
  463.         biggermsg();
  464.     Msgbuff[Msgindex++] = c;
  465. }
  466.  
  467. static
  468. biggermsg()
  469. {
  470.     char *malloc();
  471.     char *newmess;
  472.     char *oldmess = Msgbuff;
  473.     int oldleng = Msgsize;
  474.  
  475.     Msgsize += MSGINCREMENT;
  476.     newmess = malloc( (unsigned)(sizeof(char)*Msgsize) );
  477.  
  478.     /* copy old message into larger new one */
  479.     if ( oldmess != NULL ) {
  480.         register char *p = newmess;
  481.         register char *q = oldmess;
  482.         register char *endq = &oldmess[oldleng];
  483.  
  484.         for ( ; q!=endq ; p++,q++ )
  485.             *p = *q;
  486.         /* free(oldmess); */
  487.     }
  488.     Msgbuff = newmess;
  489. }
  490.