private static bool VerifyPartisipant(double[] segment, int expectedFrequency, int expectedDuration, int sampleRate) { bool partisipantIsCorrect = false; int numberOfSamplesForFft = 2048; double[] realSamplesForFft = segment.Skip(numberOfSamplesForFft).Take(numberOfSamplesForFft).ToArray(); double[] allSamplesForFft = new double[realSamplesForFft.Count() * 2]; for (int i = 0; i < allSamplesForFft.Count(); i += 2) { allSamplesForFft[i] = i % 2 == 0 ? realSamplesForFft[i / 2] : 0; //real part remain, imagine - inserts zeros } try { double[] freqReal, freqImag; RealFourierTransformation rft = new RealFourierTransformation(); rft.TransformForward(allSamplesForFft, out freqReal, out freqImag); int maxFftArrayIndex = 22000 * numberOfSamplesForFft / sampleRate / 2; //2200 - max fequency, which can be heared (theoretically); /2 - array is mirroved; freqReal = freqReal.ToList().GetRange(0, maxFftArrayIndex).ConvertAll(element => element = Math.Abs(element)).ToArray(); int fftArrayIndex = Array.IndexOf(freqReal, freqReal.Max()); double dominantFrequency = Convert.ToInt32(fftArrayIndex * sampleRate / numberOfSamplesForFft); double numberOfSamples = segment.Count(); double segmentDuration = numberOfSamples / (double)sampleRate; bool correctSegmentDuration = expectedDuration * 0.95 < segmentDuration && segmentDuration < expectedDuration * 1.05; partisipantIsCorrect = expectedFrequency * 0.95 < dominantFrequency && dominantFrequency < expectedFrequency * 1.05; } catch (Exception e) { //fail report } return(partisipantIsCorrect); }
/// <summary> /// Currently only first channel /// </summary> /// <param name="data"></param> public void DoWork(ref double[] data) { throw new NotImplementedException(); //1. wait until window buffer is full if (windowLength < windowsize) { window[windowLength] = data[0]; windowLength++; } else //window buffer full { //2. perform fft double[] freqReal, freqImag; RealFourierTransformation rft = new RealFourierTransformation(); // default convention rft.TransformForward(window, out freqReal, out freqImag); //3. move left for (int i = window.Length - 2; i >= 0; i--) { window[i + 1] = window[i]; } //4. set new value to be used next time window[0] = data[0]; //5. Fill first value for return data[0] = freqReal[0]; } }
public SpectralAnalyzer(int windowSize, int discretization, WindowType winType) { trans = new RealFourierTransformation(); frqs = trans.GenerateFrequencyScale(discretization, windowSize); if (winType == WindowType.Hann) { window = Hanning(windowSize); } else { window = Square(windowSize); } }
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> /// Currently only first channel /// </summary> /// <param name="data"></param> public double[] DoWork(double[] data) { //1. wait until window buffer is full if (windowLength < windowsize) { for (int i = 0; i < totalChannels; i++) { windowChannels[i][windowLength] = data[i]; } windowLength++; return(data); } else //window buffer full { result = new double[totalChannels]; //2. perform fft for (int i = 0; i < totalChannels; i++) { double[] freqReal, freqImag; RealFourierTransformation rft = new RealFourierTransformation(); // default convention rft.TransformForward(windowChannels[i], out freqReal, out freqImag); //3. move left for (int j = windowChannels[i].Length - 2; j >= 0; j--) { windowChannels[i][j + 1] = windowChannels[i][j]; } //4. set new value to be used next time windowChannels[i][0] = data[i]; //5. Fill first value for return result[i] = freqReal[0]; } return(result); } }
/// <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()); }
public void SetUp() { cft = new ComplexFourierTransformation(); rft = new RealFourierTransformation(); }
public void SetUp() { _fft = new RealFourierTransformation(); _fft.Convention = TransformationConvention.Default; }
/// <summary> /// Construct an FFT with default parameter values /// </summary> public FFT() { this.fft = new RealFourierTransformation(TransformationConvention.Matlab); this.SetParametersToDefaultValues(); }