/* SigLib FFT Tone Detector Example */

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

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

#define SAMPLE_RATE			((SLData_t)10000.0)
#define SIGNAL_FREQUENCY	((SLData_t)2000.0)

SLData_t		*pSrcData, *pRealData, *pImagData, *pFFTCoeffs;
SLArrayIndex_t	ToneFFTBin;
SLData_t		ToneMagnitude;
SLData_t		SinePhase;

void main(void);

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

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

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

	SinePhase = SIGLIB_ZERO;
	SDA_SignalGenerate (pSrcData,						/* Pointer to destination array */
						SIGLIB_SINE_WAVE,				/* Signal type - Sine wave */
						SIGLIB_ONE,						/* Signal peak level */
						SIGLIB_FILL,					/* Fill (overwrite) or add to existing array contents */
						SIGNAL_FREQUENCY / SAMPLE_RATE,	/* Signal frequency */
						SIGLIB_ZERO,					/* D.C. Offset */
						SIGLIB_ZERO,					/* Unused */
						SIGLIB_ZERO,					/* Signal end value - Unused */
						&SinePhase,						/* Signal phase - maintained across array boundaries */
						SIGLIB_NULL_DATA_PTR,			/* Unused */
						SAMPLE_LENGTH);					/* Output array length */

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

	plot_frequency_domain (pSrcData, SIGLIB_HANNING, "Frequency Response", SAMPLE_LENGTH, FFT_SIZE);

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

													/* Perform real FFTTone */
	SDA_RfftTone (pSrcData,							/* Real source data */
			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 */
			&ToneFFTBin,							/* Output tone bin number */
			&ToneMagnitude,							/* Output tone magnitude */
			FFT_SIZE,								/* FFT size */
			LOG_FFT_SIZE);							/* log2 FFT size */


													/* Print results - dBm relative to 0 dB = FSD on a 16 bit ADC */
	printf ("Tone frequency = %2.2lf, Magnitude = %2.2lf (dB)\n\n",
			((((SLData_t)ToneFFTBin) * ((SLData_t)SAMPLE_RATE)) / ((SLData_t)FFT_SIZE)),
			SDS_LinearTodBm (ToneMagnitude,			/* Linear value */
							 32768.0));				/* Zero dBm Level */

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


