/* SigLib Real FFT Example
This program shows that the magnitude results of the real FFT operation are (N/2)+1 long.
The reason for this is that the results in bins 0 and N/2 are purely real.
The results are plotted on the screen and also written to the debug.log file. The FFT is
16 samples long and the data in the log file is stored on two lines of 8 for each result.
*/

/* Include files */

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

/* Define constants */
#define	FFT_SIZE		((SLArrayIndex_t)16)
#define	LOG_FFT_SIZE	((SLArrayIndex_t)4)

/* Declare global variables */
SLData_t	*pRealData, *pImagData, *pResults, *pFFTCoeffs;
SLData_t	RampPhase;

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

	pRealData = SUF_VectorArrayAllocate (FFT_SIZE);	/* Allocate memory */
	pImagData = SUF_VectorArrayAllocate (FFT_SIZE);
	pResults = SUF_VectorArrayAllocate (FFT_SIZE);
	pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE);

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("Real FFT",					/* 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 */

													/* Initialise the source data to a ramp */
	RampPhase = SIGLIB_ZERO;
	SDA_SignalGenerateRamp  (pRealData,								/* Pointer to destination array */
							 ((SLData_t)FFT_SIZE)/SIGLIB_TWENTY,	/* Amplitude */
							 ((SLData_t)FFT_SIZE)/SIGLIB_TWENTY,	/* D.C. Offset */
							 &RampPhase,							/* Phase - maintained across array boundaries */
							 FFT_SIZE);								/* Array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Source Signal",				/* Title of the dataset */
				    pRealData,						/* 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 ("\nSource 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 */
				    "Real Result",					/* Title of the dataset */
				    pRealData,						/* Array of Double dataset */
				    FFT_SIZE,						/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_RED,							/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_NEW);					/* New graph */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Imaginary Result",				/* Title of the dataset */
				    pImagData,						/* Array of Double dataset */
				    FFT_SIZE,						/* Number of data points */
					SV_GRAPH_LINE,					/* Graph type */
				    SV_YELLOW,						/* Colour */
					SV_HIDE_MARKERS,				/* Marker enable / disable */
					SV_GRAPH_ADD);					/* New graph */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Magnitude Signal",				/* 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_ADD);					/* New graph */
	printf ("\nReal, Imaginary and Magnitude Results\n");

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


