/* SigLib Amplitude Modulation / Demodulation Example */

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

/* Define constants */
#define SAMPLE_RATE				((SLData_t)10000.0)
#define CARRIER_FREQUENCY		((SLData_t)2500.0)
#define CARRIER_TABLE_LENGTH	((SLArrayIndex_t)1000)

#define	PRE_FILTER_LENGTH	14L
#define	LPF_FILTER_LENGTH	27L
#define	SAMPLE_LENGTH		256L
#define	FFT_SIZE			256L
#define	LOG_FFT_SIZE		((SLArrayIndex_t)8)

			/* Initialise filter coefficients */
SLData_t	pPreFilterTaps[PRE_FILTER_LENGTH] = {
	-2.0,	-5.0, -6.0, -5.0, -1.5,	 4.5,  9.0,
	 10.0,	 9.0,  4.5, -1.0, -5.0, -6.0, -2.0
	};

SLData_t	pPreFilterState[PRE_FILTER_LENGTH];
SLArrayIndex_t	PreFilterIndex;

SLData_t	pLpfFilterTaps[LPF_FILTER_LENGTH] = {
	 0.076923,	 0.0,		-0.09091,	 0.0,	  0.111111,	 0.0,
	-0.14286,	 0.0,		 0.2,		 0.0,	 -0.33333,	 0.0,
	 1.0,		 1.570796,	 1.0,
	 0.0,		-0.33333,	 0.0,		 0.2,	  0.0,		-0.14286,
	 0.0,		 0.111111,	 0.0,	 	-0.09091, 0.0,		 0.076923
	};

SLData_t		pLpfFilterState[LPF_FILTER_LENGTH];
SLArrayIndex_t	pLpfFilterIndex;

SLData_t		*pInput, *pCarrierTable, *modulated, *demodulated;
SLData_t		CarrierTablePhase;


void	main(void);

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

	pInput = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pCarrierTable = SUF_VectorArrayAllocate (CARRIER_TABLE_LENGTH);
	modulated = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	demodulated = SUF_VectorArrayAllocate (SAMPLE_LENGTH);

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("Amplitude Modulation / Demodulation",	/* 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);
	}

	SIF_AmplitudeModulate2 (pCarrierTable,			/* Carrier table pointer */
			&CarrierTablePhase,						/* Carrier table index */
			CARRIER_TABLE_LENGTH);					/* Modulator array length */

	SIF_Fir (pPreFilterState,						/* Pointer to filter state array */
			 &PreFilterIndex,						/* Pointer to filter index register */
			 PRE_FILTER_LENGTH);					/* Filter length */
	SIF_Fir (pLpfFilterState,						/* Pointer to filter state array */
			 &pLpfFilterIndex,						/* Pointer to filter index register */
			 LPF_FILTER_LENGTH);					/* Filter length */
	
			/* Generate signal to be shifted */
	SDA_SignalGenerate (pInput,						/* 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 */

			/* Apply fir filter and store filtered data */
	SDA_Fir (pInput,								/* Input array to be filtered */
			 pInput,								/* Filtered output array */
			 pPreFilterState,						/* Pointer to filter state array */
			 pPreFilterTaps,						/* Pointer to filter coefficients */
			 &PreFilterIndex,						/* Pointer to filter index register */
			 PRE_FILTER_LENGTH,						/* Filter length */
			 SAMPLE_LENGTH);						/* Array length */

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

	plot_frequency_domain (pInput, SIGLIB_FLAT_TOP, "Raw signal spectrum        ", SAMPLE_LENGTH, FFT_SIZE);



	SDA_AmplitudeModulate2 (pInput,								/* Modulating signal source pointer */
							pCarrierTable,						/* Carrier table pointer */
							modulated,							/* Modulated signal destination pointer */
							&CarrierTablePhase,					/* Carrier table phase */
							CARRIER_FREQUENCY / SAMPLE_RATE,	/* Carrier frequency */
							CARRIER_TABLE_LENGTH,				/* Modulator array length */
							SAMPLE_LENGTH);						/* Array length */

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

	plot_frequency_domain (modulated, SIGLIB_FLAT_TOP, "Modulated signal spectrum ", SAMPLE_LENGTH, FFT_SIZE);


	SDA_AmplitudeModulate2 (modulated,							/* Modulating signal source pointer */
							pCarrierTable,						/* Carrier table pointer */
							demodulated,						/* Modulated signal destination pointer */
							&CarrierTablePhase,					/* Carrier table phase */
							CARRIER_FREQUENCY / SAMPLE_RATE,	/* Carrier frequency */
							CARRIER_TABLE_LENGTH,				/* Modulator array length */
							SAMPLE_LENGTH);						/* Array length */

	SIF_Fir (pLpfFilterState,						/* Pointer to filter state array */
			 &pLpfFilterIndex,						/* Pointer to filter index register */
			 LPF_FILTER_LENGTH);					/* Filter length */
	SDA_Fir (demodulated,							/* Input array to be filtered */
			 demodulated,							/* Filtered output array */
			 pLpfFilterState,						/* Pointer to filter state array */
			 pLpfFilterTaps,						/* Pointer to filter coefficients */
			 &pLpfFilterIndex,						/* Pointer to filter index register */
			 LPF_FILTER_LENGTH,						/* Filter length */
			 SAMPLE_LENGTH);						/* Array length */

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

	plot_frequency_domain (demodulated, SIGLIB_FLAT_TOP, "Demodulated signal spectrum ", SAMPLE_LENGTH, FFT_SIZE);

	SUF_MemoryFree (pInput);						/* Free memory */
	SUF_MemoryFree (pCarrierTable);
	SUF_MemoryFree (modulated);
	SUF_MemoryFree (demodulated);
}


