static int read16bit(void) { int c1, c2; c1 = egetc(); c2 = egetc(); return to16bit(c1, c2); }
static long read32bit(void) { int c1, c2, c3, c4; c1 = egetc(); c2 = egetc(); c3 = egetc(); c4 = egetc(); return to32bit(c1, c2, c3, c4); }
static long readvarinum(void) { long value; int c; c = egetc(); value = c; if (c & 0x80) { value &= 0x7f; do { c = egetc(); value = (value << 7) + (c & 0x7f); } while (c & 0x80); } return(value); }
static void readheader(void) /* read a header chunk */ { int format, ntrks, division; if (readmt("MThd") == EOF) return; Mf_toberead = read32bit(); format = read16bit(); ntrks = read16bit(); division = read16bit(); if (Mf_header) (*Mf_header)(format,ntrks,division); /* flush any extra stuff, in case the length of header is not 6 */ while (Mf_toberead > 0) (void) egetc(); }
line readline(FILE *istream, FILE *ostream) { int c, c1; char buf[100]; int i; c = egetc(istream); if (c==EOF) return ENDFILE; if ( c == '#' ) { if ( ignore_shebang ) { c1 = egetc(istream); if ( c1 == '!' ) { while (c=egetc(istream), !isLineTerm(c)) ; return SHEBANG; } myputc(c, ostream); c=c1; } if ( leavecpp ) { myputc(c, ostream); while (c=egetc(istream), !isLineTerm(c)) myputc(c,ostream); myputc('\n',ostream); return HASH; } } if (c==DEFNCHAR) { myputc(' ',ostream); while (c=egetc(istream), !isLineTerm(c)) myputc(c,ostream); myputc('\n',ostream); return DEFN; } if (!crunchnl) myputc('\n',ostream); while (isWhitespace(c)) c=egetc(istream); if (isLineTerm(c)) return BLANK; i = 0; buf[i++] = c; while (c=egetc(istream), !isLineTerm(c)) if (i < sizeof buf - 1) buf[i++] = c; while(i > 0 && isspace(buf[i-1])) i--; buf[i] = 0; if (strcmp(buf, BEGINCODE) == 0) return BEGIN; if (strcmp(buf, ENDCODE) == 0) return END; #ifdef PSEUDOCODE else if (strcmp(buf, BEGINPSEUDOCODE) == 0) return PSEUDO; #endif else return TEXT; }
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); }