/*
**	RA -- New "ra", reassembler
**	psl, 10/87
*/
#include <stdio.h>
#include <midi.h>

#define	MAXDBS	256		/* max hex data bytes per line */
#define	EOMD	12345		/* End-Of-Midi-Data */

int	Atmode	= 1;		/* Absolute time, using decimal time */

char *index();

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

	av0 = argv[0];
	if (argc > 1) {
	    for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
		    if (argv[i][1] == 'r')	/* use relative time bytes */
			Atmode = 0;
		    else {
			fprintf(stderr, "Usage: %s [-rel] [files or stdin]\n",
			 av0);
			exit(2);
		    }
		}
	    }
	    for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-')
		    continue;
		if (f = sopen(argv[i],"r")) {
		    reassemble(f);
		    sclose(f);
		} else
		    perror(argv[i]);
	    }
	} else
	    reassemble(stdin);
	exit(0);
}

reassemble(f)
FILE *f;
{
	char *c, s[BUFSIZ];
	int cmd[MAXDBS], tbflg;
	double time;

	while (fgets(s, sizeof s, f)) {
	    if (c = index(s, ';')) {
		*c++ = '\0';
		parse_midi(cmd, &tbflg, s);
		if (Atmode && tbflg)
		    sscanf(c, "%lf", &time);
		put_cmd(cmd, tbflg, time);
	    } else if (*s)
		fprintf(stderr, "%s: format error: %s", av0, s);
	}
}

parse_midi(obuf, tbflgp, ibuf)
int *obuf, *tbflgp; 
char *ibuf;
{
	register char *cp;
	register int i;

	cp = ibuf;
	*tbflgp = (cp[0] == '\t' || (cp[0] == ' ' && cp[1] == ' '))? 0 : 1;
	for (i = 0; i < MAXDBS; i++) {
	    for (; *cp && *cp <= ' '; cp++);
	    if (*cp == '\0')
		break;
	    sscanf(cp, "%x", &obuf[i]);
	    for (; *cp > ' '; cp++);
	}
	obuf[i] = EOMD;
}

put_cmd(cmd, tbflg, time)
int *cmd, tbflg;
double time;
{
	static long now;
	long ticks, interval;
	int i;

	i = 0;
	if (Atmode) {
	    if (cmd[0] == RT_TCIP)
		return;
	    if (tbflg) {
		ticks = time * MPU_TPS(MPU_DEFAULT_TEMPO,MPU_DEFAULT_TIME_BASE);
		interval = ticks - now;
		now = ticks;
		i = MPU_CLOCK_PERIOD;
		while (interval >= i) {
		    putchar(0xf8);
		    interval -= i;
		}
		putchar(interval);
		i = 1;		/* skip old timing byte */
	    }
	}
	for (; i < MAXDBS && cmd[i] != EOMD; i++)
	    putchar(cmd[i]);
}
