/*
**	VEGPLOT -- Plot EG & Pitch EG waveforms for DX/TX voices
** For each Yamaha system exclusive voice bulk data file, generate input
** for graph.  Handles 1-voice dumps.
**	psl, 12/88
*/

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

#define	MAXBUF	(6+DX7VOXLEN+2)	/* actually we only need 6+DX732VOXLEN+2 */

#define p fprintf

main(argc,argv)
char *argv[];
{
	int i, n, fh;

	n = 0;
	for (i = 1; i < argc; i++) {
	    if (argv[i][0] == '-') {
		switch (argv[i][1]) {
		default:
		    p(stderr, "Usage: %s [files or stdin]\n", argv[0]);
		    exit(2);
		}
	    } else
		n++;
	}
	if (n == 0)
	    n = pr(0, "stdin", stdout);
	else {
	    n = 0;
	    for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-')
		    continue;
		if ((fh = open(argv[i], 0)) < 0)
		    perror(argv[i]);
		else {
		    n += pr(fh, argv[i], stdout);
		    close(fh);
		}
	    }
	}
	exit(n? 0 : 1);
}

pr(ifh, name, ofp)
char	*name;
FILE	*ofp;
{
	unsigned char buf[MAXBUF];
	int fmt;
	Dx7Voice v;

	while (read(ifh, buf, 1) == 1 && *buf != SX_CMD);
	if (*buf != SX_CMD) {
	    fprintf(stderr, "No system exclusive dump found in %s\n", name);
	    return(0);
	}
	if (read(ifh, &buf[1], 5) != 5) {		/* get rest of header */
	    fprintf(stderr, "No header in %s\n", name);
	    return(0);
	}
	if (buf[1] != ID_YAMAHA) {
bad:
	    fprintf(stderr, "Header problem in: %x %x %x %x %x %x\n",
	     buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
	    return(0);
	}
	if ((buf[2] >> 4) != DX7_SXSS_BD)
	    goto bad;
	fmt = buf[3];
	if (fmt != DX7_SXF_1V  || buf[4] != 0x01 || buf[5] != 0x1B)
	    goto bad;
	if (read(ifh, &v, sizeof v) != sizeof v) {
	    perror("DX7_SXF_1V read");
	    return(0);
	}
	openpl();
	egplot(v.pitchRate, v.pitchLevel, 250, 770);
	egplot(&v.op[5][0], &v.op[5][4], 50, 520);
	egplot(&v.op[4][0], &v.op[4][4], 50, 270);
	egplot(&v.op[3][0], &v.op[3][4], 50, 20);
	egplot(&v.op[2][0], &v.op[2][4], 550, 520);
	egplot(&v.op[1][0], &v.op[1][4], 550, 270);
	egplot(&v.op[0][0], &v.op[0][4], 550, 20);
	closepl();
	return(1);
}

egplot(rate, level, xoff, yoff)
char	rate[], level[];
{
	int i, x;

	x = 50;
	for (i = 0; i < 4; i++)
	    x += 100 - rate[i];
	line(xoff, yoff, xoff + x, yoff);
	line(xoff, yoff, xoff, yoff + 200);
	x = 0;
	for (i = 0; i < 4; i++) {
	    x += 100 - rate[i];
	    line(xoff + x, yoff - 5, xoff + x, yoff + 5);
	    if (i == 2) {
		x += 50;
		line(xoff + x, yoff - 5, xoff + x, yoff + 5);
	    }
	}
	for (i = 200; i > 0; i -= 20)
	    line(xoff - 5, yoff + i, xoff + 5, yoff + i);
	x = 0;
	move(xoff + x, yoff + 2 * level[3]);
	for (i = 0; i < 4; i++) {
	    x += 100 - rate[i];
	    cont(xoff + x, yoff + 2 * level[i]);
	    if (i == 2) {
		x += 50;
		cont(xoff + x, yoff + 2 * level[i]);
	    }
	}
}
