public void PlotSignals()
        {
            Signal workbookSourceSignal = workBookManager.ActiveWorkBook().SumOfSources();

            SignalWaveFile     = null;
            PlotPoints         = new List <DataPoint>(512);
            FrequencyViewModel = null;

            // Return empty set, this clears the display when all signals are off
            if (workbookSourceSignal == null)
            {
                NotifyPropertyChanged(nameof(PlotPoints));
                NotifyPropertyChanged(nameof(FrequencyViewModel));
                return;
            }

            CreateWavFile(workbookSourceSignal);

            for (int idx = 0; idx < workbookSourceSignal.Samples.Count; idx++)
            {
                PlotPoints.Add(new DataPoint(idx, workbookSourceSignal.Samples[idx]));
            }

            //IDFT cmplxFFT = new ComplexFastFourierTransform();
            IDFT cmplxFFT = new DSPGuideComplexDiscreteFourierTransform();

            FrequencyDomain frequencyDomain = cmplxFFT.Transform(workbookSourceSignal.Samples, workbookSourceSignal.SamplingHZ);


            FrequencyViewModel = new FrequencyHistogramViewModel(frequencyDomain);

            NotifyPropertyChanged(nameof(PlotPoints));
            NotifyPropertyChanged(nameof(FrequencyViewModel));
        }
        public void PlotData()
        {
            List <double> summedFilterData = manager.ActiveWorkBook().CombinedFilterImpulseResponse();

            if (null == summedFilterData)
            {
                return;
            }

            Signal workbookSourceSignal = manager.ActiveWorkBook().SumOfSources();

            if (workbookSourceSignal == null)
            {
                return;
            }

            SignalPlotPoints = new List <DataPoint>(workbookSourceSignal.Samples.Count);

            for (int idx = 0; idx < workbookSourceSignal.Samples.Count; idx++)
            {
                SignalPlotPoints.Add(new DataPoint(idx, workbookSourceSignal.Samples[idx]));
            }

            ConvolutionPlotPoints = new List <DataPoint>(summedFilterData.Count);

            for (int idx = 0; idx < summedFilterData.Count; idx++)
            {
                ConvolutionPlotPoints.Add(new DataPoint(idx, summedFilterData[idx]));
            }

            List <double> convolutionResult = convolver.Convolve(summedFilterData, workbookSourceSignal.Samples, ConvolutionType.INPUTSIDE);

            ResultPlotPoints = new List <DataPoint>(convolutionResult.Count);
            for (int idx = 0; idx < convolutionResult.Count; idx++)
            {
                ResultPlotPoints.Add(new DataPoint(idx, convolutionResult[idx]));
            }

            //IDFT cmplxFFT = new ComplexFastFourierTransform();
            IDFT cmplxFFT = new DSPGuideComplexDiscreteFourierTransform();

            FrequencyDomain frequencyDomain = cmplxFFT.Transform(convolutionResult, workbookSourceSignal.SamplingHZ);

            ResultFrequencyHistogram = new FrequencyHistogramViewModel(frequencyDomain);

            NotifyPropertyChanged(nameof(SignalPlotPoints));
            NotifyPropertyChanged(nameof(ConvolutionPlotPoints));
            NotifyPropertyChanged(nameof(ResultPlotPoints));
            NotifyPropertyChanged(nameof(ResultFrequencyHistogram));
        }
Exemple #3
0
        private void LoadFilterData()
        {
            List <double> summedFilterData = manager.ActiveWorkBook().CombinedFilterImpulseResponse(true);

            // Return an empty set
            if (summedFilterData == null || summedFilterData.Count == 0)
            {
                ImpulseResponsePoints   = new List <DataPoint>();
                StepResponsePoints      = new List <DataPoint>();
                FrequencyResponsePoints = new List <DataPoint>();
                DecibelResponsePoints   = new List <DataPoint>();
                Filters = new ObservableCollection <UserControl>();

                NotifyPropertyChanged(nameof(ImpulseResponsePoints));
                NotifyPropertyChanged(nameof(FrequencyResponsePoints));
                NotifyPropertyChanged(nameof(DecibelResponsePoints));
                NotifyPropertyChanged(nameof(StepResponsePoints));
                NotifyPropertyChanged(nameof(SumModeActive));
                NotifyPropertyChanged(nameof(ConvolveModeActive));
                NotifyPropertyChanged(nameof(Filters));

                return;
            }

            ImpulseResponsePoints = new List <DataPoint>(summedFilterData.Count);
            StepResponsePoints    = new List <DataPoint>(summedFilterData.Count);

            Filters = new ObservableCollection <UserControl>();

            for (int idx = 0; idx < summedFilterData.Count; idx++)
            {
                ImpulseResponsePoints.Add(new DataPoint(idx, summedFilterData[idx]));
            }
            //IDFT cmplxFFT = new ComplexFastFourierTransform();
            IDFT cmplxFFT = new DSPGuideComplexDiscreteFourierTransform();

            int filterLength = 0;

            if (manager.ActiveWorkBook().WindowedSyncFilters.Count > 0)
            {
                filterLength = manager.ActiveWorkBook().WindowedSyncFilters.Values.First().FilterLength;
            }
            else if (manager.ActiveWorkBook().CustomFilters.Count > 0)
            {
                filterLength = manager.ActiveWorkBook().CustomFilters.Values.First().FilterLength;
            }
            else
            {
                return; // Count not find any filters to set length with
            }

            FrequencyDomain frequencyDomain = cmplxFFT.Transform(summedFilterData, filterLength);

            Convolution   convolver    = new Convolution();
            List <double> stepResponse = convolver.Convolve(summedFilterData, GetStepData(summedFilterData.Count + 16), ConvolutionType.INPUTSIDE);

            FrequencyResponsePoints = new List <DataPoint>(frequencyDomain.FrequencyAmplitudes.Count);
            DecibelResponsePoints   = new List <DataPoint>(FrequencyResponsePoints.Count);

            // Load the frequency response graph data
            // Only scan the first half of the coefficients (up to the Nyquist frequency)
            int coefficientMax = (frequencyDomain.FourierCoefficients.Count / 2);

            for (int idx = 0; idx < coefficientMax; idx++)
            {
                double coeffLen = Complex.Abs(frequencyDomain.FourierCoefficients[idx]);
                double cuttoffFrequencyPercent = (((double)idx + 1.0) / summedFilterData.Count);
                FrequencyResponsePoints.Add(new DataPoint(cuttoffFrequencyPercent, coeffLen));
                DecibelResponsePoints.Add(new DataPoint(cuttoffFrequencyPercent, 20 * Math.Log10(coeffLen)));
            }

            int startingOffset = (summedFilterData.Count / 2);
            int endingOffset   = startingOffset + summedFilterData.Count;
            int graphX         = 0;

            // Load the step response graph data
            for (int idx = (startingOffset - 1); idx < endingOffset; idx++)
            {
                StepResponsePoints.Add(new DataPoint(graphX, stepResponse[idx]));
                graphX++;
            }

            foreach (var filter in manager.ActiveWorkBook().WindowedSyncFilters.Values)
            {
                filter.PropertyChanged -= handleFilterUpdate;
                WindowedSyncFilterItemView viewItem = new WindowedSyncFilterItemView();
                viewItem.DataContext = filter;
                Filters.Add(viewItem);
                filter.PropertyChanged += handleFilterUpdate; // Remove/re-add to avoid leaks in event handlers
            }

            foreach (var filter in manager.ActiveWorkBook().CustomFilters.Values)
            {
                filter.PropertyChanged -= handleFilterUpdate;
                CustomFilterViewItem viewItem = new CustomFilterViewItem();
                viewItem.DataContext = filter;
                Filters.Add(viewItem);
                filter.PropertyChanged += handleFilterUpdate; // Remove/re-add to avoid leaks in event handlers
            }

            NotifyPropertyChanged(nameof(ImpulseResponsePoints));
            NotifyPropertyChanged(nameof(FrequencyResponsePoints));
            NotifyPropertyChanged(nameof(DecibelResponsePoints));
            NotifyPropertyChanged(nameof(StepResponsePoints));
            NotifyPropertyChanged(nameof(Filters));
        }
Exemple #4
0
        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);
            }
        }