/* SigLib - DTMF Generation And Detection Example

Freq. (Hz) 1209 1336 1477 1633 
	697		1	  2	   3	A 
	770		4	  5	   6	B 
	852		7	  8	   9	C 
	941		*	  0	   #	D 
*/

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

/* Define constants */
#define VIEW_TIME_DOMAIN		0					/* Set to '1' to view the time domain plot */
#define VIEW_FREQ_DOMAIN		1					/* Set to '1' to view the frequency domain plot */

#define	SAMPLE_LENGTH			((SLArrayIndex_t)512)
#define	FFT_SIZE				((SLArrayIndex_t)512)
#define	LOG_FFT_SIZE			((SLArrayIndex_t)9)
#define	DTMF_DETECT_LENGTH		102L
#define	SAMPLE_RATE				((SLData_t)8000.0)
#define SIGNAL_MAGNITUDE		SIGLIB_HALF			/* Note - the final output magnitude will be twice this magnitude */

/* Declare arrays and variables */
SLData_t	*pRealData, *pImagData, *pResults, *pFFTCoeffs;		/* Data array pointers */
SLData_t	*pDTMFDetectState;									/* DTMF detector state */
SLData_t	*pDTMFGenCoeffs;									/* DTMF generator frequency look up table */

void main (void)

{
	GraphObject *h2DGraph;							/* Declare graph object */
	char		OutputString [80];

	SLFixData_t	Finished = 0;
	SLFixData_t	Key;
	SLStatus_t	KeyCode;

	pRealData = SUF_VectorArrayAllocate (SAMPLE_LENGTH);
	pImagData = SUF_VectorArrayAllocate (FFT_SIZE);
	pResults = SUF_VectorArrayAllocate (FFT_SIZE);
	pDTMFDetectState = SUF_VectorArrayAllocate (SIGLIB_DTMF_STATE_LENGTH);
	pDTMFGenCoeffs = SUF_VectorArrayAllocate (SIGLIB_DTMF_FTABLE_LENGTH);
	pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE);

	printf ("\n\n\nHit standard DTMF keys 0 - 9, A - D, * and #. <Esc> to exit\n");
	printf ("The key displayed on the screen is decoded from the DTMF.\n\n");
	printf ("Hit any key to start . . .");
	getch ();

	h2DGraph =										/* Initialize graph */
		Create2DGraph ("DTMF Generation And Detection",	/* 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);
	}

	SIF_DtmfGenerate (pDTMFGenCoeffs,				/* Generator coefficient look up table pointer */
			 		  SAMPLE_RATE);					/* Sample rate */
	SIF_DtmfDetect (pDTMFDetectState,				/* Pointer to filter state array */
					SAMPLE_RATE,					/* Sample rate */
					SAMPLE_LENGTH);					/* Array length */

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

	while ((Key = getch ()) != 0x1b)
	{
		if ((KeyCode = SUF_AsciiToKeyCode (Key)) != SIGLIB_NO_DTMF_KEY)
		{
			SDA_DtmfGenerate (pRealData,			/* Destination array pointer */
							  KeyCode,				/* Key code */	
							  SIGNAL_MAGNITUDE,		/* Signal magnitude */	
							  pDTMFGenCoeffs,		/* Generator coefficient look up table pointer */
							  SAMPLE_LENGTH);		/* Array length */

			KeyCode =
				SDA_DtmfDetect (pRealData,				/* Source array pointer */
								pDTMFDetectState,		/* Pointer to filter state array */
								DTMF_DETECT_LENGTH);	/* Array length */

			Key = SUF_KeyCodeToAscii (KeyCode);

#if VIEW_TIME_DOMAIN
			sprintf (OutputString, "DTMF signal for key : %c", Key);
			Display2DGraph (h2DGraph,				/* Graph handle */
						    OutputString,			/* Title of the dataset */
						    pRealData,				/* 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 ("\n%s\nPlease hit <Carriage Return> to continue . . .", OutputString);
#endif

#if VIEW_FREQ_DOMAIN
													/* 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 */

			sprintf (OutputString, "DTMF signal for key : %c", Key);
			Display2DGraph (h2DGraph,				/* Graph handle */
						    OutputString,			/* 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_NEW);			/* New graph */
			printf ("\n%s\nPlease hit <Carriage Return> to continue . . .", OutputString);
#endif
			}
	}

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



