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

Dx7Voice *dx7readVoice();
char *VoiceFile();

#define VoiceFile(x) x

static char *lfoWave[] = { "tri ", "saw-", "saw+", "squa", "sine", "samp", };
static char *on[] = { "on ","off" };
static char *curve[] = {"-lin", "-exp", "+exp", "+lin"};
static char *mode[] = {"r", "f"};

#define p fprintf

dx7PrintOperator(op,o)
	Dx7Operator *op;
	FILE *o;
{
#define el(x) op->x[0],op->x[1],op->x[2],op->x[3]
p(o,"%s %2d %2d  %2d ",
	     mode[op->oscMode],		/* 0 ~ 1 */
	     op->oscFreqCoarse,	/* 0 ~ 31 */
	     op->oscFreqFine,	/* 0 ~ 99 */
	     op->oscDetune-7);
p(o,"%2d %2d %2d %2d  %2d %2d %2d %2d ",
     el(rate), el(level));
#undef el
p(o, "%3s %4s %4s %2d %2d   %1d  %2d  %1d",
	     itop(op->kbdBreakPoint),
	     curve[op->kbdLCurve],	/* 0 ~ 3 */
	     curve[op->kbdRCurve],
	     op->kbdLDepth,
	     op->kbdRDepth,
	     op->kbdRateScale,		/* 0 ~ 7 */
	     op->outputLevel,		/* 0 ~ 99 */
	     op->keyVelSensitivity,	/* 0 ~ 7 */
	     0);			/* 0 ~ 14 */
}

dx7PrintVoice(i,name,o) FILE *i,*o; {
	Dx7Voice *v = dx7readVoice(i,name);
	int j;

	if (!v) return;
p(o,"Voice Name: %s\n",v->name);
/*
p(o,"\n");
p(o,"|  [7] | [8] | [9] | [10]| [11]| [12]| [13]| [14]| [15]| [16]\n");
p(o,"|======|=====|=====|=====|=====|=====|=====|=====|=====|=================|\n");*/
p(o,"|========================================================================|\n");
p(o,"| algo  feed |---------------L F O---------------|  mod sensitivity      |\n");
p(o,"| rithm back |wave  speed delay  pmd   amd  sync | pitch amplitude       |\n");
p(o,"|  %3d   %3d  %s   %3d   %3d   %3d   %3d   %3d   %3d  ",
    v->algorithm+1,v->feedback,lfoWave[v->lfoWave],v->lfoSpeed,v->lfoDelay,
    v->lfoPmd,v->lfoAmd,v->lfoSync,v->modSensitivityPitch);
#define sens(n) ((Dx7Operator *)&(v->op[n][0]))->modSensitivity
p(o,"[%d %d %d %d %d %d]    |\n",sens(0),sens(1),sens(2),sens(3),sens(4),sens(5));
p(o,"|========================================================================|\n");
p(o,"| mod freq de  ----rate---  ---level--- kbd --curve-- depth kbd  out vel |\n");
p(o,"|op   c  f tune 1  2  3  4   1  2  3  4 brk  L    R    L  R rate lvl sens|\n");

/*
p(o,"\n\n");
p(o,"|  [2] | [3] | [4] | [5] | [6] | [7] |\n");
p(o,"|======|=====|=====|=====|=====|=====|\n");
p(o,"| poly | pitchbend |   portamento    |\n");
p(o,"| mono |range|step |mode  gliss time |\n");
*/

	for (j=0;j<6;j++)
		p(o,"|%d ",j+1), dx7PrintOperator(v->op[j],o), p(o, "   |\n");
p(o,"|========================================================================|\n");
p(o,"| -----pitch EG----  transpose                                           |\n");
p(o,"| rate  %2d %2d %2d %2d %3s                                                  |\n",
  v->pitchRate[0],v->pitchRate[1],v->pitchRate[2],v->pitchRate[3],itop(v->transpose+24));
p(o,"| level %2d %2d %2d %2d                                                      |\n",
  v->pitchLevel[0],v->pitchLevel[1],v->pitchLevel[2],v->pitchLevel[3]);
p(o,"|========================================================================|\n");
}

/*
** For each dx7 voice file, pretty print something like the
** Yamaha table
*/
main(ac,av) char *av[]; {
	int i=1;
	if (i==ac) dx7PrintVoice(stdin,"stdin",stdout);
	else for (;i<ac;i++){
		char *s = VoiceFile(av[i]);
		FILE *f = (FILE *)0;
		if (s) f = fopen(s,"r");
		if (f) {
			if (i>1) printf("\n\n");
			dx7PrintVoice(f,av[i],stdout);
			fclose(f);
		}
		else MidiError("%s: ",av[0]), perror(av[i]);
	}
}
