/* SigLib Cepstrum Analysis Example The real cepstrum is calculated as follows : FFT (log_magnitude (FFT (data))) The complex cepstrum is calculated as follows : FFT (complex_log (FFT (data))) where the complex log of [X(z)] = log | X(z) | + j (angle (X(z))) For speech, use samples about 10 mS long The peaks in the spectrum correspond to the vowel formants. The combs correspond to to the pitch information. The signals on the left are the formant envelope. */ /* Include files */ #include #include #include #include "GraphFunctions.h" #include "plot_fd.h" /* Plot frequency spectrum functions */ /* Define constants */ #define FFT_SIZE ((SLArrayIndex_t)512) #define LOG_FFT_SIZE ((SLArrayIndex_t)9) #define WINDOW_SIZE FFT_SIZE /* Declare global variables */ SLFixData_t waveform; SLData_t *pRealData, *pImagData, *pWindowCoeffs, *pMagnitude, *pPhase, *pMarker, *pFFTCoeffs; FILE *fp; void main(void) { GraphObject *h2DGraph; /* Declare graph object */ /* Allocate arrays */ pPhase = SUF_VectorArrayAllocate (FFT_SIZE); pRealData = SUF_VectorArrayAllocate (FFT_SIZE); pImagData = SUF_VectorArrayAllocate (FFT_SIZE); pMagnitude = SUF_VectorArrayAllocate (FFT_SIZE); pWindowCoeffs = SUF_VectorArrayAllocate (WINDOW_SIZE); pMarker = SUF_VectorArrayAllocate (FFT_SIZE); pFFTCoeffs = SUF_FftCoefficientAllocate (FFT_SIZE); SDA_SignalGenerate (pMarker, /* Pointer to destination array */ SIGLIB_IMPULSE, /* Signal type - Impulse function */ 30000.0, /* Signal peak level */ SIGLIB_FILL, /* Fill (overwrite) or add to existing array contents */ SIGLIB_ZERO, /* Signal frequency - Unused */ SIGLIB_ZERO, /* D.C. Offset */ ((SLData_t)30.0), /* Time offset */ SIGLIB_ZERO, /* Signal end value - Unused */ SIGLIB_NULL_DATA_PTR, /* Unused */ SIGLIB_NULL_DATA_PTR, /* Unused */ FFT_SIZE); /* Output array length */ system ("cls"); printf ("\n\n\n"); printf ("Choose a waveform file\n\n"); printf ("(Sample rate = 10 KHz)\n\n"); printf ("AA.SIG ... (1)\n"); printf ("EE.SIG ... (2)\n"); printf ("ER.SIG ... (3)\n"); printf ("I.SIG ... (4)\n"); printf ("OO.SIG ... (5)\n\n"); printf (">"); scanf ("%d", &waveform); getchar (); /* Clear down CR */ switch (waveform) { case 1 : printf ("Opening AA.SIG\n\n"); if ((fp = fopen ("aa.sig", "rb")) == NULL) { printf ("Error opening data file\n"); exit (0); } break; case 2 : printf ("Opening EE.SIG\n\n"); if ((fp = fopen ("ee.sig", "rb")) == NULL) { printf ("Error opening data file\n"); exit (0); } break; case 3 : printf ("Opening ER.SIG\n\n"); if ((fp = fopen ("er.sig", "rb")) == NULL) { printf ("Error opening data file\n"); exit (0); } break; case 4 : printf ("Opening I.SIG\n\n"); if ((fp = fopen ("i.sig", "rb")) == NULL) { printf ("Error opening data file\n"); exit (0); } break; case 5 : default : printf ("Opening OO.SIG\n\n"); if ((fp = fopen ("oo.sig", "rb")) == NULL) { printf ("Error opening data file\n"); exit (0); } } buffer_from_disk (pRealData, fp, FFT_SIZE); /* Read data from disk */ h2DGraph = /* Initialize graph */ Create2DGraph ("Cepstrum Analysis", /* 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); } Display2DGraph (h2DGraph, /* Graph handle */ "Source Signal", /* Title of the dataset */ pRealData, /* 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 ("\nSource Signal\nPlease hit to continue . . ."); getchar (); /* 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 */ /* Generate Hanning window table */ SIF_Window (pWindowCoeffs, /* Pointer to window oefficient */ SIGLIB_HANNING, /* Window type */ SIGLIB_ZERO, /* Window coefficient */ FFT_SIZE); /* Window length */ plot_frequency_domain (pRealData, SIGLIB_HANNING, "Spectrum",FFT_SIZE, FFT_SIZE); SDA_Window (pRealData, /* Pointer to source array */ pRealData, /* Pointer to destination array */ pWindowCoeffs, /* Pointer to window oefficients */ WINDOW_SIZE); /* Window length */ /* Perform real to real cepstrum */ SDA_RealRealCepstrum (pRealData, /* Real input array pointer */ pMagnitude, /* Real destination array pointer */ pPhase, /* Imaginary destination array pointer */ pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table */ FFT_SIZE, /* FFT size */ LOG_FFT_SIZE); /* Log2 FFT size */ Display2DGraph (h2DGraph, /* Graph handle */ "Real-Real Cepstrum", /* Title of the dataset */ pMagnitude, /* 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 */ Display2DGraph (h2DGraph, /* Graph handle */ "Marker", /* Title of the dataset */ pMarker, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nReal-Real Cepstrum\nPlease hit to continue . . ."); getchar (); /* Perform real to complex cepstrum */ SDA_RealComplexCepstrum (pRealData, /* Real input array pointer */ pMagnitude, /* Real destination array pointer */ pPhase, /* Imaginary destination array pointer */ pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table */ FFT_SIZE, /* FFT size */ LOG_FFT_SIZE); /* Log2 FFT size */ Display2DGraph (h2DGraph, /* Graph handle */ "Real-Complex Cepstrum", /* Title of the dataset */ pMagnitude, /* 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 */ Display2DGraph (h2DGraph, /* Graph handle */ "Marker", /* Title of the dataset */ pMarker, /* Array of Double dataset */ FFT_SIZE, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_RED, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nReal-Complex Cepstrum\n"); SUF_MemoryFree (pPhase); /* Free memory */ SUF_MemoryFree (pRealData); SUF_MemoryFree (pImagData); SUF_MemoryFree (pMagnitude); SUF_MemoryFree (pWindowCoeffs); SUF_MemoryFree (pMarker); SUF_MemoryFree (pFFTCoeffs); }