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); }
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); }
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)); } }