/* ** DACK - Check .da files for time sequence, note on/off, & misc. ** psl 9/85 */ #include #define MAXCHAN 16 #define MAXNOTE 128 char *nnames[] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", }; char *nn(); int verbose = 0; extern double atof(); main(argc, argv) char *argv[]; { register int i, n; FILE *fp; n = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { n++; continue; } switch (argv[i][1]) { case 'v': verbose++; break; default: fprintf(stderr, "Usage: %s [-v] [files or stdin]\n", argv[0]); exit(2); } } if (n == 0) dack(stdin, ""); else { for (i = 1; i < argc; i++) { if (argv[i][0] == '-') continue; if ((fp = fopen(argv[i], "r")) == NULL) { perror(argv[i]); continue; } dack(fp, n > 1? argv[i] : ""); fclose(fp); } } } dack(fp, file) FILE *fp; char *file; { register int line, note, chan, active, maxact; char buf[128]; int key[MAXCHAN][MAXNOTE], kl[MAXCHAN][MAXNOTE]; double time, lastime; active = maxact = 0; lastime = 0.; for (note = MAXNOTE; --note >= 0; ) for (chan = MAXCHAN; --chan >= 0; ) key[chan][note] = 0; for (line = 1; fgets(buf, sizeof buf, fp) != NULL; line++) { if (buf[0] == '\n') continue; time = atof(&buf[13]); if (time < lastime) printf("%s time %g follows %g (line %d)\n", file, time, lastime, line); lastime = time; if (buf[3] == '9') chan = hex(buf[4]); if (buf[30] == 'k' && buf[31] == 'o') { if (buf[32] == 'n') { note = hex(buf[6]) * 16 + hex(buf[7]); if (key[chan][note] & verbose) printf("%s multiple key-on %s 0x%x (line %d)\n", file, nn(note), note, line); else { if (active++ >= 16) printf("%s %d voices used (line %d)\n", file, active, line); if (active > maxact) maxact = active; } key[chan][note]++; kl[chan][note] = line; } else if (buf[32] == 'f') { note = hex(buf[6]) * 16 + hex(buf[7]); if (key[chan][note] == 0) printf("%s extra key-off %s 0x%x (line %d)\n", file, nn(note), note, line); else { --key[chan][note]; --active; } } else printf("%s Weird code - ko%c%c (line %d)\n", file, buf[32], buf[33], line); } } for (note = MAXNOTE; --note >= 0; ) for (chan = MAXCHAN; --chan >= 0; ) if (key[chan][note]) printf("%s key %s 0x%x left on since line %d\n", file, nn(note), note, kl[chan][note]); if (verbose) printf("%s Max simultaneous notes = %d\n", file, maxact); } char * nn(note) { register char *bp, *cp, oct; static char buf[5]; for (bp = buf, cp = nnames[note%12]; *bp = *cp++; bp++); oct = note / 12 - 1; if (oct < 0) { *bp++ = '-'; oct = -oct; } *bp++ = '0' + oct; *bp++ = '\0'; return(buf); } hex(c) { if (c >= '0' && c <= '9') return(c - '0'); if (c >= 'a' && c <= 'f') return(10 + c - 'a'); if (c >= 'A' && c <= 'F') return(10 + c - 'A'); return(0); }