/* SigLib All-pole Filter Example */

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

/* Define constants */
#define	SAMPLE_LENGTH		((SLArrayIndex_t)512)
#define	FFT_SIZE			((SLArrayIndex_t)512)
#define	LOG_FFT_SIZE		((SLArrayIndex_t)9)
#define FILTER_ORDER		4					/* Filter length */

			/* 100Hz cut off frequency,4 pole,10kHz sample rate */
SLData_t FourPoleButterworth_Fc100_Fs10000 [] =
{
	3.83582554064735, -5.52081913662223, 3.53353521946301, -0.848555999266477
};

SLData_t		*pRealData, *pImagData, *pResults, *pSrc, *pFilterState, *pFFTCoeffs;
SLArrayIndex_t	FilterStateOffset;
SLData_t		SinePhase;

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

													/* Allocate memory */
	pSrc = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pRealData = SUF_VectorArrayAllocate (FFT_SIZE);
	pImagData = SUF_VectorArrayAllocate (FFT_SIZE);
	pResults = SUF_VectorArrayAllocate (FFT_SIZE);		/* FFT result array */
	pFilterState = SUF_VectorArrayAllocate (FILTER_ORDER);
	pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE);


	SIF_AllPole (pFilterState,						/* Pointer to state array */
				 &FilterStateOffset,				/* Pointer to filter index */
				 FILTER_ORDER);						/* Filter order */

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("All-pole 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);
	}

													/* 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 */

	SDA_SignalGenerate (pSrc,						/* Pointer to destination array */
						SIGLIB_IMPULSE,				/* Signal type - Impulse function */
						SIGLIB_ONE,					/* 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 */

	SDA_AllPole (pSrc,								/* Pointer to input data */
				 pRealData,							/* Pointer to output data */
				 pFilterState,						/* Pointer to state array */
				 FourPoleButterworth_Fc100_Fs10000,	/* Pointer to filter coefficients */
				 &FilterStateOffset,				/* Pointer to filter index */
				 FILTER_ORDER,						/* Filter order */
				 SAMPLE_LENGTH);					/* Array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Source Signal",				/* Title of the dataset */
				    pSrc,							/* 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 ("\nSource Signal\nPlease hit <Carriage Return> to continue . . ."); getchar ();

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "All-pole Filtered Signal",		/* Title of the dataset */
				    pRealData,						/* 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_ADD);					/* New graph */
	printf ("\nAll-pole Filtered Signal\nPlease hit <Carriage Return> to continue . . ."); getchar ();

													/* Perform real FFT */
	SDA_Rfft (pRealData,							/* 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 magnitude from complex */
	SDA_Magnitude (pRealData,						/* Pointer to real source array */
				   pImagData,						/* Pointer to imaginary source array */
				   pResults,						/* Pointer to magnitude destination array */
				   FFT_SIZE);						/* Array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "All-pole Filter Frequency Response",		/* Title of the dataset */
				    pRealData,						/* 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 ("\nAll-pole Filtered Frequency Response\n");

	SUF_MemoryFree (pSrc);							/* Free memory */
	SUF_MemoryFree (pRealData);
	SUF_MemoryFree (pImagData);
	SUF_MemoryFree (pResults);
	SUF_MemoryFree (pFilterState);
	SUF_MemoryFree (pFFTCoeffs);
}


