/* SigLib FIR Filter Example 2 */

#include <stdio.h>
#include <siglib.h>
#include "GraphFunctions.h"

#define	FFT_SIZE		((SLArrayIndex_t)512)
#define	LOG_FFT_SIZE	((SLArrayIndex_t)9)

SLData_t	*pImagData, *pRealDataCopy, *pImagDataCopy, *pWindowCoeffs;
SLData_t	*pResults, *pFFTCoeffs;

/* Define constants */
#define	FILTER_LENGTH	((SLArrayIndex_t)128)
#define	SAMPLE_LENGTH	((SLArrayIndex_t)512)

			/* Initialise filter coefficients */
SLData_t	pFilterTaps[FILTER_LENGTH] = {
	-5.34266824816E-0004,  1.24568792546E-0003,  8.73278953630E-0004, 
	 4.37786545396E-0004,  1.57576481250E-0003, -1.38557006660E-0003, 
	 1.90710297624E-0004, -1.85794214656E-0003, -2.00704829381E-0003, 
	 2.40455797115E-0004, -2.04022181601E-0003,  2.71242012844E-0003, 
	 8.82181294290E-0004,  2.06390803758E-0003,  3.46115122350E-0003, 
	-1.75033817834E-0003,  1.86645226647E-0003, -4.19706616768E-0003, 
	-2.84686649762E-0003, -1.38480747151E-0003, -4.84877083488E-0003, 
	 4.15691399504E-0003, -5.59004695862E-0004,  5.33078655121E-0003, 
	 5.64663098926E-0003, -6.64415849217E-0004,  5.54512386900E-0003, 
	-7.26170537971E-0003, -2.32956984257E-0003, -5.38280517195E-0003, 
	-8.92656985171E-0003,  4.46954409718E-0003, -4.72452163230E-0003, 
	 1.05439735389E-0002,  7.10658444744E-0003,  3.43906801399E-0003, 
	 1.19942117579E-0002, -1.02552167173E-0002,  1.37716894902E-0003, 
	-1.31325730564E-0002, -1.39301212180E-0002,  1.64388322268E-0003, 
	-1.37820329052E-0002,  1.81624192809E-0002,  5.87454453127E-0003, 
	 1.37146029376E-0002,  2.30328314183E-0002, -1.17097244170E-0002, 
	 1.26049642763E-0002, -2.87440911303E-0002, -1.98723865258E-0002, 
	-9.90924135116E-0003, -3.58018612026E-0002,  3.19153948705E-0002, 
	-4.50363677305E-0003,  4.55694407950E-0002,  5.19287403766E-0002, 
	-6.69120481527E-0003,  6.26204030713E-0002, -9.50703908154E-0002, 
	-3.71802059842E-0002, -1.13988434152E-0001, -2.98431997465E-0001, 
	 4.24370110064E-0001,  4.24370110064E-0001, -2.98431997465E-0001, 
	-1.13988434152E-0001, -3.71802059842E-0002, -9.50703908154E-0002, 
	 6.26204030713E-0002, -6.69120481527E-0003,  5.19287403766E-0002, 
	 4.55694407950E-0002, -4.50363677305E-0003,  3.19153948705E-0002, 
	-3.58018612026E-0002, -9.90924135116E-0003, -1.98723865258E-0002, 
	-2.87440911303E-0002,  1.26049642763E-0002, -1.17097244170E-0002, 
	 2.30328314183E-0002,  1.37146029376E-0002,  5.87454453127E-0003, 
	 1.81624192809E-0002, -1.37820329052E-0002,  1.64388322268E-0003, 
	-1.39301212180E-0002, -1.31325730564E-0002,  1.37716894902E-0003, 
	-1.02552167173E-0002,  1.19942117579E-0002,  3.43906801399E-0003, 
	 7.10658444744E-0003,  1.05439735389E-0002, -4.72452163230E-0003, 
	 4.46954409718E-0003, -8.92656985171E-0003, -5.38280517195E-0003, 
	-2.32956984257E-0003, -7.26170537971E-0003,  5.54512386900E-0003, 
	-6.64415849217E-0004,  5.64663098926E-0003,  5.33078655121E-0003, 
	-5.59004695862E-0004,  4.15691399504E-0003, -4.84877083488E-0003, 
	-1.38480747151E-0003, -2.84686649762E-0003, -4.19706616768E-0003, 
	 1.86645226647E-0003, -1.75033817834E-0003,  3.46115122350E-0003, 
	 2.06390803758E-0003,  8.82181294290E-0004,  2.71242012844E-0003, 
	-2.04022181601E-0003,  2.40455797115E-0004, -2.00704829381E-0003,
	-1.85794214656E-0003,  1.90710297624E-0004, -1.38557006660E-0003, 
	 1.57576481250E-0003,  4.37786545396E-0004,  8.73278953630E-0004, 
	 1.24568792546E-0003, -5.34266824816E-0004
	};

SLData_t	pFilterState[FILTER_LENGTH];
SLArrayIndex_t	FilterIndex;
SLData_t	*pSrc1, *pSrc2;

void	main(void);

void main(void)
{
	GraphObject *h2DGraph;							/* Declare graph object */

	SLFixData_t	i;

	pSrc1 = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pSrc2 = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pImagData = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pResults = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE);

													/* Initialise FFT */
	SIF_Fft (pFFTCoeffs,							/* Pointer to FFT coefficients */
			 SIGLIB_NULL_ARRAY_INDEX_PTR,			/* Pointer to bit reverse address table - NOT USED */
			 FFT_SIZE);								/* FFT Size */

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("FIR Filter",				/* Graph title */
					   "Time / Frequency",			/* X-Axis label */
					   "Magnitude",					/* Y-Axis label */
					   SV_AUTO_SCALE,				/* Scaling mode */
					   SV_SIGNED,					/* Sign mode */
					   SV_GRAPH_LINE,				/* Graph type */
					   "localhost");				/* Graph server */
	if (h2DGraph == NULL)							/* Graph creation failed - e.g is server running ? */
	{
		printf ("\nGraph creation failure. Please check that the server is running\n");
		exit (1);
	}

	SIF_Fir (pFilterState,							/* Pointer to filter state array */
			 &FilterIndex,							/* Pointer to filter index register */
			 FILTER_LENGTH);						/* Filter length */

	SDA_SignalGenerate (pSrc1,						/* Pointer to destination array */
						SIGLIB_WHITE_NOISE,			/* Signal type - random white noise */
						((SLData_t)0.9),			/* Signal peak level */
						SIGLIB_FILL,				/* Fill (overwrite) or add to existing array contents */
						SIGLIB_ZERO,				/* Signal frequency - Unused */
						SIGLIB_ZERO,				/* D.C. Offset */
						SIGLIB_ZERO,				/* Unused */
						SIGLIB_ZERO,				/* Signal end value - Unused */
						SIGLIB_NULL_DATA_PTR,		/* Unused */
						SIGLIB_NULL_DATA_PTR,		/* Unused */
						SAMPLE_LENGTH);				/* Output array length */

			/* Apply fir filter and store filtered data */
	for (i = 0; i < SAMPLE_LENGTH; i++)
	{
		*pSrc2++ =
			SDS_Fir (*pSrc1++,						/* Input data sample to be filtered */
					 pFilterState,					/* Pointer to filter state array */
					 pFilterTaps,					/* Pointer to filter coefficients */
					 &FilterIndex,					/* Pointer to filter index register */
					 FILTER_LENGTH);				/* Filter length */
	}

	pSrc1 -= SAMPLE_LENGTH;
	pSrc2 -= SAMPLE_LENGTH;

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Unfiltered Signal",			/* Title of the dataset */
				    pSrc1,							/* Array of Double dataset */
				    SAMPLE_LENGTH,					/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_BLUE,						/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_NEW);					/* New graph */
	printf ("\nUnfiltered Signal\nPlease hit <Carriage Return> to continue . . ."); getchar ();

													/* Perform real FFT */
	SDA_Rfft (pSrc1,								/* Pointer to real array */
			  pImagData,							/* Pointer to imaginary array */
			  pFFTCoeffs,							/* Pointer to FFT coefficients */
			  SIGLIB_NULL_ARRAY_INDEX_PTR,			/* Pointer to bit reverse address table - NOT USED */
			  FFT_SIZE,								/* FFT size */
			  LOG_FFT_SIZE);						/* log2 FFT size */

													/* Calculate real power from complex */
	SDA_LogMagnitude (pSrc1,						/* Pointer to real source array */
					  pImagData,					/* Pointer to imaginary source array */
					  pResults,						/* Pointer to log magnitude destination array */
					  FFT_SIZE);					/* Array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Unfiltered Signal Spectrum",	/* Title of the dataset */
				    pResults,						/* Array of Double dataset */
				    FFT_SIZE,						/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_BLUE,						/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_NEW);					/* New graph */
	printf ("\nUnfiltered Signal Spectrum\nPlease hit <Carriage Return> to continue . . ."); getchar ();


	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Filtered Signal",				/* Title of the dataset */
				    pSrc2,							/* Array of Double dataset */
				    SAMPLE_LENGTH,					/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_BLUE,						/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_NEW);					/* New graph */
	printf ("\nFiltered Signal\nPlease hit <Carriage Return> to continue . . ."); getchar ();

													/* Perform real FFT */
	SDA_Rfft (pSrc2,								/* Pointer to real array */
			  pImagData,							/* Pointer to imaginary array */
			  pFFTCoeffs,							/* Pointer to FFT coefficients */
			  SIGLIB_NULL_ARRAY_INDEX_PTR,			/* Pointer to bit reverse address table - NOT USED */
			  FFT_SIZE,								/* FFT size */
			  LOG_FFT_SIZE);						/* log2 FFT size */

													/* Calculate real power from complex */
	SDA_LogMagnitude (pSrc2,						/* Pointer to real source array */
					  pImagData,					/* Pointer to imaginary source array */
					  pResults,						/* Pointer to log magnitude destination array */
					  FFT_SIZE);					/* Array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Filtered Signal Spectrum",		/* Title of the dataset */
				    pResults,						/* Array of Double dataset */
				    FFT_SIZE,						/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_BLUE,						/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_NEW);					/* New graph */
	printf ("\nFiltered Signal Spectrum\n");

	SUF_MemoryFree (pSrc1);							/* Free memory */
	SUF_MemoryFree (pSrc2);
	SUF_MemoryFree (pImagData);
	SUF_MemoryFree (pResults);
	SUF_MemoryFree (pFFTCoeffs);
}



