/* SigLib Chirp Generator, With 3D Graph Example */

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

/* Define constants */
#define SAMPLE_LENGTH			((SLArrayIndex_t)512)
#define GRAPH_X_AXIS_LENGTH		((SLArrayIndex_t)512)
#define FFT_SIZE				((SLArrayIndex_t)512)
#define HALF_FFT_SIZE			((SLArrayIndex_t)256)
#define LOG_FFT_SIZE			((SLArrayIndex_t)9)
#define WINDOW_SIZE				FFT_SIZE
#define NUMBER_OF_FFTS			((SLArrayIndex_t)512)

/* Declare arrays and variables */
SLData_t	*pRealData, *pImagData, *pResults, *pWindowCoeffs, *pFFTCoeffs;
SLData_t	ChirpPhase1, ChirpPhase2, ChirpPhase3, ChirpPhase4;
SLData_t	ChirpValue1, ChirpValue2, ChirpValue3, ChirpValue4;

void main (void);

void main(void)
{
	GraphObject *h3DGraph;							/* Declare graph object */
	SLFixData_t	i;

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

	h3DGraph =										/* Initialize graph */
		Create3DGraph ("Spectrogram Plot",			/* Graph title */
					   "Time",						/* X-Axis label */
					   "Frequency",					/* Y-Axis label */
					   GRAPH_X_AXIS_LENGTH,			/* X-axis length */
					   0.0,							/* Minimum signal magnitude */
					   100.0,						/* Maximum signal magnitude */
					   0.0,							/* Y-Axis minimum value */
					   0.5,							/* Y-Axis maximum value */
					   SV_3D_COLOUR,				/* Graph mode */
					   "localhost");				/* Graph server */
	if (h3DGraph == 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 */
													/* Generate Hanning window table */
	SIF_Window (pWindowCoeffs,						/* Pointer to window oefficient */
			SIGLIB_RECTANGLE,						/* Window type */
			SIGLIB_ZERO,							/* Window coefficient */
			WINDOW_SIZE);							/* Window length */

	ChirpPhase1 = SIGLIB_ZERO; ChirpPhase2 = SIGLIB_ZERO; ChirpPhase3 = SIGLIB_ZERO; ChirpPhase4 = SIGLIB_ZERO;
	ChirpValue1 = SIGLIB_ZERO; ChirpValue2 = SIGLIB_ZERO; ChirpValue3 = SIGLIB_ZERO; ChirpValue4 = SIGLIB_ZERO;

	i = 0;

	printf ("Spectrum of Sum of Linear and Non-linear chirp Signals");
	printf ("Press any key to stop ...");

	while ((i < NUMBER_OF_FFTS) && !kbhit())
	{
		SDA_SignalGenerate (pRealData,				/* Pointer to destination array */
							SIGLIB_CHIRP_LIN,		/* Signal type - Chirp with linear frequency ramp */
							SIGLIB_ONE,				/* Signal peak level */
							SIGLIB_FILL,			/* Fill (overwrite) or add to existing array contents */
							SIGLIB_ZERO,			/* Signal lower frequency */
							SIGLIB_ZERO,			/* D.C. Offset */
							((SLData_t)0.000003),	/* Frequency change per sample period */
							SIGLIB_HALF,			/* Signal upper frequency */
							&ChirpPhase1,			/* Chirp phase - used for next iteration */
							&ChirpValue1,			/* Chirp current value - used for next iteration */
							SAMPLE_LENGTH);			/* Output array length */

		SDA_SignalGenerate (pRealData,				/* Pointer to destination array */
							SIGLIB_CHIRP_LIN,		/* Signal type - Chirp with linear frequency ramp */
							SIGLIB_ONE,				/* Signal peak level */
							SIGLIB_ADD,				/* Fill (overwrite) or add to existing array contents */
							SIGLIB_QUARTER,			/* Signal lower frequency */
							SIGLIB_ZERO,			/* D.C. Offset */
							((SLData_t)-0.0000015),	/* Frequency change per sample period */
							SIGLIB_HALF,			/* Signal upper frequency */
							&ChirpPhase2,			/* Chirp phase - used for next iteration */
							&ChirpValue2,			/* Chirp current value - used for next iteration */
							SAMPLE_LENGTH);			/* Output array length */

		SDA_SignalGenerate (pRealData,				/* Pointer to destination array */
							SIGLIB_CHIRP_NL,		/* Signal type - Chirp with non linear frequency ramp */
							SIGLIB_ONE,				/* Signal peak level */
							SIGLIB_ADD,				/* Fill (overwrite) or add to existing array contents */
							((SLData_t)0.0025),		/* Signal lower frequency */
							SIGLIB_ZERO,			/* D.C. Offset */
							((SLData_t)1.0000135),	/* Frequency change per sample period */
							SIGLIB_HALF,			/* Signal upper frequency */
							&ChirpPhase3,			/* Chirp phase - used for next iteration */
							&ChirpValue3,			/* Chirp current value - used for next iteration */
							SAMPLE_LENGTH);			/* Output array length */

		SDA_SignalGenerate (pRealData,				/* Pointer to destination array */
							SIGLIB_CHIRP_NL,		/* Signal type - Chirp with non linear frequency ramp */
							SIGLIB_ONE,				/* Signal peak level */
							SIGLIB_ADD,				/* Fill (overwrite) or add to existing array contents */
							SIGLIB_HALF,			/* Signal lower frequency */
							SIGLIB_ZERO,			/* D.C. Offset */
							((SLData_t)0.9999965),	/* Frequency change per sample period */
							SIGLIB_ONE,				/* Signal upper frequency */
							&ChirpPhase4,			/* Chirp phase - used for next iteration */
							&ChirpValue4,			/* Chirp current value - used for next iteration */
							SAMPLE_LENGTH);			/* Output array length */

													/* Apply window to real data */
/*		SDA_Window (pRealData,						/* Pointer to source array */
/*			pRealData,								/* Pointer to destination array */
/*			pWindowCoeffs,							/* Pointer to window oefficients */
/*			WINDOW_SIZE);							/* Window length */

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

		Display3DGraph (h3DGraph,					/* Graph handle */
						"Spectrogram",				/* Title of the dataset */
						pResults,					/* Array of Double dataset */
						HALF_FFT_SIZE);				/* Number of data points */

		i++;
	}

	if (kbhit ()) getch ();							/* Clear keyboard buffer */
	printf ("\n");

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


