public static void Example7() //================[ Basic FFT + Windowing Example + ZeroPadding ]================ { // Same Input Signal as Example 1, except everything is a power of two double amplitude = 1.0; double frequency = 32768; UInt32 length = 1024; double samplingRate = 131072; double[] inputSignal = DSP.Generate.ToneSampling(amplitude, frequency, samplingRate, length); // Apply window to the Input Data & calculate Scale Factor double[] wCoefs = DSP.Window.Coefficients(DSP.Window.Type.Hamming, length); double[] wInputData = DSP.Math.Multiply(inputSignal, wCoefs); double wScaleFactor = DSP.Window.ScaleFactor.Signal(wCoefs); // Instantiate & Initialize a new DFT DSPLib.FFT fft = new DSPLib.FFT(); fft.Initialize(length, length * 3); // Zero Padding = 1024 * 3 // Call the FFT and get the scaled spectrum back Complex[] cSpectrum = fft.Execute(wInputData); // Convert the complex spectrum to note: Magnitude Squared Format // See text for the reasons to use Mag^2 format. double[] lmSpectrum = DSP.ConvertComplex.ToMagnitude(cSpectrum); // Properly scale the spectrum for the added window lmSpectrum = DSP.Math.Multiply(lmSpectrum, wScaleFactor); // For plotting on an XY Scatter plot generate the X Axis frequency Span double[] freqSpan = fft.FrequencySpan(samplingRate); // At this point a XY Scatter plot can be generated from, // X axis => freqSpan // Y axis => lmSpectrum }
/// <summary> /// FFT using DSPLib library. /// </summary> /// <param name="inputArray">The input array.</param> /// <param name="logScale">if set to <c>true</c> [log scale]</param> /// <returns></returns> Tuple <double[], double[]> FastFourierDSPLib(double[] inputArray, bool logScale) { double[] tempArray = new double[2048]; for (int i = 0; i < 2048; i++) { tempArray[i] = inputArray[i]; } UInt32 length = 2048; double samplingRate = 44100; double[] spectrum = new double[4096]; double[] wCoefs = DSP.Window.Coefficients(DSP.Window.Type.Hamming, length); double[] wInputData = DSP.Math.Multiply(tempArray, wCoefs); double wScaleFactor = DSP.Window.ScaleFactor.Signal(wCoefs); DSPLib.FFT fft = new DSPLib.FFT(); fft.Initialize(length, length * 3); Complex[] cSpectrum = fft.Execute(wInputData); spectrum = DSP.ConvertComplex.ToMagnitude(cSpectrum); if (logScale == true) { spectrum = DSP.ConvertMagnitude.ToMagnitudeDBV(spectrum); for (int i = 0; i < spectrum.Length; i++) { spectrum[i] -= 51; } } spectrum = DSP.Math.Multiply(spectrum, wScaleFactor); double[] freqSpan = fft.FrequencySpan(samplingRate); var tuple = new Tuple <double[], double[]>(spectrum, freqSpan); return(tuple); }
public static void Example10() //================[ Basic FFT Phase + Phase UnWrapping + Windowing + Zero Padding Test ]================ { // Generate a Phase Ramp between two signals double[] resultPhase = new double[600]; double[] unwrapPhase = new double[600]; UInt32 length = 2048; double[] wCoeff = DSP.Window.Coefficients(DSP.Window.Type.FTHP, length); // Instantiate & Initialize a new DFT DSPLib.FFT fft = new DSPLib.FFT(); fft.Initialize(length, 3 * length); for (Int32 phase = 0; phase < 600; phase++) { double[] inputSignalRef = DSP.Generate.ToneCycles(7.0, 128, length, phaseDeg: 45.0); double[] inputSignalPhase = DSP.Generate.ToneCycles(7.0, 128, length, phaseDeg: phase); inputSignalRef = DSP.Math.Multiply(inputSignalRef, wCoeff); inputSignalPhase = DSP.Math.Multiply(inputSignalPhase, wCoeff); // Call the DFT and get the scaled spectrum back of a reference and a phase shifted signal. Complex[] cSpectrumRef = fft.Execute(inputSignalRef); Complex[] cSpectrumPhase = fft.Execute(inputSignalPhase); // Magnitude Format - Just as a test point double[] lmSpectrumTest = DSP.ConvertComplex.ToMagnitude(cSpectrumRef); UInt32 peakLocation = DSP.Analyze.FindMaxPosition(lmSpectrumTest); // Extract the phase of 'peak value' bin double[] resultArrayRef = DSP.ConvertComplex.ToPhaseDegrees(cSpectrumRef); double[] resultArrayPhase = DSP.ConvertComplex.ToPhaseDegrees(cSpectrumPhase); resultPhase[phase] = resultArrayPhase[peakLocation] - resultArrayRef[peakLocation]; } unwrapPhase = DSP.Analyze.UnwrapPhaseDegrees(resultPhase); }