/* SigLib FFT and Hanning window Example */ /* Include files */ #include #include #include "GraphFunctions.h" /* Define constants */ #define FFT_SIZE ((SLArrayIndex_t)512) #define LOG_FFT_SIZE ((SLArrayIndex_t)9) #define WINDOW_SIZE FFT_SIZE /* Declare global variables */ SLData_t *pRealData, *pImagData, *pRealDataCopy, *pImagDataCopy, *pWindowCoeffs, *pResults, *pFFTCoeffs; SLData_t SinePhase; void main(void) { GraphObject *h2DGraph; /* Declare graph object */ /* Allocate memory */ pRealData = SUF_VectorArrayAllocate (FFT_SIZE); pImagData = SUF_VectorArrayAllocate (FFT_SIZE); pRealDataCopy = SUF_VectorArrayAllocate (FFT_SIZE); pImagDataCopy = SUF_VectorArrayAllocate (FFT_SIZE); pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE); pResults = SUF_VectorArrayAllocate (FFT_SIZE); /* RMS result array */ pWindowCoeffs = SUF_VectorArrayAllocate (WINDOW_SIZE); /* Window array */ SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pRealData, /* Pointer to destination array */ SIGLIB_SINE_WAVE, /* Signal type - Sine wave */ ((SLData_t)0.9), /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ ((SLData_t)0.015625), /* 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 */ FFT_SIZE); /* Output array length */ h2DGraph = /* Initialize graph */ Create2DGraph ("Fast Fourier Transform", /* 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); } /* 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 */ Display2DGraph (h2DGraph, /* Graph handle */ "Synthesized sine wave", /* Title of the dataset */ pRealData, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nSynthesized sine wave\nPlease hit to continue . . ."); getchar (); /* 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 */ SDA_Copy (pRealData, /* Pointer to source array */ pRealDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ SDA_Copy (pImagData, /* Pointer to source array */ pImagDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ /* Calculate real power from complex */ SDA_LogMagnitude (pRealData, /* Pointer to real source array */ pImagData, /* Pointer to imaginary source array */ pResults, /* Pointer to log magnitude destination array */ FFT_SIZE); /* Data array length */ Display2DGraph (h2DGraph, /* Graph handle */ "FFT of pure sine wave (integer number of bins)", /* 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 ("\nFFT of pure sine wave (integer number of bins)\nPlease hit to continue . . ."); getchar (); SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pRealData, /* Pointer to destination array */ SIGLIB_SINE_WAVE, /* Signal type - Sine wave */ ((SLData_t)0.9), /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ ((SLData_t)0.019), /* 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 */ FFT_SIZE); /* Output array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Synthesized sine wave", /* Title of the dataset */ pRealData, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nSynthesized sine wave\nPlease hit to continue . . ."); getchar (); /* 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 */ SDA_Copy (pRealData, /* Pointer to source array */ pRealDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ SDA_Copy (pImagData, /* Pointer to source array */ pImagDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ /* Calculate real power from complex */ SDA_LogMagnitude (pRealData, /* Pointer to real source array */ pImagData, /* Pointer to imaginary source array */ pResults, /* Pointer to log magnitude destination array */ FFT_SIZE); /* Data array length */ Display2DGraph (h2DGraph, /* Graph handle */ "FFT of pure sine wave (integer number of bins)", /* 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 ("\nFFT of pure sine wave (integer number of bins)\nPlease hit to continue . . ."); getchar (); SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pRealData, /* Pointer to destination array */ SIGLIB_COS_WAVE, /* Signal type - Cosine wave */ ((SLData_t)0.9), /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ ((SLData_t)0.0078125), /* 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 */ FFT_SIZE); /* Output array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Hanning windowed sine wave", /* Title of the dataset */ pRealData, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nHanning windowed sine wave\nPlease hit to continue . . ."); getchar (); /* Generate Hanning window table */ SIF_Window (pWindowCoeffs, /* Pointer to window oefficient */ SIGLIB_HANNING, /* Window type */ SIGLIB_ZERO, /* Window coefficient */ FFT_SIZE); /* Window length */ /* Apply window to real data */ /* Apply window to data */ SDA_Window (pRealData, /* Pointer to source array */ pRealData, /* Pointer to destination array */ pWindowCoeffs, /* Pointer to window oefficients */ WINDOW_SIZE); /* Window length */ Display2DGraph (h2DGraph, /* Graph handle */ "Hanning windowed sine wave", /* Title of the dataset */ pRealData, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nHanning windowed sine wave\nPlease hit to continue . . ."); getchar (); /* 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 */ SDA_Copy (pRealData, /* Pointer to source array */ pRealDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ SDA_Copy (pImagData, /* Pointer to source array */ pImagDataCopy, /* Pointer to destination array */ FFT_SIZE); /* Array length */ SDA_CfftShift (pRealData, pImagData, pRealData, pImagData, FFT_SIZE); /* Shift D.C. location */ /* Calculate real power from complex */ SDA_LogMagnitude (pRealData, /* Pointer to real source array */ pImagData, /* Pointer to imaginary source array */ pResults, /* Pointer to log magnitude destination array */ FFT_SIZE); /* Data array length */ Display2DGraph (h2DGraph, /* Graph handle */ "FFT of windowed sine wave (dB), non integer # of bins, D.C. Shifted", /* 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 ("\nFFT of windowed sine wave (dB), non integer # of bins, D.C. Shifted\nPlease hit to continue . . ."); getchar (); SDA_Cifft (pRealDataCopy, pImagDataCopy, pFFTCoeffs, SIGLIB_NULL_ARRAY_INDEX_PTR, FFT_SIZE, LOG_FFT_SIZE); /* Perform inverse FFT */ Display2DGraph (h2DGraph, /* Graph handle */ "IFFT done", /* Title of the dataset */ pRealDataCopy, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nIFFT done\n"); SUF_MemoryFree (pRealData); /* Free memory */ SUF_MemoryFree (pImagData); SUF_MemoryFree (pRealDataCopy); SUF_MemoryFree (pImagDataCopy); SUF_MemoryFree (pResults); SUF_MemoryFree (pWindowCoeffs); SUF_MemoryFree (pFFTCoeffs); }