//called when data for any output pin is requested public void Evaluate(int SpreadMax) { if(!Buffer.IsChanged) return; int BinSize = Buffer.SliceCount; double[] freqReal, freqImag; double[] dataReal = new double[Buffer.SliceCount]; for (int i=0; i<BinSize; i++ ) { dataReal[i] = Buffer[i]; } RealFourierTransformation rft = new RealFourierTransformation(); // default convention rft.TransformForward(dataReal, out freqReal, out freqImag); FOutput.SliceCount = freqReal.Length; FOutput.AssignFrom(freqReal); FOutput2.SliceCount = freqImag.Length; FOutput2.AssignFrom(freqImag); FOut.SliceCount = FMag.SliceCount = BinSize/2; for (int i=1; i <= BinSize/2; i++) { FMag[i-1] = Math.Sqrt(freqReal[i] * freqReal[i] + freqImag[i] * freqImag[i]); FOut[i-1] = i * Samplerate[0] / (double) BinSize; } }
public void TestWhiteGaussianNoiseIsWhite() { for(int z = 0; z < 10; z++) // run test 10 times to be sure { IChannelSource source = new WhiteGaussianNoiseSource(); double[] signal = new double[signalLength]; double signalPower = 0d; for(int i = 0; i < signal.Length; i++) { signal[i] = source.ReadNextSample(); signalPower += signal[i] * signal[i]; } signalPower /= signalLength; Assert.Less(signalPower, 1.1, "signal power must be less than 1.1"); Assert.Greater(signalPower, 0.9, "signal power must be greater than 0.9"); double[] freqReal, freqImag; RealFourierTransformation fft = new RealFourierTransformation(); fft.TransformForward(signal, out freqReal, out freqImag); double spectralPower = 0d; double[] spectralGroupPower = new double[groupCount]; for(int i = 0, j = 0; i < spectralGroupPower.Length; i++, j += groupLength) { double sum = 0d; for(int k = 0; k < groupLength; k++) { double real = freqReal[j + k]; double imag = freqImag[j + k]; sum += real * real + imag * imag; } spectralGroupPower[i] = sum / (2 * groupLength); spectralPower += sum; Assert.Less(spectralGroupPower[i], 1.4, "spectral power must be less than 1.4 for each group"); Assert.Greater(spectralGroupPower[i], 0.6, "spectral power must be greater than 0.6 for each group"); } spectralPower /= (2 * signalLength); Assert.AreEqual(signalPower, spectralPower, 0.0001, "Signal and spectral power must match."); } }
/// <summary> /// A static transformation method. The length is the nearest power of two that is not greater than the input length. /// Returns the full result. /// </summary> public static IArrayView<double> TransformRaw(IArrayView<double> input, FFTOutputType outputType = FFTOutputType.Power, WindowType windowType = WindowType.Rectangular) { int count = input.Count.NearestPowerOfTwo(false); var fft = new RealFourierTransformation(); double[] window = windowType.Apply(input.Take(count), count).ToArray(), real, imag; fft.TransformForward(window, out real, out imag); if (outputType == FFTOutputType.Imaginary) return imag.AsIArray(); if (outputType == FFTOutputType.Power) for (int i = 0; i < real.Length; i++) real[i] = Math.Sqrt(real[i] * real[i] + imag[i] * imag[i]); return real.AsIArray(); }