private void ExportButton_Click(object sender, RoutedEventArgs e) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = $"{Properties.Resources.FILTER_IMPORT_EXPORT_FILE_EXTENSION} (*{Properties.Resources.FILTER_IMPORT_EXPORT_FILE_EXTENSION})|*{Properties.Resources.FILTER_IMPORT_EXPORT_FILE_EXTENSION}|{Properties.Resources.ALL_FILES} (*.*)|*.*"; if (saveFileDialog.ShowDialog() == true) { try { using (StreamWriter fileWriter = File.CreateText(saveFileDialog.FileName)) { fileWriter.WriteLine(Properties.Resources.FILTER_CSV_HEADER); List <double> summedFilterData = manager.ActiveWorkBook().CombinedFilterImpulseResponse(true); ComplexFastFourierTransform cmplxFFT = new ComplexFastFourierTransform(); FrequencyDomain frequencyDomain = cmplxFFT.Transform(summedFilterData, manager.ActiveWorkBook().WindowedSyncFilters.Values.First().FilterLength); var magPhaseList = ComplexFastFourierTransform.ToMagnitudePhaseList(frequencyDomain); foreach (Tuple <double, double> coefficientMagPhase in magPhaseList) { fileWriter.WriteLine($"{coefficientMagPhase.Item1},{coefficientMagPhase.Item2}"); } } } catch (Exception ex) { Log.Warning(ex, ex.Message); // TODO warn user } } }
public void TestComplexTransform() { //IDFT complexFourierTransform = new ComplexFastFourierTransform(); IDFT complexFourierTransform = new DSPGuideComplexDiscreteFourierTransform(); FrequencyDomain result; List <double> recreatedSignal; int sampleRate = 1000; // hz List <double> timePoints = new List <double>(2 * sampleRate); for (double timePointVal = 0; timePointVal < 2.0; timePointVal += (1.0 / sampleRate)) { timePoints.Add(timePointVal); } List <double> signal = new List <double>(timePoints.Count); foreach (double timePointVal in timePoints) { double signalValue = (2.5 * Math.Sin(2 * Math.PI * 4 * timePointVal)) + (1.5 * Math.Sin(2 * Math.PI * 6.5 * timePointVal)); signal.Add(signalValue); } result = complexFourierTransform.Transform(signal, sampleRate); List <Tuple <double, double> > magPhaseList = ComplexFastFourierTransform.ToMagnitudePhaseList(result); FrequencyDomain fromMagPhaseList = ComplexFastFourierTransform.FromMagnitudePhaseList(magPhaseList); for (int idx = 0; idx < result.FourierCoefficients.Count; idx++) { double absDifference = Complex.Abs(result.FourierCoefficients[idx] - fromMagPhaseList.FourierCoefficients[idx]); // Check that they are close, rounding error occurs, they wont be equal Assert.IsTrue(absDifference < 1.0E-10); } // This file can be viewed in Excel for plotting of hz and amplitudes StreamWriter amplitudeFile = new StreamWriter("frequencyAmplitudes.csv"); if (amplitudeFile != null) { amplitudeFile.WriteLine("HZ, Amplitude"); foreach (var frequencyAmplitude in result.FrequencyAmplitudes) { amplitudeFile.WriteLine($"{frequencyAmplitude.Key}, {frequencyAmplitude.Value}"); } } amplitudeFile.Close(); recreatedSignal = complexFourierTransform.Synthesize(result); Assert.IsNotNull(result); Assert.IsNotNull(recreatedSignal); //double amplitude40 = result.FrequencyAmplitudes[4.0]; //double amplitude65 = result.FrequencyAmplitudes[6.5]; //Assert.IsTrue(Math.Abs(amplitude40 - 2.5) <= MaxAmplitudeDifference); //Assert.IsTrue(Math.Abs(amplitude65 - 1.5) <= MaxAmplitudeDifference); double maxDifference = 0.0; for (int idx = 0; idx < recreatedSignal.Count; idx++) { double calculateDifference = Math.Abs(recreatedSignal[idx] - signal[idx]); if (maxDifference < calculateDifference) { maxDifference = calculateDifference; } } for (int idx = 0; idx < recreatedSignal.Count; idx++) { double calculateDifference = Math.Abs(recreatedSignal[idx] - signal[idx]); Assert.IsTrue(calculateDifference <= MaxSignalDifference); } }