/*
**	CS -- Measure Chord Spread
**	psl 12/88
*/

#include <stdio.h>
#include <midi.h>

#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]);
}
