/*
 * $Header: print.c,v 1.5 88/07/20 21:40:25 glenn Exp $
 */
#include <stdio.h>
#include <math.h>
#include "dx7.h"

static double fixedfreqs[] = {
1.000, 1.023, 1.046, 1.072, 1.096, 1.122, 1.148, 1.175, 1.202, 1.230, 1.259,
1.288, 1.318, 1.349, 1.380, 1.413, 1.445, 1.479, 1.514, 1.549, 1.585, 1.622,
1.660, 1.698, 1.338, 1.778, 1.820, 1.862, 1.905, 1.950, 1.995, 2.042, 2.089,
2.138, 2.188, 2.239, 2.291, 2.344, 2.399, 2.455, 2.512, 2.570, 2.630, 2.692,
2.716, 2.818, 2.884, 2.951, 3.020, 3.090, 3.162, 3.236, 3.311, 3.388, 3.567,
3.548, 3.631, 3.715, 3.802, 3.890, 3.981, 4.074, 4.169, 4.266, 4.365, 4.467,
4.571, 4.677, 4.786, 4.898, 5.012, 5.129, 5.248, 5.370, 5.495, 5.623, 5.754,
5.888, 6.026, 6.166, 6.310, 6.457, 6.607, 6.761, 6.918, 7.079, 7.244, 7.413,
7.586, 7.762, 7.943, 8.128, 8.318, 8.511, 8.718, 8.913, 9.120, 9.333, 9.550,
9.772
};

static char *Curve[] = {"-lin", "-exp", "+exp", "+lin"};
char *LfoWave[] = {"Tri", "Saw-", "Saw+", "Squa", "Sine", "S/H"};
char *Pitches[] = {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"};
char *Octave[] = {"-1", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"};

char *itop(), *frequency();
double pow();

PrintVoice(v)
register struct dx7voice *v;
{
	int i, x, y;
	char buf[100], name[11];

	printf("%10.10s ====================================================================\n", v->v_name);
printf(
"                   |------------------LFO---------------| mod    osc\n");
printf(
"algorithm feedback | wave  speed  delay  pmd  amd  sync | pitch  sync\n");
	printf(
"%9d %8d   %4.4s     %2d     %2d   %2d   %2d    O%s      %2d   O%s\n",
		   v->v_algorithm + 1,
		   v->v_feedback,
		   LfoWave[v->v_lfoWave],
		   v->v_lfoSpeed,
		   v->v_lfoDelay,
		   v->v_lfoPmd,
		   v->v_lfoAmd,
		   (v->v_lfoSync) ? "n" : "ff",
		   v->v_pSens,
		   (v->v_sync) ? "n" : "ff"
		   );

	printf("===============================================================================\n");
	printf("\
  S  freq      +-  ----Rate---  ---Level---   kbd  --Curve-  Depth Kbd Out Sens\n");
printf("\
     C       F      1  2  3  4   1  2  3  4   brk  L    R    L  R  Rat lvl V  M\n");

	for (i = 5; i >= 0; i--) {
		printf("%1d ", i + 1);
		printOperator(v->v_operator[5 - i]);
	}

	printf("===============================================================================\n");
	printf("      ---pitch EG---    Transpose CheckSum\n");
	printf("Rate  %2.2d  %2.2d  %2.2d  %2.2d    %9.9s 0x%02.2x\n", 
		   v->v_pRate[0],
		   v->v_pRate[1],
		   v->v_pRate[2],
		   v->v_pRate[3],
		   itop(v->v_transpose),
		   v->v_checksum & 0xFF
		   );
	
	printf("Level %2.2d  %2.2d  %2.2d  %2.2d\n", 
		   v->v_pLevel[0],
		   v->v_pLevel[1],
		   v->v_pLevel[2],
		   v->v_pLevel[3]
		   );
}

printOperator(op)
register struct dx7operator *op;
{
	char buf[150];

/*"\
%c %2d      %2d %2d  %2d %2d %2d %2d  %2d %2d %2d %2d  %4.4s %4s %4s %2d %2d   %2d  %2d %1d  %1d\n",*/
	printf("\
%c %10.10s %2d  %2d %2d %2d %2d  %2d %2d %2d %2d  %4.4s %4s %4s %2d %2d   %2d  %2d %1d  %1d\n",
		   (op->o_oscMode) ? 'f' : 'r',
		   frequency(op->o_oscMode, op->o_Cfreq, op->o_Ffreq),
/*		   op->o_Cfreq,
		   op->o_Ffreq,*/
		   op->o_detune - 7,
		   op->o_rate[0],
		   op->o_rate[1],
		   op->o_rate[2],
		   op->o_rate[3],
		   op->o_level[0],
		   op->o_level[1],
		   op->o_level[2],
		   op->o_level[3],
		   itop(op->o_breakP),
		   Curve[op->o_lCurve],
		   Curve[op->o_rCurve],
		   op->o_lDepth,
		   op->o_rDepth,
		   op->o_rates,
		   op->o_output,
		   op->o_velocity,
		   op->o_sens
	);
}

char *
itop(p)
register p;
{
	static char pitch[6];

	strcpy(pitch, Pitches[p%12]);
	strcat(pitch, Octave[(p+8)/12]);

	return (pitch);
}

char *
frequency(mode, coarse, fine)
{
	static char buf[50];

	if (mode == 0) {			/* Frequency Ratio mode */
		if (fine == 0) {
			if (coarse == 0)
				sprintf(buf, "%5.5s %4.4s", "0.5", "0");
			else
				sprintf(buf, "%5d %5d", coarse, 0);
			return (buf);
		} else {
			if (coarse == 0) {
				sprintf(buf, " 0.5 %5.2f", .5 + (.5 / 100. * fine));
			} else {
				sprintf(buf, "%5d %5.2f",
						coarse, coarse + (coarse / 100. * fine));
			}
		}
	} else {					/* Fixed Frequency mode */
		if (fine == 0) {
			sprintf(buf, "%5d", (int) pow(10., (double) (coarse & 03)));
		} else {
			sprintf(buf, "%.3f",
					fixedfreqs[fine] * (int) pow(10., (double) (coarse & 03)));
		}
	}
}

