/*
** TEMPO -- Filter MIDI data, modifying the tempo in various ways.
** See syntax(), below, for details.	psl 7/87
*/
#include <stdio.h>
#include <midi.h>

int	Period = MPU_CLOCK_PERIOD;
int	Mord;
double	Factor	= 1.0;
double	Delta	= 0.0;

extern	double	atof();

syntax(argv0)
char	*argv0;
{
	fprintf(stderr, "Usage: %s [-f#.#] [-s#.#] [-d#.#] [files or stdin]\n",
	 argv0);
	fprintf(stderr, "-f2.0\tmakes the piece twice as fast (shorter).\n");
	fprintf(stderr, "-s2.0\tmakes the piece twice as slow (longer).\n");
	fprintf(stderr, "-s0.5 == -f2.0\n");
	fprintf(stderr, "-f1. -d0.1\taccelerates by .1 every 480 MPU clocks\n");
	fprintf(stderr, "-s1. -d0.1\tdecelerates by .1 every bar\n");
	fprintf(stderr, "-s0.5 -d.1 != -f2.0 -d-.1\n");
	fprintf(stderr, "-f-1.\tdoesn't work, so be wary of -d-#.\n");
	exit(2);
}

main(argc, argv)
char	*argv[];
{
	int i, flg;
	FILE *fp;

	for (i = 1; i < argc; i++) {
	    if (argv[i][0] == '-') {
		switch (argv[i][1]) {
		case 'd':
		    Delta = atof(&argv[i][2]);
		    break;
		case 'f':
		    Factor = atof(&argv[i][2]);
		    Mord = 0;
		    break;
		case 's':
		    Factor = atof(&argv[i][2]);
		    Mord = 1;
		    break;
		default:
		    syntax(argv[0]);
		}
	    }
	}
	flg = 0;
	for (i = 1; i < argc; i++) {
	    if (argv[i][0] != '-') {
		if (fp = sopen(argv[i], "r")) {
		    tempo(fp);
		    sclose(fp);
		} else {
		    perror(argv[i]);
		    syntax(argv[0]);
		}
		flg++;
	    }
	}
	if (flg == 0)
	    tempo(stdin);
	exit(0);
}

tempo(ifp)
FILE	*ifp;
{
	long now = 0;
	double fact;
	MCMD *mp;

	while (mp = getmcmd(ifp, now)) {
	    now = mp->when;
	    fact = Factor + (now * Delta) / 480.;
	    if (fact <= 0.)
		break;
	    if (Mord)
		mp->when = (long) (now * fact + 0.5);
	    else
		mp->when = (long) (now / fact + 0.5);
	    putmcmd(stdout, mp);
	}
}
