/**
 *	@file compandit.c - implementation test file for integer companding with
 *  compand/uncompand support & IIR correction
 *
 *	@copy Copyright (C) <2012>  <M. A. Chatterjee>
 *  @author M A Chatterjee <deftio [at] deftio [dot] com>
 *
 *	This software is provided 'as-is', without any express or implied
 *	warranty. In no event will the authors be held liable for any damages
 *	arising from the use of this software.
 *
 *	Permission is granted to anyone to use this software for any purpose,
 *	including commercial applications, and to alter it and redistribute it
 *	freely, subject to the following restrictions:
 *
 *	1. The origin of this software must not be misrepresented; you must not
 *	claim that you wrote the original software. If you use this software
 *	in a product, an acknowledgment in the product documentation would be
 *	appreciated but is not required.
 *
 *	2. Altered source versions must be plainly marked as such, and must not be
 *	misrepresented as being the original software.
 *
 *	3. This notice may not be removed or altered from any source
 *	distribution.
 *
 */

#include <stdio.h>
#include <string.h>


#include "companders.h"


//===============================================
//main program for testing the functions
int main (int argc, char *argv[])
{
	int ret_val = 0;
	int i=0,j=0;
	printf("\n============================================================\n");
	printf("compandit library quikie program\n");
	printf("M. A. Chatterjee (c) 2012\n\n");
	printf("These routines were developed for use on embedded projects\n");
	printf("for more info see the accompanying compand.txt\n");
	printf("\n");
	
	//uncomment to 
	//show how linear-->alaw-->linear-->alaw progression / quantization error works
	/*
	
	{
		char alaw=0,alaw2;
		short rev=0;

		for (i= -32768; i <= 32767; i++)
		{
			alaw = DIO_LinearToALaw((short)i);
			rev  = DIO_ALawToLinear(alaw);
			alaw2 =DIO_LinearToALaw(rev);
			if (alaw != alaw2)
				printf("***********");
			printf("%7d  %7d  %7d %7d\n",i,(int)alaw,(int)rev,(int)alaw2);
		}
	}


    // IIR averager examples
    //IIR window length of 8 samples, using fractional precision of 4 bits
    {    
		int a3=0, a4=0;
		unsigned char rad=4; //4 bits fixed-radix fractional precision
		printf(" index   wave  IIRav(i)  IIRav(f)  IIRavP2(i) IIRavP2(f)\n");
		for (i=0; i < 300; i++)
		{
			j=(i&0x3f)-20; // triangle wave with range -20 to + 43
			a3= DIO_IIRavgFR(a3,8,j,rad);		  
			a4= DIO_IIRavgPower2FR(a4,3,j,rad);  
			printf("%6d  %6d  %6d  %9.4f     %6d  %9.4f \n",i,j, 
				DIO_FR2I(a3,rad),DIO_FR2D(a3,rad) ,DIO_FR2I(a4,rad),DIO_FR2D(a4,rad));
		}
	}
    //IIR window length of 64 samples
    {    
		int a3=0, a4=0;
		unsigned char rad=6; //rad is the number of bits of precision 
		printf(" index   wave  IIRav(i)  IIRav(f)  IIRavP2(i) IIRavP2(f)\n");
		for (i=0; i < 300; i++)
		{
			j=(i&0x3f)-20; // triangle wave with range -20 to + 43
			a3= DIO_IIRavgFR(a3,64,j,rad);	   
			a4= DIO_IIRavgPower2FR(a4,6,j,rad); 
			printf("%6d  %6d  %6d  %9.4f     %6d  %9.4f \n",i,j, 
				DIO_FR2I(a3,rad),DIO_FR2D(a3,rad) ,DIO_FR2I(a4,rad),DIO_FR2D(a4,rad));
		}
	}
	// */
	//Typical microcontroller application.  See readme-companders.txt
	// the input here simulates an A/D which has  a range 0..3.3V mapped as 12 bits (0..4095)
	// with a DC bias of 1.55V  ==> (1.55/3.3)*4095 counts = 1923 counts
	
	//now window length of 256 is used for rejecting the resistor bias.  at 8KHz this window
	// would be approx 8000/256 ~= 31 Hz (not quite but explaining Z xforms is beyond what
	// can be explained in this small space.)
	//we seed the DC average at 3.3/2 = 1.65V (we guess its in the middle) and let the long window
	//length hone in on the correct value.  (1.65V/3.3V) *4095 = 2048 counts
    {    
		int actualDCbias     =1923;
		int calculatedDCbias =2048;	//2048 is our initial estimate as outlined above
		unsigned char windowLenPow2InBits = 8; // 8 bit long window = 256 sample long window
		unsigned char rad=6; //rad is the number of bits of precision 

		calculatedDCbias = DIO_I2FR(calculatedDCbias,rad);
		printf(" index   wave  actDCbias  calcDCbias  calcDCbias(f) alaw\n");
		for (i=0; i < 1000; i++)  // if 8000 hz sample rate this represents the number of samples captured
		{
			j=(((i&0x3f)<<1)-63)+1923; // triangle wave w range 0..127  with a bias set at actualDCbias
			calculatedDCbias = DIO_IIRavgPower2FR(calculatedDCbias,windowLenPow2InBits,j,rad); 
			printf("%6d %6d   %6d     %6d      %9.4f     %3d\n",i,j,actualDCbias, 
				DIO_FR2I(calculatedDCbias,rad),DIO_FR2D(calculatedDCbias,rad),
				(int)(DIO_LinearToALaw(j-DIO_FR2I(calculatedDCbias,rad)) ));
		}
	}
	printf("\n");
	return ret_val;
}