168d /**********************************************************/ /* MIDEXT */ /* Extracts Text/SysEx/SP Generic bank from a MIDI file */ /* 951110 Now reads SysEx and text messages > 64K */ /* 951112 Speeded up extraction drastically by reading */ /* the whole file into memory before processing */ /**********************************************************/ #include #include #include #include #include #include #include #include #include "midifile.h" #include unsigned int midf, destf; char destfname[80]; int data_exists = 0; unsigned char inbyte; unsigned long firstnote_dtime = 0xffffffff; int sysex_after_firstnote = 0; unsigned long sysex_len = 0L; int extmode = 0; int oldtype = 0xffff; #define TEXT 0 #define SYSEX 1 #define BANK 2 main(int argc,char **argv) { struct ffblk ffblk; char fname[80], extension[5]; int namelen; int done, found; if(argc > 2) { initfuncs(); switch(argv[2][0]){ case 't' : extmode = TEXT; break; case 's' : extmode = SYSEX; break; case 'b' : extmode = BANK; break; } switch(extmode) { case TEXT: strcpy(extension, ".TXT"); break; case SYSEX: strcpy(extension, ".SYX"); break; case BANK: strcpy(extension, ".C30"); break; } strcpy(fname, argv[1]); if(strncmp(fname, "*.", 2) != 0) { if(! strchr(fname, '.')) strcat(fname, ".MID"); namelen = strchr(fname, '.') - fname; strncpy(destfname, fname, namelen); destfname[namelen] = 0; strcat(destfname, extension); extract(fname); printf("OK.\n"); } else { done = findfirst(fname, &ffblk, 0); found = 0; while(! done) { namelen = strchr(ffblk.ff_name,'.') - ffblk.ff_name; strncpy(destfname, ffblk.ff_name, namelen); destfname[namelen] = 0; strcat(destfname, extension); extract(ffblk.ff_name); done = findnext(&ffblk); found++; } if(found) printf("OK.\n"); else printf("No matching files found\n"); } } else { printf("MIDEXT v2.0 Extracts text or SysEx from a standard MIDI file\n\n"); printf("usage: midext \n"); printf("\n"); printf(" t extract text\n"); printf(" s extract SysEx to raw MIDIEX file\n"); printf(" b extract SysEx to SP Gold Generic instrument bank file\n"); printf("\n"); printf("wildcards allowed\n"); } } extract(char *fname) { data_exists = 0; sysex_after_firstnote = 0; sysex_len = 0L; oldtype = 0xffff; if((midf = _open(fname, O_BINARY | O_RDONLY)) != -1) { destf = _creat(destfname, 0); if(extmode == BANK) { _write(destf, c30hdr, sizeof(c30hdr)); /* Write bank file header */ _write(destf, &sysex_len, 4); /* Dummy write */ } mfread(); _close(midf); if(data_exists) { if(extmode == BANK) { lseek(destf, (unsigned long)sizeof(c30hdr), SEEK_SET); _write(destf, &sysex_len, 4); /* Write REAL SysEx length */ } _close(destf); if((sysex_after_firstnote) && (extmode != TEXT)) printf("Warning: SysEx data after first note played in file %s\n", strupr(fname)); } else { printf("No data in %s\n", fname); _close(destf); remove(destfname); } } else { printf("MID file not found!\n"); exit(1); } } error(unsigned char *s) { fprintf(stderr,"Error: %s\n",s); exit(1); } mext_noteon(chan,pitch,vol) { if(firstnote_dtime == 0xffffffff) firstnote_dtime = mf_currtime; } mext_sysex(unsigned long leng, unsigned char far *mess) { static unsigned char sysex = 0xf0; if(extmode == TEXT) return; if(! data_exists) data_exists = 1; if(mf_currtime > firstnote_dtime) sysex_after_firstnote = 1; _write(destf, &sysex, 1); bufwrite(mess, leng); sysex_len += (++leng); } mext_metatext(int type, unsigned long leng, unsigned char far *mess) { static char *ttype[] = { NULL, "Text Event", /* type=0x01 */ "Copyright Notice", /* type=0x02 */ "Sequence/Track Name", "Instrument Name", /* ... */ "Lyric", "Marker", "Cue Point", /* type=0x07 */ "Unrecognized" }; int unrecognized = (sizeof(ttype)/sizeof(char *)) - 1; unsigned long n, c; unsigned char far *p = mess; char msgbuf[81]; int i; if(extmode != TEXT) return; if(! data_exists) data_exists = 1; if ( type < 1 || type > unrecognized ) type = unrecognized; if(oldtype != type) { oldtype = type; sprintf(msgbuf,"\r\n Type: %s\r\n\r\n", ttype[type]); _write(destf, msgbuf, strlen(msgbuf)); } for ( n = 0L; n < leng; n++ ) { c = *p++; sprintf(msgbuf, (isprint(c)||isspace(c)) ? "%c" : "\\0x%02x" , c); _write(destf, msgbuf, strlen(msgbuf)); } sprintf(msgbuf, "\r\n"); _write(destf, msgbuf, strlen(msgbuf)); } bufwrite(unsigned char far *buf, unsigned long len) { union REGS regs; struct SREGS segregs; unsigned int bytes_to_write; if(FP_OFF(buf) > 0x8000) { FP_SEG(buf) += 0x0800; FP_OFF(buf) -= 0x8000; } segregs.ds = FP_SEG(buf); while(1) { regs.h.ah = 0x40 ; regs.x.bx = destf; regs.x.dx = FP_OFF(buf); 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_error = error; mf_noteon = mext_noteon; mf_sysex = mext_sysex; mf_text = mext_metatext; } . 0