#include <stdio.h>
#include <math.h>
#include "calcadsr.h"

int rate_tab[4] = { 1, 8, 64, 512 };

#define RAMPS	252

double	times[ RAMPS ];
double	volume_range;
int	ramps[ RAMPS ];

main(argc, argv)
int argc;
char *argv[];
{
	int nv, i;
	double time;

	
	if (argc != 2) { printf("calcadsr #voices\n"); exit(0); }
	nv = atoi(argv[1]);

#define MAX_VOLUME 	0xfb
#define LOWEST_VOLUME	0x40

	volume_range = (double)((int)(MAX_VOLUME - LOWEST_VOLUME) << 4U);

	printf("/* The following times are for %d voices ramping*/\n", nv);
	printf("/* the full volume range of %lf */\n", volume_range );

	build_tables( nv );
		
	printf("#define\tMAX_ENV_INDEX\t64\n\n");
	printf("/* Envelope times for %d Oscilators. */\n\n", nv);
	printf("unsigned char attack_index[ MAX_ENV_INDEX ] =\n{\n");
	for (i=0; i < MAX_ENV_INDEX; i++) {
		time = attack_index[i];
		find_time( time );
	}

	printf("};\n\n");
	printf("unsigned char decay_release_index[ MAX_ENV_INDEX ] =\n{\n");
	printf("0,	/* Special Case */\n");
	for (i=1; i < MAX_ENV_INDEX; i++) {
		time = decay_release_index[i];
		find_time( time );
	}
	printf("};\n\n");
}

build_tables( int nv )
{
	int rr, volinc, i, j, hold_ramp;
	double fu_volume, hold_time, lowest;

	i = 0;
	for( rr=0; rr<4; rr++ )
		{
		fu_volume = (1.6 * (double)nv) * (double)rate_tab[rr];

		for( volinc = 1; volinc <= 63; volinc++ )
			{
			ramps[ i ] = (rr << 6) + volinc;
			
			times[i] = fu_volume * volume_range / (double)volinc;
			times[i] = times[i] / 1000.0;
			i++;
			}
#ifdef NEVER			
		printf(" ramp (%d) time (%lf)\n", ramps[ i-1 ],times[i-1] );
#endif	
		}

/* Now sort the times in times order not ramps. */

for( j=0; j < RAMPS; j++ )
	{
	lowest = times[j];
	for( i=0; i < RAMPS; i++ )
		{
		if( times[i] > lowest )
			{
			hold_time = times[j];
			hold_ramp = ramps[j];
			times[j] = times[i];
			ramps[j] = ramps[i];
			times[i] = hold_time;
			ramps[i] = hold_ramp;			
			lowest = times[i];
			}
		}
	}

#ifdef NEVER
for( i=0; i < RAMPS; i++ )
	printf(" ramp (%d) time (%lf)\n", ramps[ i ],times[i] );
#endif
}

find_time( double time )
{
int	i;

	for( i=0; i < RAMPS; i++ )
		{
		if( time < times[i] )
			{
			if( i )
printf("0x%02x,\t/* %lfms real */\t/* %lfms */\n", ramps[i-1], times[i-1], time);
			else
printf("0x%02x,\t/* %lfms real */\t/* %lfms */\n", ramps[i], times[i], time);

break;
			}
		}
}
