/* SigLib Comb Filter Example */ /* This program demonstrates the impulse and frequency response of four different arrangents of comb filter. The flow diagrams for each are : Comb filter type 1 |-----| - |-----| IN ---->|Delay|------>| | | |-----| | | | + | + |----> OUT |---------------->| | |-----| Comb filter type 2 |-----| IN ---->|comb |------> OUT |-----| Comb filter type 3 |-----| |-----| IN ---->|Comb1|----->|Comb2|-->|-----| | |-----| | |-----| | | | ------------->| + |----> OUT | | | -------------------------->|-----| Comb filter type 4 |------| |------| IN ---->|Delay1|----->|Delay2|-->|-----| | |------| | |------| | | | -------------->| + |----> OUT | | | ---------------------------->|-----| */ #include #include #include "GraphFunctions.h" /* Define constants */ #define SAMPLE_LENGTH ((SLArrayIndex_t)512) #define FFT_SIZE SAMPLE_LENGTH #define LOG_FFT_SIZE ((SLArrayIndex_t)9) SLArrayIndex_t FilterLength; SLArrayIndex_t FilterIndex1, FilterIndex2; SLData_t FilterSum1, FilterSum2; SLData_t *pSrc1, *pSrc2, *pSrc3, *pImagData, *pMagnitude, *pPhase, *pStateArray1, *pStateArray2, *pFFTCoeffs; SLData_t K1, K2, K3; void main(void); void main(void) { GraphObject *h2DGraph; /* Declare graph object */ SLFixData_t i; h2DGraph = /* Initialize graph */ Create2DGraph ("Comb Filter", /* 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); } system ("cls"); printf (" This program demonstrates the impulse and frequency\n"); printf (" response of four different arrangents of comb filter\n\n."); printf ("Enter a comb filter length < 512 =>"); scanf ("%d", &FilterLength); printf ("\nComb filter length => %d\n", FilterLength); getchar (); /* Clear keyboard buffer */ pImagData = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pMagnitude = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pPhase = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pSrc1 = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pSrc2 = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pSrc3 = SUF_VectorArrayAllocate (SAMPLE_LENGTH); pStateArray1 = SUF_VectorArrayAllocate (FilterLength); pStateArray2 = SUF_VectorArrayAllocate (FilterLength); pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE); /* 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 */ /* Comb filter type 1 */ system ("cls"); printf ("Comb filter type 1\n\n"); printf (" |-----| -\n"); printf ("IN ---->|Delay|------>|-----|\n"); printf (" | |-----| | |\n"); printf (" | | |\n"); printf (" | | + |----> OUT\n"); printf (" | | |\n"); printf (" | + | |\n"); printf (" ----------------->|-----|\n"); printf ("\n Comb filter length => %d", FilterLength); SIF_Delay (pStateArray1, /* Pointer to delay state array */ &FilterIndex1, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ /* Generate an impulse */ SDA_SignalGenerate (pSrc1, /* 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 */ SAMPLE_LENGTH); /* Output array length */ /* Apply comb filter and store filtered data */ for (i = 0; i < SAMPLE_LENGTH; i++) { *pSrc2++ = *pSrc1 - SDS_Delay (*pSrc1, /* Input data sample */ pStateArray1, /* Pointer to delay state array */ &FilterIndex1, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ pSrc1++; } pSrc2 -= SAMPLE_LENGTH; /* Reset pointers */ pSrc1 -= SAMPLE_LENGTH; Display2DGraph (h2DGraph, /* Graph handle */ "Impulse Response", /* Title of the dataset */ pSrc2, /* 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 ("\nImpulse Response\nPlease hit to continue . . ."); getchar (); /* Perform real FFT */ SDA_Rfft (pSrc2, /* 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_RectangularToPolar (pSrc2, /* Pointer to source real array */ pImagData, /* Pointer to source imaginary array */ pMagnitude, /* Pointer to destination magnitude array */ pPhase, /* Pointer to destination phase array */ SAMPLE_LENGTH); /* Array length */ SDA_Multiply (pMagnitude, /* Pointer to source array */ ((SLData_t)65536.0), /* Multiplier */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ SDA_10Log10 (pMagnitude, /* Pointer to source array */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Magnitude (dB)", /* Title of the dataset */ pMagnitude, /* 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 ("\nMagnitude Response\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "Phase", /* Title of the dataset */ pPhase, /* Array of Double dataset */ SAMPLE_LENGTH, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nPhase Response\nPlease hit to continue . . ."); getchar (); /* Comb filter type 2 */ system ("cls"); printf ("Comb filter type 2\n\n"); printf (" |-----|\n"); printf ("IN ---->|comb |------> OUT\n"); printf (" |-----|\n"); printf ("\n Comb filter length => %d", FilterLength); SIF_Comb (pStateArray1, /* Pointer to filter delay state array */ &FilterIndex1, /* Pointer to filter index register */ &FilterSum1, /* Pointer to filter sum register */ FilterLength); /* Filter length */ /* Generate an impulse */ SDA_SignalGenerate (pSrc1, /* 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 */ SAMPLE_LENGTH); /* Output array length */ /* Apply comb filter and store filtered data */ for (i = 0; i < SAMPLE_LENGTH; i++) { *pSrc2++ = SDS_Comb (*pSrc1++, /* Input data sample to be filtered */ pStateArray1, /* Pointer to filter state array */ &FilterIndex1, /* Pointer to filter index register */ &FilterSum1, /* Pointer to filter sum register */ FilterLength); /* Filter length */ } pSrc2 -= SAMPLE_LENGTH; /* Reset pointers */ pSrc1 -= SAMPLE_LENGTH; Display2DGraph (h2DGraph, /* Graph handle */ "Impulse Response", /* Title of the dataset */ pSrc2, /* 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 ("\nImpulse Response\nPlease hit to continue . . ."); getchar (); /* Perform real FFT */ SDA_Rfft (pSrc2, /* 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_RectangularToPolar (pSrc2, /* Pointer to source real array */ pImagData, /* Pointer to source imaginary array */ pMagnitude, /* Pointer to destination magnitude array */ pPhase, /* Pointer to destination phase array */ SAMPLE_LENGTH); /* Array length */ SDA_Multiply (pMagnitude, /* Pointer to source array */ ((SLData_t)65536.0), /* Multiplier */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ SDA_10Log10 (pMagnitude, /* Pointer to source array */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Magnitude (dB)", /* Title of the dataset */ pMagnitude, /* 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 ("\nMagnitude Response\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "Phase", /* Title of the dataset */ pPhase, /* Array of Double dataset */ SAMPLE_LENGTH, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nPhase Response\nPlease hit to continue . . ."); getchar (); /* Comb filter type 3 */ system ("cls"); printf ("Comb filter type 3\n\n"); printf (" |-----| |-----|\n"); printf ("IN ---->|Comb1|----->|Comb2|-->|-----|\n"); printf (" | |-----| | |-----| | |\n"); printf (" | | | |\n"); printf (" | ------------->| + |----> OUT\n"); printf (" | | |\n"); printf (" | | |\n"); printf (" -------------------------->|-----|\n"); printf ("\n Comb filter length => %d", FilterLength); SIF_Comb (pStateArray1, /* Pointer to filter delay state array */ &FilterIndex1, /* Pointer to filter index register */ &FilterSum1, /* Pointer to filter sum register */ FilterLength); /* Filter length */ SIF_Comb (pStateArray2, /* Pointer to filter delay state array */ &FilterIndex2, /* Pointer to filter index register */ &FilterSum2, /* Pointer to filter sum register */ FilterLength); /* Filter length */ /* Generate an impulse */ SDA_SignalGenerate (pSrc1, /* 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 */ SAMPLE_LENGTH); /* Output array length */ for (i = 0; i < SAMPLE_LENGTH; i++) { /* Apply comb filter 1 and store filtered data */ *pSrc2 = SDS_Comb (*pSrc1, /* Input data sample to be filtered */ pStateArray1, /* Pointer to filter state array */ &FilterIndex1, /* Pointer to filter index register */ &FilterSum1, /* Pointer to filter sum register */ FilterLength); /* Filter length */ /* Apply comb filter 1 and store filtered data */ *pSrc3 = SDS_Comb (*pSrc2, /* Input data sample to be filtered */ pStateArray2, /* Pointer to filter state array */ &FilterIndex2, /* Pointer to filter index register */ &FilterSum2, /* Pointer to filter sum register */ FilterLength); /* Filter length */ *pSrc3 = *pSrc3 + *pSrc1++; *pSrc3 = *pSrc3 + *pSrc2++; pSrc3++; } pSrc1 -= SAMPLE_LENGTH; pSrc2 -= SAMPLE_LENGTH; pSrc3 -= SAMPLE_LENGTH; SDA_Scale (pSrc3, /* Pointer to source array */ pSrc3, /* Pointer to destination array */ SIGLIB_ONE, /* Peak level */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Impulse Response", /* Title of the dataset */ pSrc3, /* 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 ("\nImpulse Response\nPlease hit to continue . . ."); getchar (); /* Perform real FFT */ SDA_Rfft (pSrc3, /* 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_RectangularToPolar (pSrc3, /* Pointer to source real array */ pImagData, /* Pointer to source imaginary array */ pMagnitude, /* Pointer to destination magnitude array */ pPhase, /* Pointer to destination phase array */ SAMPLE_LENGTH); /* Array length */ SDA_Multiply (pMagnitude, /* Pointer to source array */ ((SLData_t)65536.0), /* Multiplier */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ SDA_10Log10 (pMagnitude, /* Pointer to source array */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Magnitude (dB)", /* Title of the dataset */ pMagnitude, /* 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 ("\nMagnitude Response\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "Phase", /* Title of the dataset */ pPhase, /* Array of Double dataset */ SAMPLE_LENGTH, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nPhase Response\nPlease hit to continue . . ."); getchar (); /* Comb filter type 4 */ system ("cls"); printf ("Comb filter type 4\n"); printf (" |------| |------|\n"); printf ("IN ---->|Delay1|----->|Delay2|-->|-----|\n"); printf (" | |------| | |------| | |\n"); printf (" | | | |\n"); printf (" | -------------->| + |----> OUT\n"); printf (" | | |\n"); printf (" | | |\n"); printf (" ---------------------------->|-----|\n"); printf ("\n Comb filter length => %d", FilterLength); /* Initialize delays */ SIF_Delay (pStateArray1, /* Pointer to delay state array */ &FilterIndex1, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ SIF_Delay (pStateArray2, /* Pointer to delay state array */ &FilterIndex2, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ K1 = SIGLIB_QUARTER; K2 = SIGLIB_MINUS_HALF; K3 = SIGLIB_QUARTER; /* K1 = SIGLIB_HALF; K2 = SIGLIB_HALF; K3 = SIGLIB_ZERO; */ /* Generate an impulse */ SDA_SignalGenerate (pSrc1, /* 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 */ SAMPLE_LENGTH); /* Output array length */ for (i = 0; i < SAMPLE_LENGTH; i++) { /* Apply comb filter 1 and store filtered data */ *pSrc2 = SDS_Delay (*pSrc1, /* Input data sample */ pStateArray1, /* Pointer to delay state array */ &FilterIndex1, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ /* Apply comb filter 1 and store filtered data */ *pSrc3 = K3 * SDS_Delay (*pSrc2, /* Input data sample */ pStateArray2, /* Pointer to delay state array */ &FilterIndex2, /* Pointer to delay state index */ FilterLength); /* Delay filter length */ *pSrc3 = *pSrc3 + (*pSrc1++ * K1); *pSrc3 = *pSrc3 + (*pSrc2++ * K2); pSrc3++; } pSrc1 -= SAMPLE_LENGTH; pSrc2 -= SAMPLE_LENGTH; pSrc3 -= SAMPLE_LENGTH; SDA_Scale (pSrc3, /* Pointer to source array */ pSrc3, /* Pointer to destination array */ SIGLIB_ONE, /* Peak level */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Impulse Response", /* Title of the dataset */ pSrc3, /* 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 ("\nImpulse Response\nPlease hit to continue . . ."); getchar (); /* Perform real FFT */ SDA_Rfft (pSrc3, /* 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_RectangularToPolar (pSrc3, /* Pointer to source real array */ pImagData, /* Pointer to source imaginary array */ pMagnitude, /* Pointer to destination magnitude array */ pPhase, /* Pointer to destination phase array */ SAMPLE_LENGTH); /* Array length */ SDA_Multiply (pMagnitude, /* Pointer to source array */ ((SLData_t)65536.0), /* Multiplier */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ SDA_10Log10 (pMagnitude, /* Pointer to source array */ pMagnitude, /* Pointer to destination array */ SAMPLE_LENGTH); /* Array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Magnitude (dB)", /* Title of the dataset */ pMagnitude, /* 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 ("\nMagnitude Response\nPlease hit to continue . . ."); getchar (); Display2DGraph (h2DGraph, /* Graph handle */ "Phase", /* Title of the dataset */ pPhase, /* Array of Double dataset */ SAMPLE_LENGTH, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nPhase Response\n"); SUF_MemoryFree (pImagData); /* Free all memory */ SUF_MemoryFree (pMagnitude); SUF_MemoryFree (pPhase); SUF_MemoryFree (pSrc1); SUF_MemoryFree (pSrc2); SUF_MemoryFree (pSrc3); SUF_MemoryFree (pStateArray1); SUF_MemoryFree (pStateArray2); SUF_MemoryFree (pFFTCoeffs); }