/*
 *	Program:		poly_xlate.c
 *
 *	Created by:		Dan Oliver
 *
 *	Creation date:	12-30-87
 *                                      CHANGE LOG
 *	  Date		Who		Comments
 *	--------	----	-------------------------------------------------------
 */

#include <stdio.h>

#define TRUE		(1)
#define FALSE		(0)

#define TBASE		16384				/* Tempo base */
#define DBASE		8192				/* Duration base */

int notes[48] =
{
	256, 271, 287, 304, 322, 341, 362, 383, 406, 430, 456, 483,	/* Bass */
	512, 542, 575, 609, 645, 683, 724, 767, 813, 861, 912, 967,	/* Low */
	1024, 1085, 1149, 1218, 1290, 1367, 1448, 1534, 1625, 1722, 1825, 1933,	/* Medium */
	2048, 2170, 2299, 2435, 2580, 2734, 2896, 3069, 3251, 3444, 3649, 3866	/* High */
};

char *nname[12] =
{
	"C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B "
};

char title[81];							/* Song title */
int tempo;								/* Tempo */
int measure;							/* Measure duration */

unsigned voice[3];						/* Voice data */
unsigned duration;						/* Voices duration */

/*****************************************************************************/
main( argc, argv )
int argc;
char *argv[];
/*
 *	Description:	This program takes a polyphonic music data file as input
 *					(stdin) and outputs a translation (into english, more or
 *					less) of the song (to stdout).
 *
 *	Return:			-none-
 */
{

/*
 *  Read title, measure duration, and tempo and output them...
 */
	fgetstr( stdin, title, 80 );
	tfscanf( stdin, "%2d %5d\n", &measure, &tempo );
	tempo -= TBASE;
	tfprintf( stdout, "Title: %s\nMeasure duration: %d\nTempo: %d\n", title, measure, tempo );
	tfprintf( stdout, "Voice1  Voice2  Voice3  Duration\n------  ------  ------  --------\n" );
/*
 *  Now start into data read/display loop...
 */
	while( (tfscanf(stdin, "%d", &voice[0]) != -1) && voice[0] )
	{
		tfscanf( stdin, "%d %d %d\n", &voice[1], &voice[2], &duration );
		display( voice[0] );
		display( voice[1] );
		display( voice[2] );
		tfprintf( stdout, "%8d\n", duration-DBASE );
	}
	tfprintf( stdout, "\n" );
}

/*****************************************************************************/
display( dvoice )
unsigned dvoice;
{
	int value;
	int octave;
	int sindex;
	int eindex;
	int nindex;
	int i;
	int j;
	char doctave;
	
	value = dvoice & 0x1fff;
	octave = value/256;
	if( octave >= 2 && octave <= 3 )
		octave = 2;
	if( octave >= 4 && octave <= 7 )
		octave = 3;
	if(octave >= 8 && octave <= 15 )
		octave = 4;

	switch( octave )
	{
		case 1:
			sindex = 0;
			eindex = 12;
			doctave = 'b';
			break;
		case 2:
			sindex = 12;
			eindex = 24;
			doctave = 'l';
			break;
		case 3:
			sindex = 24;
			eindex = 36;
			doctave = 'm';
			break;
		case 4:
			sindex = 36;
			eindex = 48;
			doctave = 'h';
			break;
		default:
			sindex = 0;
			eindex = 0;
			break;
	}

	for( nindex=0, i=sindex, j=eindex; i < j; i++ )
	{
		if( value == notes[i] )
		{
			nindex = i % 12;
			break;
		}
	}

	if( nindex )
		tfprintf( stdout, "(%c)%s   ", doctave, nname[nindex] );
	else
		tfprintf( stdout, "        " );
}
