/* SigLib Example to Compare The Output Scaling Of The DFT And FFT Functions */ /* Include files */ #include #include #include "GraphFunctions.h" /* Define constants */ #define FFT_SIZE ((SLArrayIndex_t)512) #define LOG_FFT_SIZE ((SLArrayIndex_t)9) /* Declare global variables */ SLData_t *pSrcData, *pRealData, *pImagData, *pFFTCoeffs; SLData_t SinePhase; void main(void) { GraphObject *h2DGraph; /* Declare graph object */ pSrcData = SUF_VectorArrayAllocate (FFT_SIZE); /* Allocate memory */ pRealData = SUF_VectorArrayAllocate (FFT_SIZE); pImagData = SUF_VectorArrayAllocate (FFT_SIZE); pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE); printf ("\n\nA very common question in DSP is :\n\n"); printf ("\"why does the FFT give different resutls to the DFT ?\"\n\n"); printf ("The answer is that the difference is just the scaling of the results and it\n"); printf ("due to the efficient nature of the FFT.\n"); printf ("This example program attempts to show the differences by performing a DFT and\n"); printf ("an FFT on the same input data. When you run the program you will notice that\n"); printf ("the FFT results are much larger than those of the DFT. In fact they are N\n"); printf ("times larger than the DFT results, where N is the size of the FFT.\n"); printf ("In order to overcome this it is necessary to scale the results of theFFT to\n"); printf ("match those of the DFT. In many DSP applications (especially fixed point)\n"); printf (", scaling is a system level issue and for that reason Numerix has decided not\n"); printf ("to scale the output right after performing the FFT but to leave it to the\n"); printf ("developer to decide where is the most appropriate place to locate the scaling\n"); printf ("for his or her application.\n\n"); printf ("This issue is discussed in further detail within the SigLib documentation.\n\n"); printf ("Please hit to continue . . ."); getchar (); h2DGraph = /* Initialize graph */ Create2DGraph ("Discrete / Fast Fourier Transforms", /* Graph title */ "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); } /* Create sine wave with suitable freq to avoid edge effects */ SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pSrcData, /* Pointer to destination array */ SIGLIB_SINE_WAVE, /* Signal type - Sine wave */ ((SLData_t)1.0), /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ ((SLData_t)(1.0/16.0)), /* 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 */ pSrcData, /* 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 DFT */ SDA_Rft (pSrcData, /* Pointer to real source array */ pRealData, /* Pointer to real destination array */ pImagData, /* Pointer to imaginary destination array */ FFT_SIZE); /* Transform size */ /* Calculate real magnitude from complex */ SDA_Magnitude (pRealData, /* Pointer to real source array */ pImagData, /* Pointer to imaginary source array */ pRealData, /* Pointer to magnitude destination array */ FFT_SIZE); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Discrete Fourier Transform Results", /* 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 ("\nDiscrete Fourier Transform Results\nPlease hit to continue . . ."); getchar (); /* Create sine wave with suitable freq to avoid edge effects */ SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pRealData, /* Pointer to destination array */ SIGLIB_SINE_WAVE, /* Signal type - Sine wave */ ((SLData_t)1.0), /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ ((SLData_t)(1.0/16.0)), /* 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 */ /* 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 */ /* 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 */ pRealData, /* Pointer to magnitude destination array */ FFT_SIZE); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Fast Fourier Transform Results", /* 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 ("\nFast Fourier Transform Results\nPlease hit to continue . . ."); getchar (); SUF_MemoryFree (pRealData); /* Free memory */ SUF_MemoryFree (pSrcData); SUF_MemoryFree (pImagData); SUF_MemoryFree (pFFTCoeffs); }