/// <summary> /// Create log-spectrogram (spaced according to manager's parameters) /// </summary> /// <param name = "proxy">Proxy used in generating the spectrogram</param> /// <param name = "filename">Filename to be processed</param> /// <param name = "milliseconds">Milliseconds to be analyzed</param> /// <param name = "startmilliseconds">Starting point</param> /// <returns>Logarithmically spaced bins within the power spectrum</returns> public float[][] CreateLogSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); //NormalizeInPlace(samples); int overlap = Overlap; int fftWindowsSize = WdftSize; double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) (_windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); frames[i] = ExtractLogBins(complexSignal); } return(frames); }
private static void SimpleFFT() { ComplexF[] values = new ComplexF[1024]; ComplexF[] expectedValues = new ComplexF[1024]; Random rnd = new Random(); for (int i = 0; i < 1024; i++) { values[i] = new ComplexF(20, 0); } Array.Copy(values, expectedValues, expectedValues.Length); Fourier.FFT(values, FourierDirection.Forward); for (int i = 0; i < values.Length; i++) { Console.WriteLine(values[i]); } Fourier.FFT(values, FourierDirection.Backward); for (int i = 0; i < values.Length; i++) { Console.WriteLine("{0} {1} {2}", values[i] / values.Length , expectedValues[i], values[i] / expectedValues[i]); } }
/// <summary> /// Compute a 1D fast Fourier transform of a dataset of complex numbers. /// </summary> /// <param name="data"></param> /// <param name="direction"></param> public static void FFT(ComplexF[] data, FourierDirection direction) { if (data == null) { throw new ArgumentNullException("data"); } Fourier.FFT(data, data.Length, direction); }
public override void FFT(bool forward) { data.CopyTo(copy, 0); Fourier.FFT(copy, copy.Length, forward ? FourierDirection.Forward : FourierDirection.Backward); }
public static FilterProfile Profile(ISoundObj impulse, SmoothingType type, double resolution) { uint nSR = impulse.SampleRate; uint nSR2 = nSR / 2; ushort nChannels = impulse.NumChannels; for (ushort c = 0; c < nChannels; c++) { // Read channel into a buffer SingleChannel channel = impulse.Channel(c); SoundBuffer buff = new SoundBuffer(channel); buff.ReadAll(); // And then double in length to prevent wraparound buff.PadTo(buff.Count * 2); // Pad to next higher power of two buff.PadToPowerOfTwo(); // Read out into array of complex Complex[][] data = buff.ToComplexArray(); Complex[] cdata = data[0]; // Then we're done with the buffer for this channel buff = null; GC.Collect(); // FFT in place Fourier.FFT(cdata.Length, cdata); int n = cdata.Length / 2; // Now we have an array of complex, from 0Hz to Nyquist and back again. // We really only care about the first half of the cdata buffer, but // treat it as circular anyway (i.e. wrap around for negative values). // // We're only working with magnitudes from here on, // so we can save some space by computing mags right away and storing them in the // real part of the complex array; then we can use the imaginary portion for the // smoothed data. for (int j = 0; j < cdata.Length; j++) { cdata[j].Re = cdata[j].Magnitude; cdata[j].Im = 0; } // Take a rectangular window of width (resolution)*(octave or ERB band) // Add up all magnitudes falling within this window // // Move the window forward by one thingummajig //double wMid = 0; // center of the window //double wLen = 0; } return(new FilterProfile()); // temp }
static private void Create_spectr() { lock (lockerDF) { data_furePic.Clear(); data_own_func.Clear(); float step = (float)1 / size / stept; for (int i = 0; i < data_fure.Count; i++) { Complex[] buf = new Complex[size]; for (int j = 0; j < size; j++) { buf[j] = data_fure[i][j]; } buf = Fourier.FFT(buf); for (int j = 0; j < size; j++) { data_fure[i][j] = buf[j]; } List <PointF> buf_vector = new List <PointF>(); for (int j = 0; j < size; j++) { PointF point = new PointF { X = j * step, Y = (float)data_fure[i][j].Abs }; buf_vector.Add(point); } data_furePic.Add(buf_vector); } for (int i = 0; i < size; i++) //-2 ибо не считаю спектры с концов, там всякий шум копится { List <PointF> buf_list = new List <PointF>(); for (int j = 0; j < data_furePic.Count; j++) { PointF buf = new PointF { X = (float)xx[j], Y = (float)data_fure[j][i].Re }; buf_list.Add(buf); } data_own_func.Add(buf_list); } isSpectrDone = true; } return; }
public static double[] padded_FFT(Complex[] complexSignal) { int N = complexSignal.Length; Fourier.FFT(complexSignal, N, FourierDirection.Forward); // get the result double[] fft_real = new double[N]; for (int j = 0; j < N; j++) { fft_real[j] = complexSignal[j].Re; } return(fft_real); }
public override double[] Spectrum(double[] input, bool scale) { var data = ToComplex(input); Fourier.FFT(data, data.Length, FourierDirection.Forward); var spectrum = ComputeSpectrum(data); Fourier.FFT(data, data.Length, FourierDirection.Backward); ToDouble(data, input); return(spectrum); }
public static double[] padded_IFFT(double[] signal) { int N = signal.Length; Complex[] complexSignal = FFTUtils.DoubleToComplex(signal); Fourier.FFT(complexSignal, N, FourierDirection.Backward); // get the result double[] fft_real = new double[N]; for (int j = 0; j < N; j++) { fft_real[j] = complexSignal[j].Re; } return(fft_real); }
/// <summary> /// Applies a High Pass Filter to a Signal /// </summary> /// <param name="s">The Signal to filter</param> /// <returns>The Filtered Signal</returns> public static Signal High(Signal s) { Signal fft = Fourier.FFT(s); int indexPass = (7 * 2) - 1; Signal result = new Signal(s.Length); for (int i = 0; i < result.Length; i++) { result[i] = 0; } for (int i = 15; i < result.Length - indexPass; i += 2) { result[i] = fft[i]; } return(Fourier.InverseFFT(result)); }
public void AppendSample(byte[] data, uint time) { Complex[] fft = new Complex[N]; for (int i = 0; i < N; i++) { int byteOffset = 2 * i; double val = hammingWindowCoeffs[i] * (short)(data[byteOffset] | data[byteOffset + 1] << 8); fft[i] = new Complex(val, 0); } Fourier.FFT(N, fft); var magnitudes = new double[6]; var frequencies = new uint[6]; for (uint freq = MinFrequency; freq < MaxFrequency - 1; freq++) { // Get the magnitude: double mag = fft[freq].Magnitude; // Find out which range we are in: int range = getRange(freq); // Save the highest magnitude and corresponding frequency: if (mag > magnitudes[range]) { magnitudes[range] = mag; frequencies[range] = freq; } } var threshold = 0.9 * (magnitudes[0] + magnitudes[1] + magnitudes[2] + magnitudes[3] + magnitudes[4] + magnitudes[5]) / 6; for (int i = 0; i < 6; i++) { if (magnitudes[i] > threshold) { spectrum.Add(new SpectrumPoint() { Freq = frequencies[i], Time = time }); } } }
private static void LinqVersion() { byte[] outputBuffer = new byte[1024 * 4]; var filter = LoadBlocks(INPUT_FILENAME, outputBuffer.Length) .Select(cb => Fourier.FFT(cb, FourierDirection.Forward)) .Select(cb => LowPassFilter(cb)) .Select(cb => Fourier.FFT(cb, FourierDirection.Backward)); using (Stream output = File.Create(LINQ_OUTPUT_FILENAME)) { foreach (ComplexF[] complexBuffer in filter) { WriteComplexBuffer(output, complexBuffer); } } }
public float[] FFTForward(float[] signal, int startIndex, int length) { float[] complexSignal = new float[2 * length]; /*even - Re, odd - Img, thats how Exocortex works*/ // take 371 ms each 11.6 ms (2048 samples each 64 samples) for (int i = 0; i < length /*2048*/; i++) { complexSignal[2 * i] = signal[startIndex + i]; complexSignal[(2 * i) + 1] = 0; } lock (lockObject) { Fourier.FFT(complexSignal, length, FourierDirection.Forward); } return(complexSignal); }
/// <summary> /// Generate a spectrogram array spaced linearily /// </summary> /// <param name="samples">audio data</param> /// <param name="fftWindowsSize">fft window size</param> /// <param name="fftOverlap">overlap in number of samples (normaly half of the fft window size) [low number = high overlap]</param> /// <returns>spectrogram jagged array</returns> public static double[][] CreateSpectrogramExocortex(float[] samples, int fftWindowsSize, int fftOverlap) { int numberOfSamples = samples.Length; // overlap must be an integer smaller than the window size // half the windows size is quite normal double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); // width of the segment - e.g. split the file into X time slots (numberOfSegments) and do analysis on each slot int numberOfSegments = (numberOfSamples - fftWindowsSize) / fftOverlap; var frames = new double[numberOfSegments][]; // even - Re, odd - Img var complexSignal = new float[2 * fftWindowsSize]; for (int i = 0; i < numberOfSegments; i++) { // apply Hanning Window for (int j = 0; j < fftWindowsSize; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * fftOverlap + j]); // need to clear out as fft modifies buffer (phase) complexSignal[2 * j + 1] = 0; } // FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); // get the ABS of the complex signal var band = new double[fftWindowsSize / 2]; for (int j = 0; j < fftWindowsSize / 2; j++) { double re = complexSignal[2 * j]; double img = complexSignal[2 * j + 1]; band[j] = (double)Math.Sqrt(re * re + img * img); } frames[i] = band; } return(frames); }
/// <summary> /// Create spectrogram of the input file /// </summary> /// <param name = "proxy">Proxy used to read from file</param> /// <param name = "filename">Filename</param> /// <param name = "milliseconds">Milliseconds to process</param> /// <param name = "startmilliseconds">Starting point of the processing</param> /// <returns>Spectrogram</returns> public float[][] CreateSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds, bool doNormalise) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); if (doNormalise) { NormalizeInPlace(samples); } int overlap = Overlap; int fftWindowsSize = WdftSize; // aka N = FFT Length double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) // apply Hanning Window for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) ((4.0/(fftWindowsSize - 1)) * windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; // need to clear out as fft modifies buffer } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); float[] band = new float[fftWindowsSize / 2 + 1]; for (int j = 0; j < fftWindowsSize / 2 + 1; j++) { double re = complexSignal[2 * j]; double img = complexSignal[2 * j + 1]; //double img = 0.0; // TODO: Zero out the imaginary component (phase) ? / need to clear out as fft modifies buffer band[j] = (float)Math.Sqrt(re * re + img * img); } frames[i] = band; } return(frames); }
/// <summary> /// Applies a Notch Filter to a Signal /// </summary> /// <param name="s">The Signal to filter</param> /// <returns>The Filtered Signal</returns> public static Signal Notch(Signal s) { Signal fft = Fourier.FFT(s); Signal result = new Signal(s.Length); for (int i = 0; i < result.Length; i++) { result[i] = fft[i]; } for (int i = 9; i < 16; i++) { result[i] = 0; } for (int i = 497; i < 504; i++) { result[i] = 0; } return(Fourier.InverseFFT(result)); }
public void GetPower() { int count = WINDOW_SIZE / FLOAT_SIZE; complex = new Complex[count]; real = new double[count]; imag = new double[count]; for (int i = 0; i < WINDOW_SIZE; i += 4) { //audioStream.Read(buffer, 0, FLOAT_SIZE); complex[i] = (Complex)BitConverter.ToSingle(window, i); } Fourier.FFT(complex, count, FourierDirection.Forward); real = complex.Select(c => Math.Pow(c.Re, 2)).ToArray(); imag = complex.Select(c => Math.Pow(c.Im, 2)).ToArray(); audioStream.Position -= (WINDOW_SIZE - WINDOW_SHIFT_SIZE); audioStream.Read(window, 0, WINDOW_SIZE); }
private static void SequentialVersion() { using (Stream output = File.Create(OUTPUT_FILENAME)) { byte[] outputBuffer = new byte[1024 * 4]; // Stage 1 foreach (ComplexF[] complexBuffer in LoadBlocks(INPUT_FILENAME, outputBuffer.Length)) { // Stage 2 ComplexF[] result = Fourier.FFT(complexBuffer, FourierDirection.Forward); // Stage 3 result = LowPassFilter(result); // Stage 4 result = Fourier.FFT(result, FourierDirection.Backward); // Stage 5 WriteComplexBuffer(output, result); } } }
public static double[] padded_IFFT(Complex[] complexSignal) { int N = MathUtils.NextPowerOfTwo(complexSignal.Length); if (N <= 4096) { complexSignal = zeros(complexSignal, N); Fourier.FFT(complexSignal, N, FourierDirection.Backward); } else { N = 4096; Array.Resize(ref complexSignal, N); Fourier.FFT(complexSignal, N, FourierDirection.Backward); } // get the result double[] fft_real = new double[N]; for (int j = 0; j < N; j++) { fft_real[j] = complexSignal[j].Re; } return(fft_real); }
private static void CalculateTremor() { GetAccelAmplitudes(); Fourier.FFT(accelAmplitudes, FourierDirection.Forward); float[] fftAmplitudes = GetFFTAmplitudes(accelAmplitudes); float[] binFrequencies = new float[(int)(fftAmplitudes.Length)]; float halfSampleFreq = Sample_Frequency / 2; float freq = 0, maxAmp = Threshold_Amplitude; for (int binIndex = 0; binIndex < binFrequencies.Length; binIndex++) { freq = binIndex * halfSampleFreq / fftAmplitudes.Length; // From: (bin_id * freq/2) / N binFrequencies[binIndex] = freq; if (fftAmplitudes[binIndex] > maxAmp && freq > Threshold_Frequency) { maxAmp = fftAmplitudes[binIndex]; Amplitude = maxAmp; Frequency = freq; } } DataLogging.LogProcessedData(binFrequencies, fftAmplitudes); }
public Bitmap Draw() { var _bitmap = bitmap.Clone() as Bitmap; return(Fourier.FFT(_bitmap)); }
private static double WeightedVolume2(SoundBuffer src, double dbSPL, double dbSPLBase) { double v = 0; uint sr = src.SampleRate; // Read buffer into array of complex Complex[][] data = src.ToComplexArray(); // We only have a single channel Complex[] cdata = data[0]; // FFT in place Fourier.FFT(cdata.Length, cdata); // Calculate magnitude, weighted by 80-phon loudness, for each loudness band. // These are the ISO measured points: FilterProfile lfg; if (dbSPLBase == 0) { lfg = SPL(dbSPL); } else { lfg = DifferentialSPL(dbSPL, dbSPLBase); } // lfg.Add(new FreqGain(sr / 2, lfg[lfg.Count - 1].Gain)); // Cover the ISO measured range (only...) int nStart = (int)(lfg[0].Freq * (long)cdata.Length / sr); int nEnd = (int)(lfg[lfg.Count - 1].Freq * (long)cdata.Length / sr); // Just use linear interpolation (on a dB scale; linear freq scale) of gain between each measured point int nfg = 0; int startp = nStart; int endp = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr); // endpoint of this band double dB1 = lfg[nfg].Gain; // SPL of the ISO223 curve at this freq double dB2 = lfg[nfg + 1].Gain; // ...and the next point double vThisBand = 0; int nThisBand = 0; for (int j = nStart; j < nEnd; j++) { if (j > endp) { if (nThisBand > 0) { v += Math.Sqrt(vThisBand / nThisBand); // RMS } while (j >= endp) { nfg++; startp = j; endp = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr); dB1 = lfg[nfg].Gain; dB2 = lfg[nfg + 1].Gain; } vThisBand = 0; nThisBand = 0; } Complex c = cdata[j]; double dbHere = dB1 + ((dB2 - dB1) * (double)(j - startp) / (double)(endp - startp)); vThisBand += (c.Re * c.Re) / MathUtil.gain(dbHere); nThisBand++; } if (nThisBand > 0) { v += Math.Sqrt(vThisBand / nThisBand); } return(v); }
private bool ComputePartitionedImpulseFFT() { if (_impulse == null) { return(false); } ushort nChannels; if (_input == null) { nChannels = _impulse.NumChannels; } else { nChannels = _input.NumChannels; } ushort p; int N = _impulseLength; int Nh = N << 1; int K = (int)(N / _partitions); int L = MathUtil.NextPowerOfTwo(K << 1); int P = (int)Math.Ceiling((double)N / (double)K); // Initialize the arrays of impulse-FFTs _PartitionedImpulseFFT = new Complex[nChannels][][]; Complex[][] tmp = new Complex[nChannels][]; for (ushort c = 0; c < nChannels; c++) { tmp[c] = new Complex[Nh]; _PartitionedImpulseFFT[c] = new Complex[P][]; for (p = 0; p < P; p++) { _PartitionedImpulseFFT[c][p] = new Complex[L]; } } // Read all samples from the impulse, & fft in blocks of size K (padded to L, L~=2K) int i = 0; int n = 0; p = 0; foreach (ISample sample in _impulse) { // Reading a segment of the impulse (into src[]) n++; if (n > _impulseLength) { break; } // source gave us more data than we'd expected for (ushort c = 0; c < _impulse.NumChannels; c++) { tmp[c][i + K] = new Complex(sample[c], 0); // TBD } i++; if (i >= K) { // Do the fft of this segment of the impulse, into fftImpulse[] for (ushort c = 0; c < nChannels; c++) { if (c >= _impulse.NumChannels) { // Handle the case where impulse has only one channel, but input (hence nChannels) is wider; // we already computed the fft in _PartitionedImpulseFFT[0][p], so just duplicate it. // In fact we can just ref the whole buffer -- no need even to make a deep copy _PartitionedImpulseFFT[c][p] = _PartitionedImpulseFFT[0][p]; } else { Array.Copy(tmp[c], _PartitionedImpulseFFT[c][p], L); Fourier.FFT(L, _PartitionedImpulseFFT[c][p]); } } i = 0; p++; } } _impulseLengthOrig = n - 1; if (p < P) { // Fill any extra space with nulls for (int ii = i; ii < K; ii++) { for (ushort c = 0; c < _impulse.NumChannels; c++) { tmp[c][ii + K] = new Complex(0, 0); // TBD } } // FFT the last segment for (ushort c = 0; c < nChannels; c++) { if (c >= _impulse.NumChannels) { // Handle the case where impulse has only one channel, but input (hence nChannels) is wider; // we already computed the fft in _PartitionedImpulseFFT[0][p], so just duplicate it. // In fact we can just ref the whole buffer -- no need even to make a deep copy _PartitionedImpulseFFT[c][p] = _PartitionedImpulseFFT[0][p]; } else { Array.Copy(tmp[c], _PartitionedImpulseFFT[c][p], L); Fourier.FFT(L, _PartitionedImpulseFFT[c][p]); } } } return(true); }
private bool ComputeNormalImpulseFFT() { if (_impulse == null) { return(false); } ushort nChannels; if (_input == null) { nChannels = _impulse.NumChannels; } else { nChannels = _input.NumChannels; } int N = _impulseLength; int Nh = N << 1; // Initialize the array of impulse-FFTs _NormalImpulseFFT = new Complex[nChannels][]; for (ushort c = 0; c < nChannels; c++) { _NormalImpulseFFT[c] = new Complex[Nh]; } // Read all samples from the impulse // into the second half of the src buffer (the first half is all zeros) int i = 0; foreach (ISample sample in _impulse) { for (ushort c = 0; c < _impulse.NumChannels; c++) { _NormalImpulseFFT[c][i + N] = new Complex(sample[c], 0); } i++; if (i >= _impulseLength) { break; } // source gave us more data than we'd expected } _impulseLengthOrig = i - 1; // Do the fft of impulse, in-place for (ushort c = 0; c < nChannels; c++) { if (c >= _impulse.NumChannels) { // Handle the case where impulse has only one channel, but input (hence nChannels) is wider; // we already computed the fft in _NormalImpulseFFT[0], so just duplicate it. // In fact we can just ref the whole buffer -- no need even to make a deep copy _NormalImpulseFFT[c] = _NormalImpulseFFT[0]; } else { Fourier.FFT(Nh, _NormalImpulseFFT[c]); } } return(true); }
/// <summary> /// 读取样本 /// </summary> /// <param name="transmit"></param> private void ReadSample(bool transmit) { // 提取数据, sampleIndex特定位置 clip.GetData(sampleBuffer, sampleIndex); // 抓住一个新的样品缓冲区 float[] targetSampleBuffer = VoiceChatFloatPool.Instance.Get(); // 将我们的真实样本重新取样到缓冲区中 Resample(sampleBuffer, targetSampleBuffer); // Forward index sampleIndex += recordSampleSize; // 最高自动检测频率 float freq = float.MinValue; int index = -1; // 自动检测语音,但如果我们要按键传输,就不需要检测了 if (autoDetectSpeaking && !transmit) { // 清除FFT缓冲区 for (int i = 0; i < fftBuffer.Length; ++i) { fftBuffer[i] = 0; } // 复制到FFT缓冲区 Array.Copy(targetSampleBuffer, 0, fftBuffer, 0, targetSampleBuffer.Length); // 应用FFT Fourier.FFT(fftBuffer, fftBuffer.Length / 2, FourierDirection.Forward); // 获取最高频率 for (int i = 0; i < fftBuffer.Length; ++i) { if (fftBuffer[i] > freq) { freq = fftBuffer[i]; index = i; } } } // 如果我们有一个事件,并且 if (NewSample != null && (transmit || forceTransmit > 0 || index >= autoDetectIndex)) { // 如果我们自动检测到声音,就强行录音一会儿 if (index >= autoDetectIndex) { if (forceTransmit <= 0) { while (previousSampleBuffer.Count > 0) { TransmitBuffer(previousSampleBuffer.Remove()); } } forceTransmit = forceTransmitTime; } TransmitBuffer(targetSampleBuffer); } else { if (previousSampleBuffer.Count == previousSampleBuffer.Capacity) { VoiceChatFloatPool.Instance.Return(previousSampleBuffer.Remove()); } previousSampleBuffer.Add(targetSampleBuffer); } }
private Complex[] GetFourier(double[] Input) { Complex[] FourierMass = Fourier.FFT(Input); return(FourierMass); }
/// <summary> /// Compute a 1D real-symmetric fast fourier transform. /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <param name="direction"></param> public static void RFFT(float[] data, int length, FourierDirection direction) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < length) { throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter"); } if (Fourier.IsPowerOf2(length) == false) { throw new ArgumentOutOfRangeException("length", length, "must be a power of 2"); } float c1 = 0.5f, c2; float theta = (float)Math.PI / (length / 2); if (direction == FourierDirection.Forward) { c2 = -0.5f; FFT(data, length / 2, direction); } else { c2 = 0.5f; theta = -theta; } float wtemp = (float)Math.Sin(0.5 * theta); float wpr = -2 * wtemp * wtemp; float wpi = (float)Math.Sin(theta); float wr = 1 + wpr; float wi = wpi; // do / undo packing for (int i = 1; i < length / 4; i++) { int a = 2 * i; int b = length - 2 * i; float h1r = c1 * (data[a] + data[b]); float h1i = c1 * (data[a + 1] - data[b + 1]); float h2r = -c2 * (data[a + 1] + data[b + 1]); float h2i = c2 * (data[a] - data[b]); data[a] = h1r + wr * h2r - wi * h2i; data[a + 1] = h1i + wr * h2i + wi * h2r; data[b] = h1r - wr * h2r + wi * h2i; data[b + 1] = -h1i + wr * h2i + wi * h2r; wr = (wtemp = wr) * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } if (direction == FourierDirection.Forward) { float hir = data[0]; data[0] = hir + data[1]; data[1] = hir - data[1]; } else { float hir = data[0]; data[0] = c1 * (hir + data[1]); data[1] = c1 * (hir - data[1]); Fourier.FFT(data, length / 2, direction); } }
static void Main() { //var A1 = new double[Nx]; //var A2 = new double[Nx]; //for (int i = 0; i < Nx; i++) //{ // A1[i] = i; // A2[i] = A1[i]; //} //A2[Nx - 1] = 253; //double res = NormsComparison(A2, A1); int jj = 0; SetPumping(r); SetLosses(sigma); SetSpaceFrequency(); SetInitials(); SetExtraConstants(); for (int i = 0; i < Nx; i++) { Console.WriteLine(E[i].Abs * E[i].Abs); } sumtimer.Start(); for (int q = 0; q < Nt; q++) { ffttimer.Start(); Ef = Fourier.FFT(E); Pf = Fourier.FFT(P); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { Dfl[i] = exp1 * D[i]; Pfl[i] = exp2 * P[i]; Pf[i] = Pf[i] * exp4[i]; Efl[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]); } ffttimer.Start(); Efl = Fourier.IFFT(Efl); ffttimer.Stop(); // Start iteration process Set(E, Ec); Set(P, Pc); Set(D, Dc); Set(E, Ej); ffttimer.Start(); Ef = Fourier.FFT(Efl); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { exp5[i] = D[i] * E[i]; exp6[i] = 2 * R[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im); } //jj = 0; for (int j = 0; j < Nmax; j++) { //jj++; for (int i = 0; i < Nx; i++) { Pj[i] = Pfl[i] + (exp5[i] + Dc[i] * Ec[i]) / 2 * dt; Dj[i] = Dfl[i] + gamma * dt * (exp6[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im)) / 2; } ffttimer.Start(); Pf = Fourier.FFT(Pj); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { Pf[i] = Pf[i] * exp4[i]; Dj[i] = Dj[i] * exp1; Pj[i] = Pj[i] * exp2; Ej[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]); } ffttimer.Start(); Ej = Fourier.IFFT(Ej); ffttimer.Stop(); normtimer.Start(); double normE = NormsComparison(Ej, Ec); double normP = NormsComparison(Pj, Pc); double normD = NormsComparison(Dj, Dc); if (normE < eps && normP < eps && normD < eps) { Ec = Ej; Pc = Pj; Dc = Dj; normtimer.Stop(); if (jj != j) { Console.WriteLine(j); jj = j; } break; } else { Set(Ej, Ec); Set(Pj, Pc); Set(Dj, Dc); } normtimer.Stop(); } //Console.WriteLine(jj); E = Ec; P = Pc; D = Dc; } sumtimer.Stop(); Console.WriteLine("Sum time: " + sumtimer.ElapsedMilliseconds / Nt); Console.WriteLine("FFT time: " + ffttimer.ElapsedMilliseconds / Nt); Console.WriteLine("Norm time: " + normtimer.ElapsedMilliseconds / Nt); for (int i = 0; i < Nx; i++) { Console.WriteLine(E[i].Abs * E[i].Abs); } Console.ReadKey(); }
public static Trace[] Deconvolve(Trace[] data, double decA = Double.NegativeInfinity, bool onlyRe = false) { var tracesDataDeconv = new Trace[numberOfSonograms * numberOfTraces]; if (Double.IsNegativeInfinity(decA)) { decA = curDecA; } var impulseSpec = new Exocortex.DSP.Complex[4096]; for (int i = 0; i < signal.Length; i++) { impulseSpec[i].Re = signal[i]; } Exocortex.DSP.Fourier.FFT(impulseSpec, 4096, Exocortex.DSP.FourierDirection.Forward); var impMulti = new Exocortex.DSP.Complex[4096]; if (decA >= 0) { var impulseSpecInv = new Exocortex.DSP.Complex[4096]; for (int i = 0; i < impulseSpec.Length; i++) { impulseSpecInv[i].Re = impulseSpec[i].Re; impulseSpecInv[i].Im = -impulseSpec[i].Im; } for (int i = 0; i < impulseSpec.Length; i++) { impMulti[i] = impulseSpecInv[i] / (Math.Pow(impulseSpec[i].Re, 2) + Math.Pow(impulseSpec[i].Im, 2) + Math.Pow(decA, 2)); } } else { for (int i = 0; i < impulseSpec.Length; i++) { impMulti[i] = impulseSpec[i]; } } Parallel.For(0, data.Length, tn => { var t = data[tn]; var tempColumn = new Exocortex.DSP.Complex[4096]; for (int i = 0; i < Math.Min(4096, maxtime); i++) { tempColumn[i].Re = t.data[i]; } Fourier.FFT(tempColumn, 4096, FourierDirection.Forward); for (int i = 0; i < 4096; i++) { tempColumn[i] = tempColumn[i] * impMulti[i]; } Fourier.FFT(tempColumn, 4096, FourierDirection.Backward); Trace tConv = new Trace(t); for (int i = 0; i < Math.Min(4096, maxtime); i++)//обрезаем то, что вылезло за границы { tConv.data[i] = (onlyRe ? (float)tempColumn[i].Re : (float)Math.Sqrt(tempColumn[i].Re * tempColumn[i].Re + tempColumn[i].Im * tempColumn[i].Im)) / 4096; } tracesDataDeconv[tn] = tConv; }); return(tracesDataDeconv); }
public void Calculate() { try { sumtimer.Reset(); ffttimer.Reset(); normtimer.Reset(); if (OnCalculationStart != null) { OnCalculationStart(this, new EventArgs()); } sumtimer.Start(); SetParameters(); for (int q = 0; q < Nt; q++) { if (CalculationCancelled) { break; } ffttimer.Start(); Ef = Fourier.FFT(E); Pf = Fourier.FFT(P); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { Dfl[i] = exp1 * D[i]; Pfl[i] = exp2 * P[i]; Pf[i] = Pf[i] * exp4[i]; Efl[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]); } ffttimer.Start(); Efl = Fourier.IFFT(Efl); ffttimer.Stop(); // Start iteration process Set(E, Ec); Set(P, Pc); Set(D, Dc); Set(E, Ej); ffttimer.Start(); Ef = Fourier.FFT(Efl); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { exp5[i] = D[i] * E[i]; exp6[i] = 2 * R[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im); } //jj = 0; for (int j = 0; j < Nmax; j++) { //jj++; for (int i = 0; i < Nx; i++) { Pj[i] = Pfl[i] + (exp5[i] + Dc[i] * Ec[i]) / 2 * dt; Dj[i] = Dfl[i] + gamma * dt * (exp6[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im)) / 2; } ffttimer.Start(); Pf = Fourier.FFT(Pj); ffttimer.Stop(); for (int i = 0; i < Nx; i++) { Pf[i] = Pf[i] * exp4[i]; Dj[i] = Dj[i] * exp1; Pj[i] = Pj[i] * exp2; Ej[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]); } ffttimer.Start(); Ej = Fourier.IFFT(Ej); ffttimer.Stop(); normtimer.Start(); //double normE = NormsComparison(Ej, Ec); //double normP = NormsComparison(Pj, Pc); //double normD = NormsComparison(Dj, Dc); if (NormsComparison(Ej, Ec) < eps && NormsComparison(Pj, Pc) < eps && NormsComparison(Dj, Dc) < eps) { Ec = Ej; Pc = Pj; Dc = Dj; normtimer.Stop(); if (jj != j) { Console.WriteLine(j); jj = j; } break; } else { Set(Ej, Ec); Set(Pj, Pc); Set(Dj, Dc); } normtimer.Stop(); } //Console.WriteLine(jj); E = Ec; P = Pc; D = Dc; } } catch (Exception ex) { if (OnCalculationError != null) { OnCalculationError(this, new EventArgs()); } } sumtimer.Stop(); if (OnCalculationFinish != null) { OnCalculationFinish(this, new EventArgs()); } CalculationCancelled = false; }