/* SigLib 180 Degree Phase Reversal Detector Example */

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

/* Define constants */
#define	SAMPLE_LENGTH			256L
#define	SAMPLE_RATE				((SLData_t)8000.0)
#define	FILTER_LENGTH			7L						/* 180 degree phase detector filter length */
#define CARRIER_FREQ			((SLData_t)2100.0)		/* Carrier frequency */

#define	SINE_TABLE_SIZE			((SLArrayIndex_t)1024)	/* Look up table for fast sine calculation */

SLData_t		*pData;
SLData_t		*pFilterCoeffs, *pFilterState;			/* 180 degree phase detector filter coefficient pointer */

SLArrayIndex_t	FilterIndex;							/* Filter index */
SLData_t		CosineTablePhase;						/* Cosine table phase */
SLData_t		SavedSample;							/* saved sample for next iteration */

SLArrayIndex_t	PreviousOutputSign;						/* Sign of previous output value */
SLArrayIndex_t	PhaseChangeLocation;					/* Location of phase change in array */

SLData_t		*pFastCosineLookUpTable;				/* For fast sine lookup */
SLData_t		SinePhase;


void   main(void)

{
	GraphObject *h2DGraph;							/* Declare graph object */

	pData = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pFilterCoeffs = SUF_VectorArrayAllocate (FILTER_LENGTH);
	pFilterState = SUF_VectorArrayAllocate (FILTER_LENGTH);
	pFastCosineLookUpTable = SUF_VectorArrayAllocate (SINE_TABLE_SIZE);

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("180 Degree Phase Reversal Detector",	/* Graph title */
					   "Time",						/* 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);
	}


	SinePhase = 1.2;								/* Arbitrary phase - radians */
//	SinePhase = SIGLIB_ZERO;
//	SinePhase = SIGLIB_PI / SIGLIB_TWO;
//	SinePhase = SIGLIB_PI;
	SDA_SignalGenerate (pData,						/* 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 */
						CARRIER_FREQ / 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/2);			/* Output array length */

	SinePhase += SIGLIB_PI;							/* Arbitrary phase - radians */
	SDA_SignalGenerate (pData+(SAMPLE_LENGTH/2),	/* 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 */
						CARRIER_FREQ / 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/2);			/* Output array length */

	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Source Signal",				/* Title of the dataset */
				    pData,							/* 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 ();

	SIF_180DegreePhaseDetect (&CosineTablePhase,			/* Fast cosine look up table phase */
							  pFastCosineLookUpTable,		/* Pointer to fast cosine look up table */
							  SINE_TABLE_SIZE,				/* Fast cosine look up table size */
							  CARRIER_FREQ / SAMPLE_RATE,	/* Carrier frequency */
							  pFilterState,					/* Pointer to filter state array */
							  pFilterCoeffs,				/* Pointer to filter coefficients */
							  &FilterIndex,					/* Pointer to filter index */
							  FILTER_LENGTH,				/* Filter length */
							  &PreviousOutputSign);			/* Pointer to sign of previous output */

	PhaseChangeLocation =
		SDA_180DegreePhaseDetect (pData,						/* Source data pointer */
								  pData,						/* Destination data pointer */
								  &CosineTablePhase,			/* Fast cosine look up table phase */
								  pFastCosineLookUpTable,		/* Pointer to fast cosine look up table */
								  SINE_TABLE_SIZE,				/* Fast cosine look up table size */
								  CARRIER_FREQ / SAMPLE_RATE,	/* Carrier frequency */
								  pFilterState,					/* Pointer to filter state array */
								  pFilterCoeffs,				/* Pointer to filter coefficients */
								  &FilterIndex,					/* Pointer to filter index */
								  FILTER_LENGTH,				/* Filter length */
								  &PreviousOutputSign,			/* Pointer to sign of previous output */
								  SAMPLE_LENGTH);				/* Length of input array */

	printf ("Phase change location = %ld\n", PhaseChangeLocation);
	Display2DGraph (h2DGraph,						/* Graph handle */
				    "Phase Detector Output",		/* Title of the dataset */
				    pData,							/* 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 ("\nPhase Detector Output\nPlease hit <Carriage Return> to continue . . ."); getchar ();

	SUF_MemoryFree (pData);							/* Free memory */
	SUF_MemoryFree (pFilterCoeffs);
	SUF_MemoryFree (pFilterState);
	SUF_MemoryFree (pFastCosineLookUpTable);

}


