Exemple #1
0
        static void Ex01()
        {
            var hp = new WWComplex[8];

            hp[0].real = 1.0;
            hp[1].real = -1.0;

            var fft = new WWRadix2Fft(8);

            var H = fft.ForwardFft(hp);

            Print("hp", hp);
            Print("H ", H);

            var xp = new WWComplex[8];

            xp[0].real = 1.0;
            xp[1].real = 2.0;
            xp[2].real = 3.0;
            xp[3].real = 1.0;

            var X = fft.ForwardFft(xp);

            Print("xp", xp);
            Print("X ", X);

            var Y = WWComplex.Mul(H, X);

            Print("Y ", Y);

            var y = fft.InverseFft(Y);

            Print("y ", y);
        }
Exemple #2
0
        private void UpdateMagnitudePhase()
        {
            var timeDomain = new WWComplex[SampleCount()];

            for (int i = 0; i < timeDomain.Length; ++i)
            {
                timeDomain[i] = new WWComplex(mSLArray[i].Value, 0);
            }

            var freqDomain = new WWComplex[SampleCount()];

            for (int i = 0; i < freqDomain.Length; ++i)
            {
                freqDomain[i] = new WWComplex();
            }

            var fft = new WWRadix2Fft(SampleCount());

            fft.ForwardFft(timeDomain, freqDomain);

            UpdateMagnitude(freqDomain);
            UpdatePhase(freqDomain);
        }
        private void UpdateUpsampleGraph()
        {
            LineSetX1Y1X2Y2(lineUSX,
                    0, canvasUpsampleGraph.ActualHeight / 2,
                    canvasUpsampleGraph.ActualWidth, canvasUpsampleGraph.ActualHeight / 2);

            LineSetX1Y1X2Y2(lineUSY,
                    GRAPH_YAXIS_POS_X, 0,
                    GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight);

            LineSetX1Y1X2Y2(lineUSTickP1,
                    GRAPH_YAXIS_POS_X - 4, canvasUpsampleGraph.ActualHeight / 4,
                    GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight / 4);
            LineSetX1Y1X2Y2(lineUSTickM1,
                    GRAPH_YAXIS_POS_X - 4, canvasUpsampleGraph.ActualHeight * 3 / 4,
                    GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight * 3 / 4);

            CanvasSetLeftTop(labelUSP1, 0, canvasUpsampleGraph.ActualHeight / 4 - labelUSP1.ActualHeight / 2);
            CanvasSetLeftTop(labelUS0, 0, canvasUpsampleGraph.ActualHeight / 2 - labelUS0.ActualHeight / 2);
            CanvasSetLeftTop(labelUSM1, 0, canvasUpsampleGraph.ActualHeight * 3 / 4 - labelUSM1.ActualHeight / 2);

            foreach (var t in mUpsampleGraph.points) {
                canvasUpsampleGraph.Children.Remove(t.Item1);
                canvasUpsampleGraph.Children.Remove(t.Item2);
                canvasUpsampleGraph.Children.Remove(t.Item3);
            }
            mUpsampleGraph.points.Clear();

            // オリジナルPCMデータtimeDomainOrigをFFTして周波数ドメインデータfreqDomainOrigを得る
            var timeDomainOrig = new WWComplex[SampleCount()];
            for (int i=0; i < timeDomainOrig.Length; ++i) {
                timeDomainOrig[i] = new WWComplex(mSLArray[i].Value, 0);
            }

            var freqDomainOrig = new WWComplex[SampleCount()];

            {
                var fft = new WWRadix2Fft(SampleCount());
                fft.ForwardFft(timeDomainOrig, freqDomainOrig);
            }

            timeDomainOrig = null;

            // 周波数ドメインデータfreqDomainOrigを0で水増ししたデータfreqDomainUpsampledを作って逆FFTする

            int upsampledSampleCount = SampleCount() * UpsampleMultiple();

            var freqDomainUpsampled = new WWComplex[upsampledSampleCount];
            for (int i=0; i < freqDomainUpsampled.Length; ++i) {
                if (i <= freqDomainOrig.Length / 2) {
                    freqDomainUpsampled[i].CopyFrom(freqDomainOrig[i]);
                    if (i == freqDomainOrig.Length / 2) {
                        freqDomainUpsampled[i].Mul(0.5);
                    }
                } else if (freqDomainUpsampled.Length - freqDomainOrig.Length / 2 <= i) {
                    int pos = i + freqDomainOrig.Length - freqDomainUpsampled.Length;
                    freqDomainUpsampled[i].CopyFrom(freqDomainOrig[pos]);
                    if (freqDomainUpsampled.Length - freqDomainOrig.Length / 2 == i) {
                        freqDomainUpsampled[i].Mul(0.5);
                    }
                } else {
                    // do nothing
                }
            }
            freqDomainOrig = null;

            var timeDomainUpsampled = new WWComplex[upsampledSampleCount];
            {
                var fft = new WWRadix2Fft(upsampledSampleCount);
                fft.InverseFft(freqDomainUpsampled, timeDomainUpsampled, 1.0 / SampleCount());
            }

            freqDomainUpsampled = null;

            // アップサンプルされたPCMデータtimeDomainUpsampledをグラフにプロットする
            double pointIntervalX = (canvasUpsampleGraph.ActualWidth - GRAPH_YAXIS_POS_X) / (upsampledSampleCount + 2 * UpsampleMultiple());

            for (int i=0; i < upsampledSampleCount; ++i) {
                double x = GRAPH_YAXIS_POS_X + pointIntervalX * (i + UpsampleMultiple());
                double y = canvasUpsampleGraph.ActualHeight / 2 - (canvasUpsampleGraph.ActualHeight / 4) * timeDomainUpsampled[i].real;

                var el = new Ellipse();
                el.Width = 6;
                el.Height = 6;
                el.Fill = Brushes.Black;
                canvasUpsampleGraph.Children.Add(el);
                CanvasSetLeftTop(el, x - 3, y - 3);

                var la = new Label();
                la.Content = string.Format("{0:0.00}", timeDomainUpsampled[i].real);
                canvasUpsampleGraph.Children.Add(la);
                if (timeDomainUpsampled[i].real >= 0) {
                    CanvasSetLeftTop(la, x - 16, y - labelUS0.ActualHeight);
                } else {
                    CanvasSetLeftTop(la, x - 16, y);
                }

                var li = new Line();
                li.Stroke = Brushes.Black;
                canvasUpsampleGraph.Children.Add(li);
                LineSetX1Y1X2Y2(li,
                    x, y,
                    x, canvasUpsampleGraph.ActualHeight / 2);

                mUpsampleGraph.points.Add(new Tuple<Ellipse, Label, Line>(el, la, li));
            }
        }
        private void UpdateMagnitudePhase()
        {
            var timeDomain = new WWComplex[SampleCount()];
            for (int i=0; i < timeDomain.Length; ++i) {
                timeDomain[i] = new WWComplex(mSLArray[i].Value, 0);
            }

            var freqDomain = new WWComplex[SampleCount()];
            for (int i=0; i < freqDomain.Length; ++i) {
                freqDomain[i] = new WWComplex();
            }

            var fft = new WWRadix2Fft(SampleCount());
            fft.ForwardFft(timeDomain, freqDomain);

            UpdateMagnitude(freqDomain);
            UpdatePhase(freqDomain);
        }
Exemple #5
0
        private void UpdateUpsampleGraph()
        {
            LineSetX1Y1X2Y2(lineUSX,
                            0, canvasUpsampleGraph.ActualHeight / 2,
                            canvasUpsampleGraph.ActualWidth, canvasUpsampleGraph.ActualHeight / 2);

            LineSetX1Y1X2Y2(lineUSY,
                            GRAPH_YAXIS_POS_X, 0,
                            GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight);

            LineSetX1Y1X2Y2(lineUSTickP1,
                            GRAPH_YAXIS_POS_X - 4, canvasUpsampleGraph.ActualHeight / 4,
                            GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight / 4);
            LineSetX1Y1X2Y2(lineUSTickM1,
                            GRAPH_YAXIS_POS_X - 4, canvasUpsampleGraph.ActualHeight * 3 / 4,
                            GRAPH_YAXIS_POS_X, canvasUpsampleGraph.ActualHeight * 3 / 4);

            CanvasSetLeftTop(labelUSP1, 0, canvasUpsampleGraph.ActualHeight / 4 - labelUSP1.ActualHeight / 2);
            CanvasSetLeftTop(labelUS0, 0, canvasUpsampleGraph.ActualHeight / 2 - labelUS0.ActualHeight / 2);
            CanvasSetLeftTop(labelUSM1, 0, canvasUpsampleGraph.ActualHeight * 3 / 4 - labelUSM1.ActualHeight / 2);

            foreach (var t in mUpsampleGraph.points)
            {
                canvasUpsampleGraph.Children.Remove(t.Item1);
                canvasUpsampleGraph.Children.Remove(t.Item2);
                canvasUpsampleGraph.Children.Remove(t.Item3);
            }
            mUpsampleGraph.points.Clear();

            // オリジナルPCMデータtimeDomainOrigをFFTして周波数ドメインデータfreqDomainOrigを得る
            var timeDomainOrig = new WWComplex[SampleCount()];

            for (int i = 0; i < timeDomainOrig.Length; ++i)
            {
                timeDomainOrig[i] = new WWComplex(mSLArray[i].Value, 0);
            }

            var freqDomainOrig = new WWComplex[SampleCount()];

            {
                var fft = new WWRadix2Fft(SampleCount());
                fft.ForwardFft(timeDomainOrig, freqDomainOrig);
            }

            timeDomainOrig = null;

            // 周波数ドメインデータfreqDomainOrigを0で水増ししたデータfreqDomainUpsampledを作って逆FFTする

            int upsampledSampleCount = SampleCount() * UpsampleMultiple();

            var freqDomainUpsampled = new WWComplex[upsampledSampleCount];

            for (int i = 0; i < freqDomainUpsampled.Length; ++i)
            {
                if (i <= freqDomainOrig.Length / 2)
                {
                    freqDomainUpsampled[i].CopyFrom(freqDomainOrig[i]);
                    if (i == freqDomainOrig.Length / 2)
                    {
                        freqDomainUpsampled[i].Mul(0.5);
                    }
                }
                else if (freqDomainUpsampled.Length - freqDomainOrig.Length / 2 <= i)
                {
                    int pos = i + freqDomainOrig.Length - freqDomainUpsampled.Length;
                    freqDomainUpsampled[i].CopyFrom(freqDomainOrig[pos]);
                    if (freqDomainUpsampled.Length - freqDomainOrig.Length / 2 == i)
                    {
                        freqDomainUpsampled[i].Mul(0.5);
                    }
                }
                else
                {
                    // do nothing
                }
            }
            freqDomainOrig = null;

            var timeDomainUpsampled = new WWComplex[upsampledSampleCount];

            {
                var fft = new WWRadix2Fft(upsampledSampleCount);
                fft.InverseFft(freqDomainUpsampled, timeDomainUpsampled, 1.0 / SampleCount());
            }

            freqDomainUpsampled = null;


            // アップサンプルされたPCMデータtimeDomainUpsampledをグラフにプロットする
            double pointIntervalX = (canvasUpsampleGraph.ActualWidth - GRAPH_YAXIS_POS_X) / (upsampledSampleCount + 2 * UpsampleMultiple());

            for (int i = 0; i < upsampledSampleCount; ++i)
            {
                double x = GRAPH_YAXIS_POS_X + pointIntervalX * (i + UpsampleMultiple());
                double y = canvasUpsampleGraph.ActualHeight / 2 - (canvasUpsampleGraph.ActualHeight / 4) * timeDomainUpsampled[i].real;

                var el = new Ellipse();
                el.Width  = 6;
                el.Height = 6;
                el.Fill   = Brushes.Black;
                canvasUpsampleGraph.Children.Add(el);
                CanvasSetLeftTop(el, x - 3, y - 3);

                var la = new Label();
                la.Content = string.Format("{0:0.00}", timeDomainUpsampled[i].real);
                canvasUpsampleGraph.Children.Add(la);
                if (timeDomainUpsampled[i].real >= 0)
                {
                    CanvasSetLeftTop(la, x - 16, y - labelUS0.ActualHeight);
                }
                else
                {
                    CanvasSetLeftTop(la, x - 16, y);
                }

                var li = new Line();
                li.Stroke = Brushes.Black;
                canvasUpsampleGraph.Children.Add(li);
                LineSetX1Y1X2Y2(li,
                                x, y,
                                x, canvasUpsampleGraph.ActualHeight / 2);

                mUpsampleGraph.points.Add(new Tuple <Ellipse, Label, Line>(el, la, li));
            }
        }