/* ** CS -- Measure Chord Spread ** psl 12/88 */ #include #include #define MAXCHAN MIDI_MAX_CHANS #define MAXKEY 128 #define MAXDEL 1000 int Clock = 100; /* beats / minute (m.m.) */ int Cs[MAXDEL]; /* how many at each delay (msecs) */ double Onset[MAXKEY]; /* when key played (seconds) */ syntax(prog) char *prog; { fprintf(stderr, "Usage: %s [-t#] [files or stdin]\n", prog); fprintf(stderr, "-t#\tcalc times based on given clock rate (default 100)\n"); exit(2); } main(argc, argv) char *argv[]; { char fname[32], buf[1024]; int i, n, fh; FILE *f; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 't': Clock = atoi(&argv[i][2]); break; default: syntax(argv[0]); } } } n = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { if ((f = sopen(argv[i], "r")) != NULL) { cs(f); sclose(f); n++; } else perror(argv[i]); } } if (n == 0) { sprintf(fname, "/tmp/cs%d", getpid()); if ((fh = creat(fname, 0644)) < 0) { perror(fname); exit(1); } while ((n = read(0, buf, sizeof buf)) > 0) write(fh, buf, n); close(fh); if (!(f = fopen(fname, "r"))) { perror(fname); exit(1); } unlink(fname); cs(f); } } cs(ifp) FILE *ifp; { int status, type, key, vel; int k, lastb, cb, ds; long now; double secs, isecs, rsecs; MCMD *mp; for (key = MAXKEY; --key >= 0; Onset[key] = -1.0); lastb = 0; secs = 0; for (now = 0L; mp = getmcmd(ifp, now); ) { now = mp->when; lastb += 1; /* compensate for time-tag */ cb = ftell(ifp); isecs = now / (2. * Clock); /* when it's supposed to be */ rsecs = secs + (cb - lastb) * 0.00032; /* transmission delay */ /****printf("now=%d, isecs=%g, ", now, isecs); /****printf("secs=%g, lastb=%d, cb=%d, rsecs=%g\n", secs, lastb, cb, rsecs); ****/ lastb = cb; secs = (isecs > rsecs)? isecs : rsecs; status = mp->cmd[0]; type = (status & M_CMD_MASK); if (type == CH_KEY_OFF) { type = CH_KEY_ON; mp->cmd[2] = 0; } if (type == CH_KEY_ON) { /* calc key, & vel */ key = mp->cmd[1]; vel = mp->cmd[2]; Onset[key] = -1.0; if (vel) { for (k = MAXKEY; --k >= 0; ) { if (Onset[k] >= 0.) { ds = (secs - Onset[k]) * 1000. + 0.5; /****/if (ds == 0) /****/ printf("now=%d, isecs=%g, rsecs=%g, secs=%g, key=%d, Onset[%d]=%g\n", /****/ now, isecs, rsecs, secs, key, k, Onset[k]); if (0 <= ds && ds < MAXDEL) Cs[ds]++; } } Onset[key] = secs; } } } printf("msec\tnumber\n"); for (ds = MAXDEL; --ds >= 0; ) if (Cs[ds] > 0) printf("%3d\t%4d\n", ds, Cs[ds]); }