1c6d /* SYXINS Inserts SysEx in MIDI file */ #define NULLFUNC 0 #include #include #include #include #include #include char *strcpy(), *strcat(); void exit(), free(); unsigned char syxfname[80], midfname[80]; unsigned int syxf, midf, tmpf; unsigned long syxlen; unsigned int syxfmt; int mf_format; #define MIDIEX 0 #define BANK 1 int (*mf_getc)() = NULLFUNC; int (*mf_putc)() = NULLFUNC; int (*mf_error)() = NULLFUNC; unsigned long mf_toberead = 0L; unsigned long bufread(unsigned int handle, unsigned long buflen); long readvarinum(); long read32bit(); long to32bit(); int writevarinum(unsigned long num); void write16bit(unsigned int val); void write32bit(unsigned long val); unsigned char far *buff = NULL; unsigned int bufsegp; unsigned long allocated; unsigned char inbyte; main(int argc, char **argv) { unsigned int max_para; unsigned long fpos1, fpos2; int bytecount; if(argc > 2) { strcpy(syxfname, argv[2]); strcpy(midfname, argv[1]); if(strstr(strupr(syxfname), ".C30")) syxfmt = BANK; else { if(strstr(strupr(syxfname), ".SYX")) syxfmt = MIDIEX; else { printf("Error: .C30 or .SYX extension required for SysEx file\n"); exit(1); } } if(! strstr(strupr(midfname), ".MID")) strcat(midfname, ".MID"); if((syxf = _open(syxfname, O_BINARY|O_RDONLY)) == -1) { printf("Error opening %s!\n", syxfname); exit(1); } syxlen = filelength(syxf); if(syxfmt == BANK) syxlen -= 4743L; if((midf = _open(midfname, O_BINARY|O_RDONLY)) == -1) { printf("Error opening %s!\n", midfname); exit(1); } tmpf = _creat("SYXINS.TMP", 0); initfuncs(); max_para = allocmem(0xffff, &bufsegp); /* Allocate all but 1K memory max_para -= 16; for SysEx buffer */ allocated = (unsigned long)max_para * 16L; allocmem(max_para, &bufsegp); buff = MK_FP(bufsegp, 0); readheader(); if(mf_format == 1) /* If format = 1 read past 1st track */ readtrack(); readmt(); mf_toberead = read32bit(); fpos1 = tell(tmpf); /* Save position where to insert new /* track length value */ lseek(tmpf, 4L, SEEK_CUR); /* Skip over track length for now */ bytecount = writevarinum(0L); /* Delta time */ fileputc(0xf0); bytecount += writevarinum(syxlen-1L); fpos2 = tell(tmpf); mf_toberead += (syxlen + (unsigned long)bytecount); lseek(tmpf, fpos1, SEEK_SET); /* Go back and fill in new tracklen */ write32bit(mf_toberead); lseek(tmpf, fpos2, SEEK_SET); if(syxfmt == BANK) lseek(syxf, 4743L, SEEK_SET); /* Skip header if bank file */ lseek(syxf, 1L, SEEK_CUR); /* Skip first byte (0xf0) */ bufread(syxf, syxlen - 1L); bufwrite(syxlen - 1L); /* Write SysEx to new file */ bufwrite(bufread(midf, 0xffffffff)); /* Append rest of MIDI file */ _close(syxf); _close(midf); _close(tmpf); remove(midfname); rename("SYXINS.TMP", midfname); freemem(bufsegp); printf("SysEx inserted OK!\n"); /* We're done! */ } else { printf("SYXINS v1.0 Inserts SysEx into a standard MIDI file\n"); printf("usage: syxins \n"); } } error(unsigned char *s) { fprintf(stderr,"Error: %s\n",s); exit(1); } readmt() /* read through the "MThd" or "MTrk" header string */ { bufread(midf, 4L); bufwrite(4L); } readheader() /* read a header chunk */ { bufread(midf, 4L); bufwrite(4L); mf_toberead = read32bit(); write32bit(mf_toberead); mf_format = read16bit(); /* Get format of MIDI file */ write16bit(mf_format); bufread(midf, mf_toberead); bufwrite(mf_toberead); } readtrack() /* read a track chunk */ { readmt(); mf_toberead = read32bit(); write32bit(mf_toberead); bufread(midf, mf_toberead); bufwrite(mf_toberead); } to16bit(int c1, int c2) { return ((c1 & 0xff ) << 8) + (c2 & 0xff); } read16bit() { int c1, c2; c1 = egetc(); c2 = egetc(); return to16bit(c1,c2); } long to32bit(c1,c2,c3,c4) { long value = 0L; value = (c1 & 0xff); value = (value<<8) + (c2 & 0xff); value = (value<<8) + (c3 & 0xff); value = (value<<8) + (c4 & 0xff); return (value); } long read32bit() { int c1, c2, c3, c4; c1 = egetc(); c2 = egetc(); c3 = egetc(); c4 = egetc(); return to32bit(c1,c2,c3,c4); } writevarinum(unsigned long value) { unsigned long buffer; int bytecount; bytecount = 0; buffer = value & 0x7f; while((value >>= 7) > 0) { buffer <<= 8; buffer |= 0x80; buffer += (value & 0x7f); } while(1) { eputc((unsigned)(buffer & 0xff)); bytecount++; if(buffer & 0x80) buffer >>= 8; else return bytecount; } } void write16bit(unsigned int data) { eputc((unsigned)((data & 0xff00) >> 8)); eputc((unsigned)(data & 0xff)); } void write32bit(unsigned long data) { eputc((unsigned)((data >> 24) & 0xff)); eputc((unsigned)((data >> 16) & 0xff)); eputc((unsigned)((data >> 8 ) & 0xff)); eputc((unsigned)(data & 0xff)); } filegetc() { if(! _read(midf, &inbyte, 1)) return EOF; else return((int)inbyte); } fileputc(int outbyte) { unsigned char c; c = (unsigned char)outbyte; if(_write(tmpf, &c, 1) == -1) return EOF; else return 0; } egetc() /* read a single character and abort on EOF */ { int c = (*mf_getc)(); if ( c == EOF ) (*mf_error)("premature EOF"); mf_toberead--; return(c); } eputc(c) unsigned char c; { int return_val; if((mf_putc) == NULLFUNC) { mf_error("mf_putc undefined"); return(-1); } return_val = (mf_putc)(c); if ( return_val == EOF ) mf_error("error writing"); return(return_val); } unsigned long bufread(unsigned int handle, unsigned long len) { union REGS regs; struct SREGS segregs; unsigned int bytes_to_read; unsigned long bytes_read; segregs.ds = FP_SEG(buff); bytes_read = 0L; while(1) { regs.h.ah = 0x3f ; regs.x.bx = handle; regs.x.dx = 0; if(len >= 0x8000L) bytes_to_read = 0x8000; else bytes_to_read = (unsigned int)len; regs.x.cx = bytes_to_read; intdosx(®s, ®s, &segregs); bytes_read += (unsigned long)(regs.x.ax); if(regs.x.ax < bytes_to_read) return bytes_read; if(bytes_to_read < 0x8000) break; len -= 0x8000L; if(len == 0L) break; segregs.ds += 0x0800; } return 0L; } bufwrite(unsigned long len) { union REGS regs; struct SREGS segregs; unsigned int bytes_to_write; segregs.ds = FP_SEG(buff); while(1) { regs.h.ah = 0x40 ; regs.x.bx = tmpf; regs.x.dx = 0; if(len >= 0x8000L) bytes_to_write = 0x8000; else bytes_to_write = (unsigned int)len; regs.x.cx = bytes_to_write; intdosx(®s, ®s, &segregs); if(bytes_to_write < 0x8000) break; len -= 0x8000L; if(len == 0L) break; segregs.ds += 0x0800; } } initfuncs() { mf_getc = filegetc; mf_putc = fileputc; mf_error = error; } . 0