static void badbyte(int c) { char buff[32]; (void) sprintf(buff,"unexpected byte: 0x%02x",c); mferror(buff); }
/* write a single character and abort on error */ static int eputc(unsigned char c) { int return_val; if ((Mf_putc) == NULLFUNC) { mferror("Mf_putc undefined"); return(-1); } return_val = (*Mf_putc)(c); if (return_val == EOF) mferror("error writing"); Mf_numbyteswritten++; return(return_val); }
DECLSPEC void mfread(void) /* The only non-static function in this file. */ { if ( Mf_getc == NULLFUNC ) mferror("mfread() called without setting Mf_getc"); readheader(); while (readtrack()); }
static int egetc(void) /* read a single character and abort on EOF */ { int c = (*Mf_getc)(); if (c == EOF) mferror("premature EOF"); Mf_toberead--; return(c); }
void mfread() /* The only non-static function in this file. */ { int track; if ( Mf_getc == NULLFUNC ) mferror("mfread() called without setting Mf_getc"); readheader(); track =1; while (readtrack()) {track++; if(track>ntrks) break; } }
void midifile() /* The only non-static function in this file. */ { int ntrks; midifile_error = 0; if ( Mf_getc == 0 ) { mferror("mf.h() called without setting Mf_getc"); return; } ntrks = readheader(); if (midifile_error) return; if ( ntrks <= 0 ) { mferror("No tracks!"); /* no need to return since midifile_error is set */ } while ( ntrks-- > 0 && !midifile_error && !check_aborted()) readtrack(); if (check_aborted()) { mferror("Midifile read aborted\n\ \tthe rest of your file will be ignored.\n"); if (abort_flag == BREAK_LEVEL) abort_flag = 0; } }
static int readmt(char *s) /* read through the "MThd" or "MTrk" header string */ { int n = 0; char *p = s; int c; while (n++<4 && (c=(*Mf_getc)()) != EOF) { if (c != *p++) { char buff[32]; (void) strcpy(buff,"expecting "); (void) strcat(buff,s); mferror(buff); } } return(c); }
void mfreadtrk(itrack) /* The only non-static function in this file. */ { int track,ok; if ( Mf_getc == NULLFUNC ) mferror("mfprocess() called without setting Mf_getc"); readheader(); track =1; ok = 1; for (track=1;track<=ntrks && ok == 1;track++) {if (track == itrack) ok = readtrack(); else ok = skiptrack(); } }
static void biggermsg(void) { char *newmess; char *oldmess = Msgbuff; int oldleng = Msgsize; Msgsize += MSGINCREMENT; newmess = (char *)malloc((unsigned)(sizeof(char)*Msgsize)); if (newmess == NULL) mferror("malloc error!"); /* copy old message into larger new one */ if (oldmess != NULL) { register char *p = newmess; register char *q = oldmess; register char *endq = &oldmess[oldleng]; for (; q!=endq; p++, q++) *p = *q; free(oldmess); } Msgbuff = newmess; }
static int readtrack(void) /* read a track chunk */ { /* This array is indexed by the high half of a status byte. It's */ /* value is either the number of bytes needed (1 or 2) for a channel */ /* message, or 0 (meaning it's not a channel message). */ static int chantype[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 through 0x70 */ 2, 2, 2, 2, 1, 1, 2, 0 /* 0x80 through 0xf0 */ }; long lookfor; int c, c1, type; int sysexcontinue = 0; /* 1 if last message was an unfinished sysex */ int running = 0; /* 1 when running status used */ int status = 0; /* status value (e.g. 0x90==note-on) */ int needed; if (readmt("MTrk") == EOF) return(0); Mf_toberead = read32bit(); Mf_currtime = 0; if (Mf_starttrack) (*Mf_starttrack)(); while (Mf_toberead > 0) { Mf_currtime += readvarinum(); /* delta time */ c = egetc(); if (sysexcontinue && c != 0xf7) mferror("didn't find expected continuation of a sysex"); if ((c & 0x80) == 0) { /* running status? */ if (status == 0) mferror("unexpected running status"); running = 1; c1 = c; c = status; } else if (c < 0xf0) { status = c; running = 0; } needed = chantype[(c>>4) & 0xf]; if (needed) { /* ie. is it a channel message? */ if (! running) c1 = egetc(); chanmessage(status, c1, (needed>1) ? egetc() : 0); continue;; } switch (c) { case 0xff: /* meta event */ type = egetc(); lookfor = Mf_toberead - readvarinum(); msginit(); while (Mf_toberead > lookfor) msgadd(egetc()); metaevent(type); break; case 0xf0: /* start of system exclusive */ lookfor = Mf_toberead - readvarinum(); msginit(); msgadd(0xf0); while (Mf_toberead > lookfor) msgadd(c = egetc()); if (c == 0xf7 || Mf_nomerge == 0) sysex(); else sysexcontinue = 1; /* merge into next msg */ break; case 0xf7: /* sysex continuation or arbitrary stuff */ lookfor = Mf_toberead - readvarinum(); if (! sysexcontinue) msginit(); while (Mf_toberead > lookfor) msgadd(c=egetc()); if ( ! sysexcontinue ) { if (Mf_arbitrary) (*Mf_arbitrary)(msgleng(),msg()); } else if (c == 0xf7) { sysex(); sysexcontinue = 0; } break; default: badbyte(c); break; } } if (Mf_endtrack) (*Mf_endtrack)(); return(1); }