/* SigLib Frequency Domain Pitch Shifting by interpolation, The process used is equivalent to time-domain sin(x) / x interpolation. The shifted signal is a sine wave. This algorithm benefits from using overlapping windows, in general, the greater the overlap, the better the performance. ie. the lower the distortion. */ #include #include #include "GraphFunctions.h" #define LENGTH1 ((SLArrayIndex_t)64) #define LENGTH2 256L #define SMALL_FFT_SIZE LENGTH1 #define LOG_SMALL_FFT_SIZE 6L #define LARGE_FFT_SIZE LENGTH2 #define LOG_LARGE_FFT_SIZE ((SLArrayIndex_t)8) SLData_t pRealInput[LENGTH2], pImagInput[LENGTH2]; SLData_t pRealOutput[LENGTH2], pImagOutput[LENGTH2]; SLData_t *pFFTCoeffs; SLData_t SinePhase; void main(void) { GraphObject *h2DGraph; /* Declare graph object */ /* Allocate enough space for largest FFT */ pFFTCoeffs = SUF_FftCoefficientAllocate (LARGE_FFT_SIZE); h2DGraph = /* Initialize graph */ Create2DGraph ("Frequency Domain Interpolation", /* 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); } /* Initialise FFT */ SIF_Fft (pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table - NOT USED */ SMALL_FFT_SIZE); /* FFT Size */ SinePhase = SIGLIB_ZERO; SDA_SignalGenerate (pRealInput, /* 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.038), /* 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 */ LENGTH1); /* Output array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Source signal (time domain)", /* Title of the dataset */ pRealInput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ printf ("\nSource signal (time domain)\nPlease hit to continue . . ."); getchar (); /* Perform real FFT */ SDA_Rfft (pRealInput, /* Pointer to real array */ pImagInput, /* Pointer to imaginary array */ pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table - NOT USED */ SMALL_FFT_SIZE, /* FFT size */ LOG_SMALL_FFT_SIZE); /* log2 FFT size */ Display2DGraph (h2DGraph, /* Graph handle */ "Source signal (frequency domain - real)", /* Title of the dataset */ pRealInput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Source signal (frequency domain - imag)", /* Title of the dataset */ pImagInput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nSource signal (frequency domain)\nPlease hit to continue . . ."); getchar (); /* Perform frequency domain interpolation */ /* Interp. factor defined by array length ratios */ SDA_FdInterpolate2 (pRealInput, /* Pointer to real source array */ pImagInput, /* Pointer to imaginary source array */ pRealOutput, /* Pointer to real destination array */ pImagOutput, /* Pointer to imaginary destination array */ LENGTH1, /* Source array length */ LENGTH2); /* Destination array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (frequency domain - real)", /* Title of the dataset */ pRealOutput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (frequency domain - imag)", /* Title of the dataset */ pImagOutput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nInterpolated signal (frequency domain)\nPlease hit to continue . . ."); getchar (); /* Prepare for inverse FFT */ SIF_Fft (pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table - NOT USED */ LARGE_FFT_SIZE); /* FFT Size */ SDA_Cifft (pRealOutput, pImagOutput, pFFTCoeffs, SIGLIB_NULL_ARRAY_INDEX_PTR, LARGE_FFT_SIZE, LOG_LARGE_FFT_SIZE); /* Perform FFT */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (time domain - real)", /* Title of the dataset */ pRealOutput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (time domain - imag)", /* Title of the dataset */ pImagOutput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nInterpolated signal (time domain)\nPlease hit to continue . . ."); getchar (); /* Copy the array and reverse the process */ SDA_Copy (pRealOutput, /* Pointer to source array */ pRealInput, /* Pointer to destination array */ LENGTH2); /* Array length */ /* Perform real FFT */ SDA_Rfft (pRealInput, /* Pointer to real array */ pImagInput, /* Pointer to imaginary array */ pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table - NOT USED */ LARGE_FFT_SIZE, /* FFT size */ LOG_LARGE_FFT_SIZE); /* log2 FFT size */ Display2DGraph (h2DGraph, /* Graph handle */ "Source signal (frequency domain - real)", /* Title of the dataset */ pRealInput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Source signal (frequency domain - imag)", /* Title of the dataset */ pImagInput, /* Array of Double dataset */ LENGTH2, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nSource signal (frequency domain)\nPlease hit to continue . . ."); getchar (); /* Perform frequency domain interpolation */ /* Interp. factor defined by array length ratios */ SDA_FdInterpolate2 (pRealInput, /* Pointer to real source array */ pImagInput, /* Pointer to imaginary source array */ pRealOutput, /* Pointer to real destination array */ pImagOutput, /* Pointer to imaginary destination array */ LENGTH2, /* Source array length */ LENGTH1); /* Destination array length */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (frequency domain - real)", /* Title of the dataset */ pRealOutput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (frequency domain - imag)", /* Title of the dataset */ pImagOutput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nInterpolated signal (frequency domain)\nPlease hit to continue . . ."); getchar (); /* Prepare for inverse FFT */ SIF_Fft (pFFTCoeffs, /* Pointer to FFT coefficients */ SIGLIB_NULL_ARRAY_INDEX_PTR, /* Pointer to bit reverse address table - NOT USED */ SMALL_FFT_SIZE); /* FFT Size */ SDA_Cifft (pRealOutput, pImagOutput, pFFTCoeffs, SIGLIB_NULL_ARRAY_INDEX_PTR, SMALL_FFT_SIZE, LOG_SMALL_FFT_SIZE); /* Perform FFT */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (time domain - real)", /* Title of the dataset */ pRealOutput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_MAGENTA, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_NEW); /* New graph */ Display2DGraph (h2DGraph, /* Graph handle */ "Interpolated signal (time domain - imag)", /* Title of the dataset */ pImagOutput, /* Array of Double dataset */ LENGTH1, /* Number of data points */ SV_GRAPH_LINE, /* Graph type */ SV_BLUE, /* Colour */ SV_HIDE_MARKERS, /* Marker enable / disable */ SV_GRAPH_ADD); /* New graph */ printf ("\nInterpolated signal (time domain)\n"); SUF_MemoryFree (pFFTCoeffs); /* Free memory */ }