/* SigLib FIR Filter Design Example */ #include #include #include "GraphFunctions.h" #include "plot_fd.h" /* Define constants */ #define FILTER_LENGTH ((SLArrayIndex_t)125) #define FFT_LENGTH ((SLArrayIndex_t)512) /* Declare global arrays and variables */ SLData_t pLPFilterCoeffs[FILTER_LENGTH]; SLData_t pLPFilterState[FILTER_LENGTH]; SLData_t pBPFilterCoeffs[FILTER_LENGTH]; SLData_t pHPFilterCoeffs[FILTER_LENGTH]; SLData_t pHPFilterState[FILTER_LENGTH]; SLArrayIndex_t LPFilterIndex; SLArrayIndex_t HPFilterIndex; SLData_t *pSrc; void main(void); void main(void) { GraphObject *h2DGraph; /* Declare graph object */ SLData_t FilterInverseCoherentGain; pSrc = SUF_VectorArrayAllocate (FFT_LENGTH); if (pSrc == NULL) { printf ("Memory allocation error in main ()\n"); return; } h2DGraph = /* Initialize graph */ Create2DGraph ("FIR Filter Design", /* 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 the filters */ SIF_Fir (pLPFilterState, /* Pointer to filter state array */ &LPFilterIndex, /* Pointer to filter index register */ FILTER_LENGTH); /* Filter length */ SIF_Fir (pHPFilterState, /* Pointer to filter state array */ &HPFilterIndex, /* Pointer to filter index register */ FILTER_LENGTH); /* Filter length */ SIF_LowPassFirFilter (pLPFilterCoeffs, /* Filter coeffs array */ (3000.0/8000.0), /* Filter cut off frequency */ SIGLIB_HANNING, /* Window type */ FILTER_LENGTH); /* Filter length */ SIF_BandPassFirFilter (pBPFilterCoeffs, /* Filter coeffs array */ (1600.0/8000.0), /* Filter center frequency */ (2000.0/8000.0), /* Filter bandwidth */ SIGLIB_HANNING, /* Window type */ FILTER_LENGTH); /* Filter length */ SIF_HighPassFirFilter (pHPFilterCoeffs, /* Filter coeffs array */ (1000.0/8000.0), /* Filter cut off frequency */ SIGLIB_HANNING, /* Window type */ FILTER_LENGTH); /* Filter length */ /* Display coefficients for each filter */ Display2DGraph (h2DGraph, /* Graph handle */ "Low-pass Filter Coefficients", /* Title of the dataset */ pLPFilterCoeffs, /* Array of Double dataset */ FILTER_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 ("\nLow-pass Filter Coefficients\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "Band-pass Filter Coefficients", /* Title of the dataset */ pBPFilterCoeffs, /* Array of Double dataset */ FILTER_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 ("\nBand-pass Filter Coefficients\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "High-pass Filter Coefficients", /* Title of the dataset */ pHPFilterCoeffs, /* Array of Double dataset */ FILTER_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 ("\nHigh-pass Filter Coefficients\nPlease hit to continue . . ."); getchar (); /* Display frequency response for each filter */ SDA_Clear (pSrc, /* Pointer to destination array */ FFT_LENGTH); /* Array length */ SDA_Copy (pLPFilterCoeffs, /* Pointer to source array */ pSrc, /* Pointer to destination array */ FILTER_LENGTH); /* Array length */ plot_frequency_domain (pSrc, SIGLIB_FLAT_TOP, "Low-pass Filter Response", FFT_LENGTH, FFT_LENGTH); SDA_Clear (pSrc, /* Pointer to destination array */ FFT_LENGTH); /* Array length */ SDA_Copy (pBPFilterCoeffs, /* Pointer to source array */ pSrc, /* Pointer to destination array */ FILTER_LENGTH); /* Array length */ plot_frequency_domain (pSrc, SIGLIB_FLAT_TOP, "Band-pass Filter Response", FFT_LENGTH, FFT_LENGTH); SDA_Clear (pSrc, /* Pointer to destination array */ FFT_LENGTH); /* Array length */ SDA_Copy (pHPFilterCoeffs, /* Pointer to source array */ pSrc, /* Pointer to destination array */ FILTER_LENGTH); /* Array length */ plot_frequency_domain (pSrc, SIGLIB_FLAT_TOP, "High-pass Filter Response", FFT_LENGTH, FFT_LENGTH); /* Combine filters and display combined result */ /* Generate an impulse input signal */ SDA_SignalGenerate (pSrc, /* 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 */ FFT_LENGTH); /* Output array length */ /* Low-pass filter */ SDA_Fir(pSrc, /* Input array to be filtered */ pSrc, /* Filtered output array */ pLPFilterState, /* Pointer to filter state array */ pLPFilterCoeffs, /* Pointer to filter coefficients */ &LPFilterIndex, /* Pointer to filter index register */ FILTER_LENGTH, /* Filter length */ FFT_LENGTH); /* Array length */ /* High-pass filter */ SDA_Fir(pSrc, /* Input array to be filtered */ pSrc, /* Filtered output array */ pHPFilterState, /* Pointer to filter state array */ pHPFilterCoeffs, /* Pointer to filter coefficients */ &HPFilterIndex, /* Pointer to filter index register */ FILTER_LENGTH, /* Filter length */ FFT_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Dual Filter Impulse Response", /* Title of the dataset */ pSrc, /* Array of Double dataset */ FFT_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 ("\nDual Filter Impulse Response\nPlease hit to continue . . ."); getchar (); plot_frequency_domain (pSrc, SIGLIB_FLAT_TOP, "Dual filter frequency response", FFT_LENGTH, FFT_LENGTH); /* We will design another LPF FIR filter and normalize the gain */ /* Initialise the filters */ SIF_Fir (pLPFilterState, /* Pointer to filter state array */ &LPFilterIndex, /* Pointer to filter index register */ FILTER_LENGTH); /* Filter length */ SIF_LowPassFirFilter (pLPFilterCoeffs, /* Filter coeffs array */ 0.012, /* Filter cut off frequency */ SIGLIB_HAMMING, /* Window type */ FILTER_LENGTH); /* Filter length */ FilterInverseCoherentGain = SDA_FirFilterInverseCoherentGain (pLPFilterCoeffs, FILTER_LENGTH); printf ("CoeffSum = %lf\n\n", SDA_Sum (pLPFilterCoeffs, FILTER_LENGTH)); printf ("Inverse coherent gain = %lf\n\n", FilterInverseCoherentGain); SDA_Multiply (pLPFilterCoeffs, FilterInverseCoherentGain, pLPFilterCoeffs, FILTER_LENGTH); /* Normalize 0dB gain for graph */ SDA_Multiply (pLPFilterCoeffs, 20000.0, pLPFilterCoeffs, FILTER_LENGTH); /* Display coefficients for each filter */ Display2DGraph (h2DGraph, /* Graph handle */ "Low-pass Filter Coefficients", /* Title of the dataset */ pLPFilterCoeffs, /* Array of Double dataset */ FILTER_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 ("\nLow-pass Filter Coefficients\nPlease hit to continue . . ."); getchar (); /* Display frequency response for each filter */ plot_frequency_domain (pLPFilterCoeffs, SIGLIB_RECTANGLE, "Low-pass Filter Response", FILTER_LENGTH, FFT_LENGTH); SUF_MemoryFree (pSrc); /* Free memory */ }