home *** CD-ROM | disk | FTP | other *** search
/ ftp.4front-tech.com / ftp.4front-tech.com.tar / ftp.4front-tech.com / ossfree / snd-util-3.8.tar.gz / snd-util-3.8.tar / sndkit / mplay / mlib.c < prev    next >
C/C++ Source or Header  |  1996-11-28  |  17KB  |  871 lines

  1. #define DEB(stmt)    /* stmt    */    /* For debug printing */
  2. #define DEB2(stmt)    /* stmt */    /* For debug printing */
  3. #define DEB3(stmt)    /* stmt */    /* For debug printing */
  4. #define DEB_ALWAYS(stmt) /* stmt */    /* Interesting things */
  5.  
  6. #define _INCLUDE_POSIX_SOURCE 1
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <fcntl.h>
  11. #include <sys/errno.h>
  12.  
  13. extern int errno;
  14.  
  15. #define USE_SIMPLE_MACROS
  16. #include <sys/soundcard.h>
  17.  
  18. #include "mlib.h"
  19.  
  20. #define _seqbuf eventptr
  21. #define _seqbufptr 4
  22. #define _SEQ_ADVBUF(len) *optr = *optr + 1;
  23.  
  24. #define STORE(cmd) \
  25.     if (track->events) \
  26.       { \
  27.           unsigned char *eventptr = &(track->events[*optr*12]); \
  28.         *(int *)&eventptr[0] = track->current_time; \
  29.           cmd; \
  30.       } \
  31.     else \
  32.       { \
  33.         *optr =  *optr + 1; \
  34.       }
  35.  
  36. #define META_EVENT(type, buf, len) \
  37.     { \
  38.         eventptr[_seqbufptr + 0] = EV_PRIVATE_META; \
  39.         eventptr[_seqbufptr + 1] = (type); \
  40.         *(short*)&eventptr[_seqbufptr + 2] = (short)len; \
  41.         *(char**)&eventptr[_seqbufptr + 4] = malloc(len); \
  42.         memcpy((char**)&eventptr[_seqbufptr + 4], &(buf), len); \
  43.         *optr = *optr + 1; \
  44.     }
  45.  
  46. #define MAX_EVENT_SIZE    4095
  47.  
  48. static int midi_msglen[8] = {
  49.         2,    /* 8x = Note off */
  50.         2,    /* 9x = Note on */
  51.         2,    /* Ax = Polyphonic key pressure (After-touch) */
  52.         2,    /* Bx = Control change */
  53.         1,    /* Cx = Program change */
  54.         1,    /* Dx = Channel pressure (After-touch) */
  55.         2,    /* Ex = Pitch wheel change */
  56.         0    /* Fx = system messages */
  57.     };
  58.  
  59. static char mlib_errstring[256] = "No errors so far\n";
  60.  
  61. static char *mlib_seterr(char *msg)
  62. {
  63.     strncpy(mlib_errstring, msg, sizeof(mlib_errstring));
  64.     return NULL;
  65. }
  66.  
  67. static char *mlib_syserr(char *name)
  68. {
  69.     sprintf(mlib_errstring, "%s: %s", name, strerror(errno));
  70.     return NULL;
  71. }
  72.  
  73. int mlib_chkdesc(mlib_desc *desc)
  74. {
  75.     if (desc == NULL)
  76.     {
  77.         mlib_seterr("NULL mlib descriptor specified");
  78.         return 0;
  79.     }
  80.  
  81.     if (desc->magic != 0x121234)
  82.     {
  83.         mlib_seterr("Invalid MAGIC in the mlib descriptor");
  84.         return 0;
  85.     }
  86.  
  87.  
  88.     if (desc->fd < 0)
  89.     {
  90.         mlib_seterr("Invalid fd in the mlib descriptor");
  91.         return 0;
  92.     }
  93.  
  94.     return 1;
  95. }
  96.  
  97. static int
  98. mlib_loadbuf(mlib_desc *desc)
  99. {
  100.     desc->bufp = 0;
  101.  
  102.     if ((desc->bufcnt=read(desc->fd, desc->buf, sizeof(desc->buf)))==-1)
  103.     {
  104.         mlib_syserr(desc->path);
  105.         return 0;
  106.     }
  107.  
  108.     if (desc->bufcnt == 0)
  109.     {
  110.         mlib_seterr("End of MIDI file");
  111.         return 0;
  112.     }
  113.  
  114.     return 1;
  115. }
  116.  
  117. static int
  118. mlib_seek(mlib_desc *desc, long pos)
  119. {
  120.  
  121.     if (lseek(desc->fd, pos, 0)==-1)
  122.     {
  123.         mlib_syserr(desc->path);
  124.         return 0;
  125.     }
  126.  
  127.     desc->bufcnt = 0;
  128.     desc->bufp = 1;
  129.  
  130.     return 1;
  131. }
  132.  
  133. static int
  134. mlib_rdstr(mlib_desc *desc, char *target, int nchars)
  135. {
  136.     int i;
  137.  
  138.     if (!mlib_chkdesc(desc)) return 0;
  139.  
  140.     for (i=0;i<nchars;i++)
  141.     {
  142.         if (desc->bufp >= desc->bufcnt)
  143.         if (!mlib_loadbuf(desc)) return 0;
  144.  
  145.         target[i] = desc->buf[desc->bufp];
  146.         desc->bufp++;
  147.     }
  148.  
  149.     target[nchars] = 0;    /* End of string */
  150.  
  151.     return nchars;
  152. }
  153.  
  154. static int
  155. mlib_rdvarlen(mlib_desc *desc, int *target)
  156. {
  157.     int tmp, i;
  158.  
  159.     *target = 0;
  160.  
  161.     for (i=0;i<6;i++)    /* Read at most 6 bytes */
  162.     {
  163.         if (desc->bufp >= desc->bufcnt)
  164.         if (!mlib_loadbuf(desc)) return 0;
  165.  
  166.         tmp = desc->buf[desc->bufp];
  167.         desc->bufp++;
  168.  
  169.         *target <<= 7;
  170.         *target |= tmp & 0x7f;    /* Extract 7 bits */
  171.         if ((tmp & 0x80) == 0)    return i+1; /* Last byte */
  172.     }
  173.  
  174.     mlib_seterr("Unterminated variable length value");
  175.  
  176.     return 0;
  177. }
  178.  
  179. static int
  180. mlib_rdint16(mlib_desc *desc, int *target)
  181. {
  182.     int tmp, i;
  183.  
  184.     *target = 0;
  185.  
  186.     for (i=0;i<2;i++)
  187.     {
  188.         if (desc->bufp >= desc->bufcnt)
  189.         if (!mlib_loadbuf(desc)) return 0;
  190.  
  191.         tmp = desc->buf[desc->bufp];
  192.         desc->bufp++;
  193.  
  194.         *target <<= 8;
  195.         *target |= tmp & 0xff;
  196.     }
  197.  
  198.     return 2;
  199. }
  200.  
  201. static int
  202. mlib_rdbyte(mlib_desc *desc, unsigned char *target)
  203. {
  204.     if (desc->bufp >= desc->bufcnt)
  205.     if (!mlib_loadbuf(desc)) return 0;
  206.  
  207.     *target = (char)(desc->buf[desc->bufp]);
  208.     desc->bufp++;
  209.     return 1;
  210. }
  211.  
  212. static int
  213. mlib_rdint32(mlib_desc *desc, int *target)
  214. {
  215.     int tmp, i;
  216.  
  217.     *target = 0;
  218.  
  219.     for (i=0;i<4;i++)
  220.     {
  221.         if (desc->bufp >= desc->bufcnt)
  222.         if (!mlib_loadbuf(desc)) return 0;
  223.  
  224.         tmp = desc->buf[desc->bufp];
  225.         desc->bufp++;
  226.  
  227.         *target <<= 8;
  228.         *target += tmp & 0xff;
  229.     }
  230.  
  231.     return 4;
  232. }
  233.  
  234. static int
  235. mlib_read_mthd(mlib_desc *desc)
  236. {
  237.     char sig[5];
  238.     unsigned char hi, lo;
  239.     int len;
  240.  
  241.     if (!mlib_chkdesc(desc)) return 0;
  242.  
  243.     if (!mlib_rdstr(desc, sig, 4)) return 0;
  244.  
  245.     if (strcmp(sig, "MThd"))
  246.     {
  247.         mlib_seterr("Invalid header signature (!= MThd)");
  248.         return 0;
  249.     }
  250.  
  251.     if (mlib_rdint32(desc, &len))
  252.  
  253.     if (mlib_rdint16(desc, &desc->hdr.MThd_fmt))
  254.     DEB2(printf("Header: Format %d\n", desc->hdr.MThd_fmt));
  255.  
  256.     if (mlib_rdint16(desc, &desc->hdr.MThd_ntrk))
  257.     DEB2(printf("Header: ntrks %d\n", desc->hdr.MThd_ntrk));
  258.  
  259.     if (mlib_rdbyte(desc, &hi))
  260.     if (mlib_rdbyte(desc, &lo))
  261.  
  262.     if (hi & 0x80)    /* Negative */
  263.       {
  264.         DEB2(printf("SMPTE timing: format = %d, resolution = %d\n",
  265.             (char)hi, lo));
  266.         desc->hdr.time_mode = TIME_SMPTE;
  267.         desc->hdr.SMPTE_format = (char)hi;
  268.         desc->hdr.SMPTE_resolution = lo;
  269.       }
  270.     else
  271.       {
  272.         desc->hdr.time_mode = TIME_MIDI;
  273.         desc->hdr.division = (hi << 8) + lo;
  274.         DEB2(printf("Midi timing: timebase = %d ppqn\n",
  275.             desc->hdr.division));
  276.       }
  277.  
  278.     desc->curr_trk = -1;
  279.     desc->trk_offs = 0;
  280.     desc->next_trk_offs = 4 + 4 + len;;
  281.  
  282.     return mlib_seek(desc, desc->trk_offs);    /* Point to the first track */
  283. }
  284.  
  285. static int
  286. mlib_store_chn_voice_msg(mlib_desc *desc, mlib_track *track, int *optr,
  287.               unsigned char *evbuf, int len)
  288. {
  289.  
  290.     unsigned char chn, pgm, note, vel;
  291.  
  292.     chn = evbuf[0] & 0x0f;    /* Midi channel */
  293.  
  294.     if (track->init_chn == -1)
  295.        track->init_chn = chn;
  296.     else
  297.        if (chn != track->init_chn)
  298.           track->flags |= TRK_MULTICHN;
  299.  
  300.     track->chnmask |= (1 << chn);    /* Update channel mask */
  301.  
  302.     switch (evbuf[0] & 0xf0)
  303.     {
  304.     case 0x90:    /* Note on */
  305.       vel = evbuf[2];
  306.       note = evbuf[1];
  307.  
  308.       if (vel != 0)
  309.       {    /* Velocity given -> true note on event */
  310.             track->flags |= TRK_NOTES;
  311.  
  312.             if (note > track->max_note)
  313.                track->max_note = note;
  314.  
  315.             if (note < track->min_note)
  316.                track->min_note = note;
  317.  
  318.         if (track->noteon_time == -1)
  319.            track->noteon_time = track->current_time;
  320.  
  321.         if (vel != 64)
  322.            track->flags |= TRK_VEL_NOTEON;
  323.  
  324.         STORE( SEQ_START_NOTE(0, chn, note, vel) );
  325.         if (chn == 9) /* Drum channel */
  326.            track->drum_map[note] = note;
  327.           break;    /* NOTE! The break is here, not later */
  328.       }
  329.       /* Note on with zero G -> note off with vel=64. */
  330.       /* Fall to the next case */
  331.       evbuf[2] = 64;    /* Velocity for the note off handler */
  332.  
  333.     case 0x80:    /* Note off */
  334.       vel = evbuf[2];
  335.       note = evbuf[1];
  336.  
  337.       if (vel != 64)
  338.          track->flags |= TRK_VEL_NOTEOFF;
  339.       STORE( SEQ_STOP_NOTE(0, chn, note, vel) );
  340.       break;
  341.  
  342.     case 0xA0:    /* Polyphonic key pressure/Aftertouch */
  343.       track->flags |= TRK_POLY_AFTERTOUCH | TRK_AFTERTOUCH;
  344.       STORE( SEQ_KEY_PRESSURE(0, chn, note, vel) );
  345.       break;
  346.  
  347.     case 0xB0:    /* Control change */
  348.       {
  349.         unsigned short value = evbuf[2];    /* Incorrect */
  350.         unsigned char ctl = evbuf[1];
  351.  
  352.         track->flags |= TRK_CONTROLS;
  353.         STORE( SEQ_CONTROL(0, chn, ctl, value) );
  354.       }
  355.       break;
  356.  
  357.     case 0xC0:    /* Program change */
  358.       pgm = evbuf[1];
  359.       if (track->init_pgm == -1)
  360.          track->init_pgm = pgm;
  361.       else
  362.          if (pgm != track->init_pgm)
  363.             track->flags |= TRK_MULTIPGM;
  364.  
  365.        track->pgm_map[pgm] = pgm;
  366.        STORE( SEQ_SET_PATCH(0, chn, pgm) ); 
  367.       break;
  368.  
  369.     case 0xD0:    /* Channel pressure/Aftertouch */
  370.       track->flags |= TRK_AFTERTOUCH;
  371.       STORE( SEQ_CHN_PRESSURE(0, chn, evbuf[1]) );
  372.       break;
  373.  
  374.     case 0xE0:    /* Pitch bend change */
  375.       track->flags |= TRK_BENDER;
  376.       STORE( SEQ_BENDER(0, chn, (evbuf[1] & 0x7f) + ((evbuf[2] & 0x7f)<<7)) );
  377.       break;
  378.  
  379.     default:
  380.       mlib_seterr("Internal error: Unexpected midi event");
  381.       fprintf(stderr, "Internal error: Unexpected midi event %02x\n", evbuf[0]);
  382.  
  383.       return 0;
  384.     }
  385.  
  386.     return 1;
  387. }
  388.  
  389. static int
  390. mlib_store_meta_event(mlib_desc *desc, mlib_track *track, int *optr,
  391.               unsigned char *evbuf, int len)
  392. {
  393.     int type = evbuf[0];
  394.     int i;
  395.  
  396. /*
  397.  * The event is stored at the end of this function. If there is no 
  398.  * need to store the event, the case entry should return (return 1).
  399.  */
  400.  
  401.     switch (type)
  402.     {
  403.     case 0x00:    /* Extension events ?????????????? */
  404.       /* Not supported yet */
  405.       break;
  406.  
  407.     case 0x01:    /* Descriptive text */
  408.     case 0x02:    /* Copyright notice */
  409.     case 0x03:    /* Sequence/track name */
  410.     case 0x04:    /* Instrument name */
  411.     case 0x05:    /* Lyric */
  412.     case 0x06:    /* Marker */
  413.     case 0x07:    /* Cue point */
  414. #if 0
  415.       for (i=0;i<len-1;i++)
  416.           printf("%c", evbuf[1+i]);
  417.       printf("\n");
  418. #endif
  419.       break;
  420.  
  421.     case 0x21:    /* What is this */
  422.       break;
  423.  
  424. /*    Here is a big hole in the known meta event space */
  425.  
  426.     case 0x2f:    /* End of track */
  427.       break;
  428.  
  429. /*    Here is a big hole in the known meta event space */
  430.  
  431.     case 0x51:    /* Set tempo (usec per MIDI quarter-note) */
  432.       {
  433.         int tempo_bpm = 120;
  434.         unsigned int usecs_per_qn;
  435.  
  436.         usecs_per_qn = (evbuf[1] << 16) | (evbuf[2] << 8) | evbuf[3];
  437.         tempo_bpm = (60000000 + (usecs_per_qn / 2)) / usecs_per_qn;
  438.  
  439.         STORE( SEQ_SET_TEMPO(tempo_bpm) );
  440.         return 1;
  441.       }
  442.       break;
  443.  
  444.     case 0x54:    /* SMPTE offset */
  445.       break;
  446.  
  447.     case 0x58:    /* Time signature */
  448.       {
  449.           unsigned sig;
  450.  
  451.           sig = evbuf[1] << 24;
  452.           sig |= evbuf[2] << 16;
  453.           sig |= evbuf[3] << 8;
  454.           sig |= evbuf[4];
  455.  
  456.           if (!desc->timesig)
  457.              desc->timesig = sig;
  458.           STORE( SEQ_TIME_SIGNATURE(sig) );
  459.       }
  460.       break;
  461.  
  462.     case 0x59:    /* Key signature */
  463.       break;
  464.  
  465.     case 0x7f:    /* Vendor specific meta event */
  466.       if (evbuf[1] == 0 && evbuf[2] == 0 && evbuf[3] == 0x41)
  467.         {    /* Microsoft ?? */
  468.         if (len == 4) DEB_ALWAYS(printf("GM file flag \n"));
  469.  
  470. /* Don't forget to add more code here */
  471.         }
  472.       else
  473.         {
  474.           DEB_ALWAYS(printf("Private meta event:\n"));
  475.           for (i=0;i<len;i++)
  476.             DEB_ALWAYS(printf("%02x ", evbuf[i]));
  477.           DEB_ALWAYS(printf("\n"));
  478.           for (i=0;i<len;i++)
  479.             DEB_ALWAYS(printf("%c", (evbuf[i]>=' ' && evbuf[i] < 127) ?
  480.                         evbuf[i] : '.'));
  481.           DEB_ALWAYS(printf("\n"));
  482.         }
  483.       break;
  484.  
  485.     default:
  486.       DEB_ALWAYS(printf("Meta event: 0x%02x???\n", type));
  487.       for (i=0;i<len;i++)
  488.         DEB_ALWAYS(printf("%02x ", evbuf[i]));
  489.       DEB_ALWAYS(printf("\n"));
  490.       for (i=0;i<len;i++)
  491.         DEB_ALWAYS(printf("%c", (evbuf[i]>=' ' && evbuf[i] < 127) ?
  492.                     evbuf[i] : '.'));
  493.       DEB_ALWAYS(printf("\n"));
  494.     }
  495.  
  496.     STORE( META_EVENT(type, evbuf, len) );
  497.  
  498.     return 1;
  499. }
  500.  
  501. static int
  502. mlib_input_event(mlib_desc *desc, int *iptr, int *optr, mlib_track *track)
  503. {
  504.     int time, len, event_len, i, p;
  505.     unsigned char b, status, type;
  506.  
  507.     unsigned char buf[MAX_EVENT_SIZE+1];
  508.  
  509.     if (!(len=mlib_rdvarlen(desc, &time))) return 0;
  510.     *iptr += len;
  511.  
  512.     track->current_time += time;
  513.     if (track->end_time < track->current_time)
  514.           track->end_time = track->current_time;
  515.  
  516.     if (!(len=mlib_rdbyte(desc, &type))) return 0;
  517.     *iptr += len;
  518.  
  519.     DEB(printf("EVENT: time = %d type = 0x%02x: ", time, type));
  520.  
  521.     p = 0;
  522.  
  523.     switch (type)
  524.     {
  525.     case 0xff:    /* Meta event */
  526.       if (!(len=mlib_rdbyte(desc, &type))) return 0;
  527.       *iptr += len;
  528.  
  529.       buf[p++] = type;
  530.  
  531.       if (!(len=mlib_rdvarlen(desc, &event_len))) return 0;
  532.       *iptr += len;
  533.  
  534.       DEB(printf("meta(type=%02x, len=%d): ", type, event_len));
  535.  
  536.       if ((event_len+1) > MAX_EVENT_SIZE)
  537.       {
  538.         mlib_seterr("Too long meta event in file");
  539.         *iptr += event_len;
  540.         return 0;    /* Fatal error */
  541.       }
  542.  
  543.       for (i=0;i<event_len;i++)
  544.       {
  545.         if (!(len=mlib_rdbyte(desc, &b))) return 0;
  546.         *iptr += len;
  547.  
  548.         buf[p++] = b;
  549.         DEB(printf("%02x ", b));
  550.       }
  551.  
  552. /*
  553.  * End of track test
  554.  */
  555.  
  556.       if (type == 0x2f)
  557.       {
  558.           *iptr = 0x7fffffff;
  559.           return 1;
  560.       }
  561.       if (!mlib_store_meta_event(desc, track, optr, buf, p)) return 0;
  562.       break;
  563.  
  564.     case 0xf0:    /* Sysex, variation 1 */
  565.       if (!(len=mlib_rdvarlen(desc, &event_len))) return 0;
  566.       *iptr += len;
  567.       DEB(printf("sysex1 (%d): f0 ", event_len));
  568.       p=0;buf[p++] = 0xf0;
  569.       for (i=0;i<event_len;i++)
  570.       {
  571.         if (!(len=mlib_rdbyte(desc, &b))) return 0;
  572.         *iptr += len;
  573.           buf[p++] = b;
  574.  
  575.         DEB(printf("%02x ", b));
  576.       }
  577.       {
  578.         int l;
  579.  
  580.         i = 0;
  581.         while (i<p)
  582.         {
  583.           int xx;
  584.           l = p-i;
  585.           if (l > 6)
  586.              l = 6;
  587.           STORE( SEQ_SYSEX(0, &buf[i], l) );
  588.           i+=l;
  589.         }
  590.       }
  591.       break;
  592.  
  593.     case 0xf7:    /* Sysex, variation 2 */
  594.       if (!(len=mlib_rdvarlen(desc, &event_len))) return 0;
  595.       *iptr += len;
  596.       DEB(printf("sysex2 (%d): ", event_len));
  597.       for (i=0;i<event_len;i++)
  598.       {
  599.         if (!(len=mlib_rdbyte(desc, &b))) return 0;
  600.           buf[p++] = b;
  601.         *iptr += len;
  602.  
  603.         DEB(printf("%02x ", b));
  604.       }
  605.       {
  606.         int l;
  607.  
  608.         i = 0;
  609.         while (i<p)
  610.         {
  611.           l = p-i;
  612.           if (l > 6)
  613.              l = 6;
  614.           STORE( SEQ_SYSEX(0, &buf[i], l) );
  615.           i+=l;
  616.         }
  617.       }
  618.       break;
  619.  
  620.     default:
  621.  
  622.       if ((type & 0xf0) == 0xf0)    /* Sys message */
  623.         {
  624.         DEB(printf("system message "));
  625.         DEB(printf("\n"));
  626.         mlib_seterr("Unsupported midi file event");
  627.         return 0;
  628.         }
  629.       else
  630.       if (type < 0x80)
  631.         {
  632.         buf[p++] = status = desc->prev_status;
  633.         DEB(printf("Midi message (RST): %02x %02x ",
  634.             status, type));
  635.         buf[p++] = type;
  636.  
  637.         event_len = midi_msglen[((status >> 4) & 0xf) -8]-1;
  638.         for (i=0;i<event_len;i++)
  639.         {
  640.             if (!(len=mlib_rdbyte(desc, &b))) return 0;
  641.             *iptr += len;
  642.             buf[p++] = b;
  643.             DEB(printf("%02x ", b));
  644.         }
  645.           if (!mlib_store_chn_voice_msg(desc, track, optr, buf, p)) 
  646.             return 0;
  647.         }
  648.       else
  649.         {
  650.         buf[p++] = status = desc->prev_status = type;
  651.         DEB(printf("Midi message: %02x ", status));
  652.  
  653.         event_len = midi_msglen[((status >> 4) & 0xf) -8];
  654.         for (i=0;i<event_len;i++)
  655.         {
  656.             if (!(len=mlib_rdbyte(desc, &b))) return 0;
  657.             *iptr += len;
  658.             buf[p++] = b;
  659.             DEB(printf("%02x ", b));
  660.         }
  661.           if (!mlib_store_chn_voice_msg(desc, track, optr, buf, p)) 
  662.             return 0;
  663.         }
  664.     }
  665.  
  666.     DEB(printf("\n"));
  667.  
  668.     return 1;
  669. }
  670.  
  671. static int
  672. mlib_load_pass(mlib_desc *desc, mlib_track *track, int *iptr, int *optr, int len)
  673. {
  674.     int i;
  675.  
  676.     for (i=0;i<128;i++)
  677.     {
  678.         track->pgm_map[i] = -1;
  679.         track->drum_map[i] = -1;
  680.     }
  681.  
  682.     track->len = 0;
  683.     track->flags = 0;
  684.     track->init_chn = -1;
  685.     track->init_pgm = -1;
  686.     track->port = -1;
  687.     track->chn = -1;
  688.     track->chnmask = 0;
  689.     track->pgm = -1;
  690.     track->current_time = 0;
  691.     track->noteon_time = -1;
  692.     track->end_time = 0;
  693.     track->min_note = 300;
  694.     track->max_note = -1;
  695.  
  696.     *iptr = *optr = 0;
  697.     desc->prev_status = 0;
  698.  
  699.     while (*iptr<len)
  700.       if (!mlib_input_event(desc, iptr, optr, track))
  701.     {
  702.         return 0;
  703.     }
  704.  
  705.     return 1;
  706. }
  707.  
  708. mlib_track *mlib_loadtrack(mlib_desc *desc, int *end_detected)
  709. {
  710.     mlib_track *track;
  711.     char sig[5];
  712.     int dummy, len, iptr, optr, pass1events;
  713.  
  714.     *end_detected = 0;
  715.  
  716.     if (!mlib_chkdesc(desc)) return NULL;
  717.  
  718.     if ((track = (mlib_track *)malloc(sizeof(*track)))==NULL)
  719.        return (mlib_track*)mlib_seterr("Can't malloc track descriptor");
  720.  
  721.     desc->curr_trk++;
  722.  
  723.     if (desc->curr_trk >= desc->hdr.MThd_ntrk)
  724.     {
  725.         *end_detected = 1;
  726.         return (mlib_track*)mlib_seterr(
  727.             "No more tracks in the midi file");
  728.     }
  729.  
  730.     desc->trk_offs = desc->next_trk_offs;
  731.  
  732.     if (!mlib_seek(desc, desc->trk_offs))
  733.     {
  734.         free((char *)track);
  735.         return NULL;
  736.     }
  737.  
  738.     if (!mlib_rdstr(desc, sig, 4))
  739.     {
  740.         free((char *)track);
  741.         return NULL;
  742.     }
  743.  
  744.     if (strcmp(sig, "MTrk"))
  745.     {
  746.         free((char *)track);
  747.         return (mlib_track *)mlib_seterr(
  748.             "Invalid track signature (!= MTrk)");
  749.     }
  750.  
  751.     if (!mlib_rdint32(desc, &len))
  752.     {
  753.         free((char *)track);
  754.         return 0;
  755.     }
  756.  
  757.     desc->next_trk_offs = desc->trk_offs + 4 + 4 + len;
  758.  
  759.     track->events = NULL;
  760.  
  761.     if (!mlib_load_pass(desc, track, &iptr, &optr, len))
  762.     {
  763.         free((char *)track);
  764.         return NULL;
  765.     }
  766.  
  767.     pass1events = optr;
  768.  
  769. /*
  770.  *    Pass 2 actually store the messages
  771.  */
  772.  
  773.     track->events = malloc(12 * pass1events);
  774.     if (pass1events == 0) return track;    /* Empty track */
  775.  
  776.     if (!mlib_seek(desc, desc->trk_offs+4))    /* Past the MTrk */
  777.     {
  778.         free(track->events);
  779.         free((char *)track);
  780.         return NULL;
  781.     }
  782.  
  783.     if (!mlib_rdint32(desc, &dummy))
  784.     {
  785.         free(track->events);
  786.         free((char *)track);
  787.         return 0;
  788.     }
  789.  
  790.     if (!mlib_load_pass(desc, track, &iptr, &optr, len))
  791.     {
  792.         free(track->events);
  793.         free((char *)track);
  794.         return NULL;
  795.     }
  796.  
  797.     track->len = optr;
  798.  
  799.     if (optr != pass1events)
  800.        fprintf(stderr, 
  801.          "Warning: Events counts of pass 1 and 2 differ (%d/%d)\n",
  802.                 pass1events, optr);
  803.  
  804.     return track;
  805. }
  806.  
  807. void
  808. mlib_deltrack(mlib_track *track)
  809. {
  810.     if (track == NULL) return;
  811.  
  812.     if (track->events != NULL)
  813.        free(track->events);
  814.  
  815.     free((char *)track);
  816. }
  817.  
  818. mlib_desc *mlib_open(char *path)
  819. {
  820.     mlib_desc *desc;
  821.     int i;
  822.  
  823.     desc = (mlib_desc *)malloc(sizeof(*desc));
  824.     if (desc == NULL)
  825.        return (mlib_desc *)mlib_seterr("Malloc failed");
  826.  
  827.     if ((desc->fd=open(path, O_RDONLY, 0))== -1)
  828.     {
  829.         free((char *)desc);
  830.         return (mlib_desc*)mlib_syserr(path);
  831.     }
  832.  
  833.     strncpy(desc->path, path, sizeof(desc->path));
  834.  
  835.     desc->bufcnt = 0;
  836.     desc->bufp = 1;
  837.     desc->curr_trk = 0;
  838.     desc->trk_offs = 0;
  839.     desc->next_trk_offs = 0;
  840.     desc->magic = 0x121234;
  841.     desc->control_track = NULL;
  842.     desc->timesig = 0;
  843.     for (i=0;i<MAX_TRACK;i++)
  844.         desc->tracks[i] = NULL;
  845.  
  846.     if (!mlib_read_mthd(desc))
  847.     {
  848.         close(desc->fd);
  849.         free((char *)desc);
  850.         return NULL;
  851.     }
  852.  
  853.     return desc;
  854. }
  855.  
  856. void
  857. mlib_close(mlib_desc *desc)
  858. {
  859.     if (mlib_chkdesc(desc))
  860.     {
  861.         close(desc->fd);
  862.         desc->fd = -1;
  863.         free(desc);
  864.     }
  865. }
  866.  
  867. char *mlib_errmsg(void)
  868. {
  869.     return &mlib_errstring[0];
  870. }
  871.