/* MAKEMIDI.C Makes MIDI samples of all patches for GM, GS and XG from a table stored in a text file and 3 MIDI model files. Also creates a table in HTML format with links to those samples. E.Hurtebis, France 2004 */ #include #include #include #include char *write_midi(int num, int msb, int lsb, char *name_inst, char *typ); void write_html(FILE *out, int num, int msb, int lsb, char *name_inst, char *typ, char *file_midi); int main() { char *file_txt="inst.txt"; /* source text file (instruments) */ char *file_html="inst.htm"; /* output HTML file */ char *file_midi; /* output MIDI sample file */ FILE *f, *html; char s[80]; char typ[3]; char name[80]; int patch_num, msb, lsb; int nbytes; unsigned nline=0; if (! (f=fopen(file_txt, "rt"))) { perror(file_txt); exit(1); } if (! (html=fopen(file_html, "wt"))) { perror(file_html); exit(1); } fprintf(html, "\n\n
\n\n"); while (fgets(s, sizeof(s), f)) { nline++; msb=lsb=0; if (*s<'0' || *s>'2') continue; if (*s=='0') if (sscanf(s, "%s %d %n", typ, &patch_num, &nbytes) != 2) { badf: fprintf(stderr, "Line %u: Bad format\patch_num", nline); exit(1); } if (*s=='1') if (sscanf(s, "%s %d %d %n", typ, &patch_num, &msb, &nbytes) != 3) goto badf; if (*s=='2') if (sscanf(s, "%s %d %d %d %n", typ, &patch_num, &msb, &lsb, &nbytes) != 4) goto badf; strcpy(name, s+nbytes); /* instrument name */ name[strlen(name)-1] = 0; /* removes \n */ file_midi = write_midi(patch_num, msb, lsb, name, typ); printf("%s: %s\patch_num", file_midi, name); write_html(html, patch_num, msb, lsb, name, typ, file_midi); } fclose(f); fprintf(html, "
\n
\n\n\n"); fclose(html); return 0; } char *write_midi(int num, int msb, int lsb, char *name_inst, char *typ) { FILE *f; char track_name[61]; char s[100], t[30]; static char file_midi[40]; char buf[512]; int nbuf; char *model_midi; strcpy(s, name_inst); if (strcmp(typ, "0") == 0) { sprintf(t, " (GM) %d", num); sprintf(file_midi, "%03d___GM.mid", num); model_midi="gm.mid"; } else if (strcmp(typ, "1") == 0) { sprintf(t, " (GS) %d %d", num, msb); sprintf(file_midi, "%03d_%02XGS.mid", num, msb); model_midi="gs.mid"; } else if (strcmp(typ, "1a") == 0) { sprintf(t, " (88) %d %d", num, msb); sprintf(file_midi, "%03d_%02X88.mid", num, msb); model_midi="gs.mid"; } else if (strcmp(typ, "1b") == 0) { sprintf(t, " (MT) %d %d", num, msb); sprintf(file_midi, "%03d_%02XMT.mid", num, msb); model_midi="gs.mid"; } else if (strcmp(typ, "2") == 0) { sprintf(t, " (XG) %d %d %d", num, msb, lsb); sprintf(file_midi, "%03d%02X%02XX.mid", num, msb, lsb); model_midi="xg.mid"; } else { sprintf(t, " (??) %d %d %d", num, msb, lsb); sprintf(file_midi, "%03d_%02X_%02X.mid", num, msb, lsb); model_midi="gs.mid"; } strcat(s, t); sprintf(track_name, "%-*.*s", sizeof(track_name)-1, sizeof(track_name)-1, s); if (! (f=fopen(model_midi, "rb"))) { perror(model_midi); exit(1); } nbuf=fread(buf, 1, sizeof(buf), f); /* reads model file */ fclose(f); /* modifies content: track name, Bank Select (MSB & LSB), patch number */ memcpy(buf+26, track_name, strlen(track_name)); buf[133] = msb; buf[136] = lsb; buf[139] = num-1; /* 0=piano */ assert(strlen(file_midi) <= 12); /* DOS 8.3 Filenames */ if (! (f=fopen(file_midi, "wb"))) { perror(file_midi); exit(1); } if (fwrite(buf, 1, nbuf, f) != nbuf) /* writes MIDI file */ { fprintf(stderr, "Disk full ?\n"); exit(1); } fclose(f); return file_midi; } void write_html(FILE *out, int num, int msb, int lsb, char *name_inst, char *typ, char *file_midi) { static int num0=0; /* to write Patch number once */ if (num0 != num) fprintf(out, "\n", num); /* comment */ /* writes a Row with 5 Columns */ fprintf(out, "\n"); if (num0 == num) fprintf(out, " \n"); else fprintf(out, " %03d\n", num); if (*typ=='0') fprintf(out, " \n"); else fprintf(out, " %03d\n", msb); if (*typ<'2') fprintf(out, " \n"); else fprintf(out, " %03d\n", lsb); fprintf(out, " %s\n", file_midi, name_inst); if (strcmp(typ, "0") == 0) fprintf(out, " GM\n"); else if (strcmp(typ, "1") == 0) fprintf(out, " GS\n"); else if (strcmp(typ, "1a") == 0) fprintf(out, " 88\n"); else if (strcmp(typ, "1b") == 0) fprintf(out, " MT\n"); else if (strcmp(typ, "2") == 0) fprintf(out, " XG\n"); fprintf(out, "\n"); num0 = num; }