/* SigLib FFT and Hanning window test program */

/* Include files */
#include <math.h>
#include <stdlib.h>
#include <siglib.h>
#include <nhl.h>

/* Define constants */
#define FFT_SIZE            512
#define LOG_FFT_SIZE        9
#define WINDOW_SIZE         FFT_SIZE

#define SIGNAL_MAGNITUDE    1.0
#define SIGNAL_FREQUENCY    0.019	/* Normalised to 1.0 Hz */

/* Define global variables */
SLData_t	*pRealData, *pImagData, *pWindowCoeffs, *pResultsData, *pFFTCoeffs;
SLData_t	SinePhase;

void main (void)
{
    SLFixData_t	SigLibErrorCode;

    pRealData = SUF_VectorArrayAllocate (FFT_SIZE);			/* Allocate data arrays */
    pImagData = SUF_VectorArrayAllocate (FFT_SIZE);
    pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE);		/* FFT Coefficients */
    pResultsData = SUF_VectorArrayAllocate (FFT_SIZE);		/* RMS result data array */
    pWindowCoeffs = SUF_VectorArrayAllocate (WINDOW_SIZE);	/* Window coefficients array */

    if ((pRealData == NULL) || (pImagData == NULL) || (pFFTCoeffs == NULL) || 
    	(pResultsData == NULL) || (pWindowCoeffs == NULL))
    {
        SUF_Halt;											/* Halt on memory allocation error */
    }

    SigLibErrorCode = SIF_Fft (pFFTCoeffs, SIGLIB_NULL_FIX_DATA_PTR, FFT_SIZE); /* Init. FFT */
    if (SigLibErrorCode != SIGLIB_NO_ERROR)
    {
        SUF_Halt;											/* Halt on memory allocation error */
    }

    SIF_Window (pWindowCoeffs, SIGLIB_HANNING, SIGLIB_ZERO, WINDOW_SIZE);  /* Generate Hanning window table */

    SinePhase = SIGLIB_ZERO;								/* Generate signal for FFT input */
    SDA_SignalGenerate (pRealData, SIGLIB_SINE_WAVE, SIGNAL_MAGNITUDE, SIGLIB_FILL,
                         SIGNAL_FREQUENCY, SIGLIB_ZERO, SIGLIB_ZERO, SIGLIB_ZERO, &SinePhase,
                         SIGLIB_NULL_DATA_PTR, FFT_SIZE);

    SDA_Window (pRealData, pRealData, pWindowCoeffs, WINDOW_SIZE);  /* Apply window to data */

															/* Perform FFT */
    SDA_Rfft (pRealData, pImagData, pFFTCoeffs, SIGLIB_NULL_FIX_DATA_PTR, FFT_SIZE, LOG_FFT_SIZE);
															/* Scale output for display */
    SDA_ComplexScalarDivide (pRealData, pImagData, ((SLData_t)FFT_SIZE), pRealData, pImagData, FFT_SIZE);
	SDA_LogMagnitude (pRealData, pImagData, pResultsData, FFT_SIZE);	/* Calculate power */

	display_buffer_line (pResultsData, GRAPH_SCALE, GRAPH_NEW, SHORT_YELLOW, FFT_SIZE);	/* Display array */
	printat (29, 1, "FFT of windowed sine wave (dB), non integer # of bins");
	cross_hairs (pResultsData, GRAPH_SCALE, FFT_SIZE);		/* Display cross hairs */

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