/// <summary> /// 入力データが完全に復元できる特殊な窓関数を使用したオーバーラップ・アドFFT。 /// あらかじめSetNumSamples()を呼ぶと入出力サンプル数が一致する。 /// </summary> /// <param name="fftLength">Forward FFT長。</param> /// <param name="ifftLength">Inverse FFT長。0のときForward FFT長を使用。</param> public WWOverlappedFft(int fftLength, int ifftLength = 0) { mFFTfwd = new WWTimeDependentForwardFourierTransform(fftLength, WWTimeDependentForwardFourierTransform.WindowType.Hann); if (ifftLength == 0) { ifftLength = fftLength; } mFFTinv = new WWTimeDependentInverseFourierTransform(ifftLength); }
public void TimeDependentFourierTransformTestImpulse() { var t = new WWTimeDependentForwardFourierTransform(4, WWTimeDependentForwardFourierTransform.WindowType.Bartlett); var f = new WWTimeDependentInverseFourierTransform(4); var x = new double[20]; x[0] = 1; Test(t, f, x, 1); }
public void TimeDependentFourierTransformTestDClong() { var t = new WWTimeDependentForwardFourierTransform(4, WWTimeDependentForwardFourierTransform.WindowType.Bartlett); var f = new WWTimeDependentInverseFourierTransform(4); var x = new double[20]; for (int i = 0; i < x.Length; ++i) { x[i] = 1; } Test(t, f, x, x.Length); }
public void TimeDependentFourierTransformTestSine() { var t = new WWTimeDependentForwardFourierTransform(4, WWTimeDependentForwardFourierTransform.WindowType.Bartlett); var f = new WWTimeDependentInverseFourierTransform(4); var x = new double[20]; for (int i = 0; i < x.Length; ++i) { x[0] = Math.Sin(i * 2.0 * Math.PI / x.Length); } Test(t, f, x, 1); }
public void TimeDependentFourierTransformTestHannDC() { var t = new WWTimeDependentForwardFourierTransform(8, WWTimeDependentForwardFourierTransform.WindowType.Hann); var f = new WWTimeDependentInverseFourierTransform(8); var x = new double[19]; for (int i = 0; i < x.Length; ++i) { x[i] = 1; } f.SetNumSamples(x.Length); Test(t, f, x, 1); }
// //You can use the following additional attributes as you write your tests: // //Use ClassInitialize to run code before running the first test in the class //[ClassInitialize()] //public static void MyClassInitialize(TestContext testContext) //{ //} // //Use ClassCleanup to run code after all tests in a class have run //[ClassCleanup()] //public static void MyClassCleanup() //{ //} // //Use TestInitialize to run code before running each test //[TestInitialize()] //public void MyTestInitialize() //{ //} // //Use TestCleanup to run code after each test has run //[TestCleanup()] //public void MyTestCleanup() //{ //} // #endregion private void Test(WWTimeDependentForwardFourierTransform t, WWTimeDependentInverseFourierTransform f, double [] x, int fragmentSize) { int iPos = 0; int oPos = 0; // Processのテスト。 while (iPos < x.Length) { int size = fragmentSize; if (x.Length - iPos < size) { size = x.Length - iPos; } var xF = new double[size]; Array.Copy(x, iPos, xF, 0, size); iPos += size; var X = t.Process(xF); if (0 < X.Length) { var xR = f.Process(X); if (0 <= xR.Length) { for (int j = 0; j < xR.Length; ++j) { Assert.IsTrue(Math.Abs(xR[j] - x[oPos]) < 1e-8); ++oPos; } } } } { // Drainのテスト。 var X = t.Drain(); var xR = f.Process(X); for (int j = 0; j < xR.Length; ++j) { if (x.Length <= oPos) { break; } Assert.IsTrue(Math.Abs(xR[j] - x[oPos]) < 1e-8); ++oPos; } } }
public override PcmFormat Setup(PcmFormat inputFormat) { mPcmFormat = new PcmFormat(inputFormat); /* 周波数の精度 = メインローブの幅/2 * Bartlett窓やHann窓のとき 4π/M ラジアン、M == FFTsize * 人間の耳は、超低音域の音程は長3音(=1.26倍)ずれていても気にならないという。 */ mFftLength = Functions.NextPowerOf2(mPcmFormat.SampleRate); mFFTfwd = new WWTimeDependentForwardFourierTransform(mFftLength, WWTimeDependentForwardFourierTransform.WindowType.Hann); mFFTinv = new WWTimeDependentInverseFourierTransform(mFftLength); mTotalSamples = inputFormat.NumSamples; mProcessedSamples = 0; return(inputFormat); }