public static double[] MagnitudeSpectrum(ReadOnlySpan <float> frame, int nfft) { var spec = new double[nfft]; for (var i = 0; i < frame.Length; i++) { // Blackman Harris 62 dB var w = (0.44859 + 0.49364 * Math.Cos(2.0 * Math.PI * i / frame.Length) + 0.05677 * Math.Cos(4.0 * Math.PI * i / frame.Length)) / frame.Length; // センタリング spec[(nfft - frame.Length) / 2 + i] = frame[i] * w; } var imag = new double[nfft]; FourierTransform2.FFT(spec, imag, FourierTransform.Direction.Forward); for (var i = 0; i < spec.Length; i++) { spec[i] = Math.Sqrt(spec[i] * spec[i] + imag[i] * imag[i]); } return(spec); }
public void gh878() { // https://github.com/accord-net/framework/issues/878 // Should not throw (throws now): Complex[][] input = new[] { new[] { Complex.Zero, Complex.Zero }, new[] { Complex.Zero, Complex.Zero }, new[] { Complex.Zero, Complex.Zero }, }; FourierTransform2.DFT2(input, FourierTransform.Direction.Forward); Assert.AreEqual(3, input.Rows()); Assert.AreEqual(2, input.Columns()); // Also should not throw (symmetric check, doesn't throw now): Complex[][] input2 = new[] { new[] { Complex.Zero, Complex.Zero, Complex.Zero }, new[] { Complex.Zero, Complex.Zero, Complex.Zero }, }; FourierTransform2.DFT2(input2, FourierTransform.Direction.Forward); Assert.AreEqual(3, input.Rows()); Assert.AreEqual(2, input.Columns()); }
public static Complex[] DFT(this IEnumerable <Point> source) { var complex = source.Select(item => new Complex(item.x, item.y)).ToArray(); FourierTransform2.DFT(complex, FourierTransform.Direction.Backward); return(complex); }
public override void FFT(bool forward) { data.CopyTo(copy, 0); FourierTransform2.FFT(copy, forward ? FourierTransform.Direction.Forward : FourierTransform.Direction.Backward); }
/// <summary> /// Applies backward fast Fourier transformation to the complex signal. /// </summary> /// public void BackwardFourierTransform() { if (status == ComplexSignalStatus.FourierTransformed) { for (int i = 0; i < NumberOfChannels; i++) { Complex[] channel = GetChannel(i); FourierTransform2.FFT(channel, FourierTransform.Direction.Backward); SetChannel(i, channel); } status = ComplexSignalStatus.Normal; } }
static void Main(string[] args) { // Console.WriteLine("Hello World!"); const int end = 100; // const int step = 1; // var count = end / step; // if (end % step != 0) count++; // var data = new Complex [count]; // var j = 0; // for (var i = 0; i < end; i += step) // { // data[j++] = new Complex(i, 1); // } // // //// data = Enumerable.Range(0, count).Select(t => new Complex(t, 1)).ToArray(); // data[^3..] // .ToList() // .ForEach(t => // Console.WriteLine($"{t},{t.Real / t.Imaginary}") // ); // Console.WriteLine($"count:{count}, end:{end}, step:{step}"); // FourierTransform2.FFT(data, FourierTransform.Direction.Forward); // var result = data.Where(t => t.Imaginary > 0).ToList(); // Console.WriteLine($"result count:{count}"); // foreach (var t in result) // { // Console.WriteLine($"{t}"); // } var data2 = new Complex[end]; data2[0] = new Complex(0, 1); for (var i = 1; i < end; i++) { data2[i] = new Complex(i, 0); if (i % 4 == 0) { data2[i] = new Complex(i, 1); } } FourierTransform2.FFT(data2, FourierTransform.Direction.Forward); var result = data2.Take(data2.Length / 2).ToList(); for (var i = 0; i < result.Count; i++) { Console.WriteLine($"period:{i},m:{result[i].Magnitude:f2},{result[i]},{result[i].Phase}"); } }
public override double[] Spectrum(double[] input, bool scale) { var data = ToComplex(input); FourierTransform2.FFT(data, FourierTransform.Direction.Forward); var spectrum = ComputeSpectrum(data); FourierTransform2.FFT(data, FourierTransform.Direction.Backward); ToDouble(data, input); return(spectrum); }
public void dft2d_test() { #region doc_dft2 // Suppose we would like to transform the matrix Complex[][] input = new Complex[][] { new Complex[] { 1, 4, 8, 0 }, new Complex[] { 0, 4, 5, 0 }, new Complex[] { 0, 0, 8, 0 }, }; // We can forward it to the time domain using the Fourier transform FourierTransform2.DFT2(input, FourierTransform.Direction.Forward); // We can also get the real and imaginary parts of the matrix using double[][] re = input.Re(); // The real part of the output will be: double[][] expectedRe = new double[][] { new double[] { 30.0, -20.0, 14.0, -20.0 }, new double[] { 4.5, -3.9641, 0.4999, 2.9641 }, new double[] { 4.5, 2.9641, 0.5000, -3.9641 } }; double[][] im = input.Im(); // The imaginary part of the output will be: double[][] expectedIm = new double[][] { new double[] { 0, -8, 0, 7.9999 }, new double[] { -0.8660, -4.5980, 6.0621, -0.5980 }, new double[] { 0.8660, 0.5980, -6.0621, 4.5980 } }; // We can recover the initial matrix using the backward transform: FourierTransform2.DFT2(input, FourierTransform.Direction.Backward); #endregion string a = re.ToCSharp(); string b = im.ToCSharp(); Assert.IsTrue(re.IsEqual(expectedRe, 1e-3)); Assert.IsTrue(im.IsEqual(expectedIm, 1e-3)); var expected = new Complex[][] { new Complex[] { 1, 4, 8, 0 }, new Complex[] { 0, 4, 5, 0 }, new Complex[] { 0, 0, 8, 0 }, }; Assert.IsTrue(input.Re().IsEqual(expected.Re(), 1e-3)); Assert.IsTrue(input.Im().IsEqual(expected.Im(), 1e-3)); }
/// <summary> /// Computes (populates) a Spectrogram mapping with values from a signal. /// </summary> /// /// <param name="signal">The signal to be windowed in the spectrogram.</param> /// public void Compute(Signal signal) { this.frequencies = FourierTransform2.GetFrequencyVector(windowSize, signal.SampleRate); Signal[] signals = signal.Split(window: window, stepSize: windowSize); this.magnitudes = new double[signals.Length][]; for (int i = 0; i < signals.Length; i++) { ComplexSignal c = signals[i].ToComplex(); c.ForwardFourierTransform(); this.magnitudes[i] = FourierTransform2.GetMagnitudeSpectrum(c.GetChannel(channel)); } }
private static void BasicTest() { const int windowSize = 1024; int rate; var data = new float[windowSize]; // 2.5sのところから1024サンプル取得してくる using (var reader = new AudioFileReader(@"C:\Users\azyob\Documents\Jupyter\chroma\BEYOND THE STARLIGHT.wav")) { var provider = reader.ToSampleProvider() .Skip(TimeSpan.FromSeconds(5.2)) .ToMono(); rate = provider.WaveFormat.SampleRate; for (var readSamples = 0; readSamples < data.Length;) { var delta = provider.Read(data, readSamples, data.Length - readSamples); if (delta == 0) { throw new EndOfStreamException(); } readSamples += delta; } } var fft = Array.ConvertAll(data, x => (Complex)x); FourierTransform2.FFT(fft, FourierTransform.Direction.Forward); var fftSeries = new LineSeries(); fftSeries.Points.AddRange(fft.Take(fft.Length / 2).Select((x, i) => new DataPoint(i, Math.Log(x.SquaredMagnitude())))); ShowPlot(new PlotModel() { Title = "スペクトル", Series = { fftSeries } }); var nsdf = McLeodPitchMethod.NormalizedSquareDifference(data); var series = new LineSeries(); series.Points.AddRange(nsdf.Select((x, i) => new DataPoint(i, x))); ShowPlot(new PlotModel() { Title = "NSDF", Series = { series } }); Console.WriteLine("{0} Hz", McLeodPitchMethod.EstimateFundamentalFrequency(rate, data)); }
public FrequencySpectrum(double[] data, double samplingFrequency) { var count = data.Length / 2; _data = data; _energy = new double[data.Length]; Array.Copy(data, _energy, _energy.Length); _samplingFrequency = samplingFrequency; var im = new double[_energy.Length]; FourierTransform2.FFT(_energy, im, FourierTransform.Direction.Forward); Helpers.CalculateEnergy(_energy, im, count); Maximum = _energy.Take(_energy.Length / 2).Max(); //for (int i = 0; i < _energy.Length / 2; i++) // _energy[i] /= Maximum; }
private void InputCore(double pitchRate) { var hop = this._windowLength / 2; for (var i = 0; i < this._fftInputBuffer.Length; i++) { this._fftBuffer[i] = this._fftInputBuffer[i] * this._window[i]; } FourierTransform2.FFT(this._fftBuffer, FourierTransform.Direction.Forward); // ピッチ変更 for (var i = 0; i < hop; i++) { var pos = i / pitchRate; var a = (int)pos; Complex newSpec; if (a >= this._windowLength) { // 範囲外なので諦める newSpec = this._fftBuffer[i]; } else if (a == this._windowLength - 1 || a == pos) { newSpec = this._fftBuffer[a]; } else { // 補間 newSpec = this._fftBuffer[a] + (this._fftBuffer[a + 1] - this._fftBuffer[a]) * (pos - a); } this._modifiedSpectrum[i] = newSpec; this._modifiedSpectrum[this._windowLength - i - 1] = newSpec; } FourierTransform2.FFT(this._modifiedSpectrum, FourierTransform.Direction.Backward); for (var i = 0; i < this._fftOutputBuffer.Length; i++) { this._fftOutputBuffer[i] = (float)this._modifiedSpectrum[i].Real * this._window[i]; } }
private static void testConvolution(int size) { double[] randomReals1 = randomReals(size); double[] randomReals2 = randomReals(size); double[] randomReals3 = randomReals(size); double[] randomReals4 = randomReals(size); // Test double array overloads double[] input0real = (double[])randomReals1.Clone(); double[] input0imag = (double[])randomReals2.Clone(); double[] input1real = (double[])randomReals3.Clone(); double[] input1imag = (double[])randomReals4.Clone(); double[] refoutreal = new double[size]; double[] refoutimag = new double[size]; naiveConvolve(input0real, input0imag, input1real, input1imag, refoutreal, refoutimag); double[] actualoutreal = new double[size]; double[] actualoutimag = new double[size]; FourierTransform2.Convolve(input0real, input0imag, input1real, input1imag, actualoutreal, actualoutimag); double error = log10RmsErr(refoutreal, refoutimag, actualoutreal, actualoutimag); Assert.IsTrue(error < 13); // Test Complex overloads input0real = (double[])randomReals1.Clone(); input0imag = (double[])randomReals2.Clone(); input1real = (double[])randomReals3.Clone(); input1imag = (double[])randomReals4.Clone(); Complex[] input0 = input0real.ToComplex(input0imag); Complex[] input1 = input1real.ToComplex(input1imag); Complex[] actualout = new Complex[size]; FourierTransform2.Convolve(input0, input1, actualout); actualoutreal = actualout.Re(); actualoutimag = actualout.Im(); double newError = log10RmsErr(refoutreal, refoutimag, actualoutreal, actualoutimag); Assert.AreEqual(error, newError); }
public void TestBandStopSinusoid() { const int order = 16; const int fs = 44100; const int targetFrequency = 3; const double br = 5; const int cycles = 10; double[] frequencies = { 65.406, 130.81, 261.63, 523.25, 1046.5, 2093.0, 4186.0, 8372.0 }; var signal = new double[cycles * fs]; foreach (var frequency in frequencies) { Helpers.GenerateSinusoid(frequency, fs, signal); } var im = new double[signal.Length]; var coeff = new BandStopChebyshevIICoefficients(order, fs, frequencies[targetFrequency] - br, frequencies[targetFrequency] + br, 48); var chain = coeff.Calculate(); chain.Filter(signal, 0, signal, 0, signal.Length); var count = signal.Length / 2; FourierTransform2.FFT(signal, im, FourierTransform.Direction.Forward); Helpers.CalculateEnergy(signal, im, count); var maxEnergy = signal.Take(count).Max(); var step = fs / (2d * count); var peakSet = new HashSet <double>(); for (int i = 1; i < count - 1; i++) { var freq = i * step; if (signal[i] > signal[i - 1] && signal[i] > signal[i + 1] && signal[i] >= 0.01 * maxEnergy) { var peak = frequencies.FirstOrDefault(x => Math.Abs(freq - x) <= 1); Assert.AreNotEqual(0, peak); peakSet.Add(peak); } } Assert.IsTrue(peakSet.SetEquals(frequencies.Except(Enumerable.Repeat(frequencies[targetFrequency], 1)))); }
protected List <Tuple <double, double[]> > GetFourierTransformedList(Complex[][] dataRows) { double[][] frequencyEstimates = new double[dataRows.GetLength(0)][]; for (int column = 0; column < dataRows.GetLength(0); column++) { FourierTransform2.FFT(dataRows[column], Accord.Math.FourierTransform.Direction.Forward); // fft transform on rows for provided column frequencyEstimates[column] = GetFourierProperty(dataRows[column]); } List <Tuple <double, double[]> > frequencySpectraData = new List <Tuple <double, double[]> >(); for (int frequencyBin = 0; frequencyBin < frequencyEstimates[0].Length; frequencyBin++) { // NOTE - frequency transforms are applied to all columns double[] frequencyColumn = TransformRow(GetAppliedColumns(GetColumns(), dataRows.GetLength(0)), (value, column) => frequencyEstimates[column][frequencyBin], new double[dataRows.GetLength(0)]); frequencySpectraData.Add(new Tuple <double, double[]>(frequencyBin, frequencyColumn)); } return(frequencySpectraData); }
public void TestLowPassSinusoid() { const int order = 16; const int fs = 44100; const double cutoffFrequency = 400d; const int cycles = 10; double[] frequencies = { 65.406, 130.81, 261.63, 523.25, 1046.5, 2093.0, 4186.0, 8372.0 }; var signal = new double[cycles * fs]; foreach (var frequency in frequencies) { Helpers.GenerateSinusoid(frequency, fs, signal); } var im = new double[signal.Length]; var coeff = new LowPassButtersworthCoefficients(order, fs, cutoffFrequency); var chain = coeff.Calculate(); chain.Filter(signal, 0, signal, 0, signal.Length); var count = signal.Length / 2; FourierTransform2.FFT(signal, im, FourierTransform.Direction.Forward); Helpers.CalculateEnergy(signal, im, count); var maxEnergy = signal.Take(count).Max(); var step = fs / (2d * count); var peakSet = new HashSet <double>(); for (int i = 1; i < count - 1; i++) { var freq = i * step; if (signal[i] > signal[i - 1] && signal[i] > signal[i + 1] && signal[i] >= 0.001 * maxEnergy) { var peak = frequencies.FirstOrDefault(x => Math.Abs(freq - x) <= 1); Assert.AreNotEqual(0, peak); peakSet.Add(peak); } } Assert.IsTrue(peakSet.SetEquals(frequencies.Where(x => x < cutoffFrequency))); }
public void Calculate(float[] samples) { lock (this) { if (_complexArr.Length != samples.Length) { Array.Resize(ref _complexArr, samples.Length); } for (var i = 0; i < samples.Length; i++) { _complexArr[i] = samples[i]; } FourierTransform2.FFT(_complexArr, Accord.Math.FourierTransform.Direction.Backward); for (var i = 0; i < samples.Length; i++) { samples[i] = (float)_complexArr[i].Magnitude; } } }
public static double[] NormalizedSquareDifference(ReadOnlySpan <float> samples) { // ACF // 1. zero pad var acf = new Complex[samples.Length * 2]; for (var i = 0; i < samples.Length; i++) { acf[i] = samples[i]; } // 2. FFT FourierTransform2.FFT(acf, FourierTransform.Direction.Forward); // 3. パワースペクトル for (var i = 0; i < acf.Length; i++) { var x = acf[i]; acf[i] = x.Real * x.Real + x.Imaginary * x.Imaginary; } // 4. inverse FFT FourierTransform2.FFT(acf, FourierTransform.Direction.Backward); // NSDF var nsdf = new double[samples.Length]; var m = 0.0; for (var i = samples.Length - 1; i >= 0; i--) { var x = (double)samples[i]; m += x * x; var inv = samples.Length - i - 1; x = samples[inv]; m += x * x; nsdf[i] = 2.0 * acf[i].Real / m; } return(nsdf); }
private void UpdateTimer_Tick(object sender, EventArgs e) { double[] real; lock (cb) { real = cb.ToArray(); } double[] imag = real.Select(s => 0.0).ToArray(); FourierTransform2.FFT(real, imag, Accord.Math.FourierTransform.Direction.Forward); double[] frequencyVector = Accord.Math.Vector.Interval(0.0, (double)(real.Length / 2)); frequencyVector = frequencyVector.Select(s => s * fps / real.Length).ToArray(); faChart.Series[0].Points.Clear(); for (int i = 1; i < real.Length / 2; i++) { faChart.Series[0].Points.AddXY(frequencyVector[i], 2 * ComplexAbs(real[i], imag[i]) / real.Length); } faChart.ResetAutoValues(); }
public void CalculateFFT() { Complex[] complexPcm = new Complex[AudioInput.BUFFER_LENGTH_16]; for (int i = 0; i < AudioInput.BUFFER_LENGTH_16; i++) { // https://dsp.stackexchange.com/questions/1991/how-to-shift-the-frequency-spectrum Complex exp = new Complex(0.0, -2 * Math.PI * Offset * i / AudioInput.SAMPLING_RATE); complexPcm[i] = pcm[i] * Complex.Exp(exp); } FourierTransform2.FFT(complexPcm, FourierTransform.Direction.Forward); const int HIGH = (int)(FFT_HIGHEST_FREQ / FREQ_RESOLUTION); double[] freqs = new double[HIGH]; for (int i = 4; i < freqs.Length; i++) { freqs[i] = complexPcm[i].Magnitude; } FFT = freqs; }
/// <summary> /// Calculates Periodogram of a given vector of type double based on Welch method. /// </summary> /// /// <param name="vector"> /// A vector of observations whose Periodogram will be calculated. It is assumed that /// the vector is a 1-D array of type double /// </param> /// /// <returns> /// Returns a vector of type double giving the periodogram of the vector. /// </returns> public static double[] Periodogram(double[] vector) { int nTime = vector.Length; double[] pwr = new double[vector.Length]; if (nTime == 1) { pwr[0] = 1.0; return(pwr); } Complex[] vectorComplex = new Complex[vector.Length]; for (int k = 0; k < vector.Length; k++) { vectorComplex[k] = new Complex(vector[k], 0); } FourierTransform2.FFT(vectorComplex, FourierTransform.Direction.Forward); pwr = FourierTransform2.GetPowerSpectrum(vectorComplex); return(pwr); }
public void fft1d_test() { #region doc_fft // Example from http://www.robots.ox.ac.uk/~sjrob/Teaching/SP/l7.pdf Complex[] input = new Complex[] { 8, 4, 8, 0 }; FourierTransform2.FFT(input, FourierTransform.Direction.Forward); Complex[] output = input; // the output will be { 20, -4j, 12, 4j } // We can also get the real and imaginary parts of the vector using double[] re = output.Re(); // should be { 20, 0, 12, 0 } double[] im = output.Im(); // should be { 0, -4, 0, 4 } // We can recover the initial vector using the backward transform: FourierTransform2.FFT(output, FourierTransform.Direction.Backward); #endregion double[] re2 = output.Re(); double[] im2 = output.Im(); Assert.IsTrue(re.IsEqual(new[] { 20, 0, 12, 0 }, 1e-8)); Assert.IsTrue(im.IsEqual(new[] { 0, -4, 0, 4 }, 1e-8)); Assert.IsTrue(re2.IsEqual(new[] { 8, 4, 8, 0 }, 1e-8)); Assert.IsTrue(im2.IsEqual(new[] { 0, 0, 0, 0 }, 1e-8)); }
private static void testFft(int size) { double[] re = randomReals(size); double[] im = randomReals(size); // Test double array overloads double[] inputreal = (double[])re.Clone(); double[] inputimag = (double[])im.Clone(); double[] refoutreal = new double[size]; double[] refoutimag = new double[size]; naiveDft(inputreal, inputimag, refoutreal, refoutimag, false); double[] actualoutreal = (double[])inputreal.Clone(); double[] actualoutimag = (double[])inputimag.Clone(); FourierTransform2.FFT(actualoutreal, actualoutimag, FourierTransform.Direction.Forward); double error = log10RmsErr(refoutreal, refoutimag, actualoutreal, actualoutimag); Assert.IsTrue(error < -12.9); // Test Complex overloads inputreal = (double[])re.Clone(); inputimag = (double[])im.Clone(); Complex[] input = inputreal.ToComplex(inputimag); FourierTransform2.FFT(input, FourierTransform.Direction.Forward); actualoutreal = input.Re(); actualoutimag = input.Im(); double newError = log10RmsErr(refoutreal, refoutimag, actualoutreal, actualoutimag); Assert.AreEqual(error, newError); }
public double[] MelSpectrum(ReadOnlySpan <float> samples) { if (samples.Length != this.SampleCount) { throw new ArgumentException("samples の長さが違います。"); } var real = new double[samples.Length]; var imag = new double[samples.Length]; // プリエンファシス → 窓関数 real[0] = samples[0] * this._windowFunc[0]; for (var i = 1; i < real.Length; i++) { var emphasized = samples[i] - 0.97 * samples[i - 1]; real[i] = emphasized * this._windowFunc[i]; } FourierTransform2.FFT(real, imag, FourierTransform.Direction.Forward); // 振幅スペクトル for (var i = 0; i < real.Length; i++) { real[i] = real[i] * real[i] + imag[i] * imag[i]; } // メルフィルターバンクをかける var filtered = real.Dot(this._melFilterbank); for (var i = 0; i < filtered.Length; i++) { filtered[i] = Math.Log10(filtered[i]); } return(filtered); }
public static void Compute(ref double[,] u, ref Complex[,] u_hat, ref double[,] omega, double[] signal, double alpha, double tau, int K, int DC, int init, double tol) { int save_T = signal.Length; double fs = 1 / (double)save_T; //int T = save_T; double[] f_mirrow = new double[2 * save_T]; Array.Copy(signal, 0, f_mirrow, (int)(save_T / 2), save_T); for (int i = 0; i < save_T / 2; ++i) { f_mirrow[i] = signal[save_T / 2 - 1 - i]; } for (int i = 3 * save_T / 2; i < 2 * save_T; i++) { f_mirrow[i] = signal[save_T + 3 * save_T / 2 - 1 - i]; } double[] f = f_mirrow; int T = f.Length; Complex[] freqs = Vector.Zeros <Complex>(T); double[] timevec = Vector.Zeros <double>(T); for (int i = 0; i < T; i++) { timevec[i] = (double)(i + 1.0) / T; freqs[i] = (timevec[i] - 0.5) - (double)(1 / T); } int N = 500; double[] Alpha = Vector.Create <double>(K, alpha); Complex[] freqvec = new Complex[T]; for (int i = 0; i < freqvec.Length; i++) { freqvec[i] = f[i]; } FourierTransform2.FFT(freqvec, FourierTransform.Direction.Forward); Complex[] f_hat = circshift(freqvec, T / 2); Complex[] f_hat_plus = Vector.Zeros <Complex>(f_hat.Length); Array.Copy(f_hat, T / 2, f_hat_plus, T / 2, T / 2); Complex[,,] u_hat_plus = new Complex[N, K, T]; Complex[,] omega_plus = Matrix.Zeros <Complex>(N, K); double[] tmp; switch (init) { case 1: for (int i = 0; i < K; i++) { omega_plus[0, i] = (double)(0.5 / K) * i; } break; case 2: tmp = omega_init_method2(K, fs); for (int i = 0; i < K; i++) { omega_plus[0, i] = tmp[i]; } break; default: break; } if (DC != 0) { omega_plus[0, 0] = 0; } Complex[,] lambda_hat = new Complex[N, T]; double uDiff = tol + eps_for_VMD; int n = 1;// loop counter Complex[] sum_uk = new Complex[T]; int k; while (uDiff > tol && n < N) { k = 1; for (int i = 0; i < sum_uk.Length; ++i) { sum_uk[i] = u_hat_plus[n - 1, K - 1, i] + sum_uk[i] - u_hat_plus[n - 1, 0, i]; } //update spectrum of first mode through Wiener filter of residuals Complex[] Dividend_vec = new Complex[T]; Complex[] Divisor_vec = new Complex[T]; for (int i = 0; i < sum_uk.Length; ++i) { Dividend_vec[i] = f_hat_plus[i] - sum_uk[i] - (lambda_hat[n - 1, i] / 2.0); Divisor_vec[i] = (1 + Alpha[k - 1] * (freqs[i] - omega_plus[n - 1, k - 1]) * (freqs[i] - omega_plus[n - 1, k - 1])); u_hat_plus[n, k - 1, i] = Dividend_vec[i] / Divisor_vec[i]; } if (DC == 0) { Complex Dividend = new Complex(0, 0), Divisor = new Complex(0, 0), Addend; for (int i = 0; i < T - T / 2; i++) { Addend = u_hat_plus[n, k - 1, T / 2 + i].Magnitude * u_hat_plus[n, k - 1, T / 2 + i].Magnitude; Divisor += Addend; Dividend += freqs[T / 2 + i] * Addend; } omega_plus[n, k - 1] = Dividend / Divisor; } for (k = 1; k < K; k++) { for (int i = 0; i < u_hat_plus.GetLength(2); i++) { sum_uk[i] = u_hat_plus[n, k - 1, i] + sum_uk[i] - u_hat_plus[n - 1, k, i]; } Complex[] Dividend_vec1 = new Complex[T]; Complex[] Divisor_vec1 = new Complex[T]; for (int i = 0; i < sum_uk.Length; ++i) { Dividend_vec1[i] = f_hat_plus[i] - sum_uk[i] - (lambda_hat[n - 1, i] / 2.0); Divisor_vec1[i] = (1 + Alpha[k] * (freqs[i] - omega_plus[n - 1, k]) * (freqs[i] - omega_plus[n - 1, k])); u_hat_plus[n, k, i] = Dividend_vec1[i] / Divisor_vec1[i]; } Complex Dividend = new Complex(0, 0), Divisor = new Complex(0, 0), Addend; for (int i = 0; i < T - T / 2; i++) { Addend = u_hat_plus[n, k, T / 2 + i].Magnitude * u_hat_plus[n, k, T / 2 + i].Magnitude; Divisor += Addend; Dividend += freqs[T / 2 + i] * Addend; } omega_plus[n, k] = Dividend / Divisor; } Complex[] sumv = sum(u_hat_plus, n); for (int i = 0; i < lambda_hat.GetLength(1); ++i) { lambda_hat[n, i] = lambda_hat[n - 1, i] + tau * (sumv[i] - f_hat_plus[i]); } n++; Complex acc = new Complex(eps_for_VMD, 0); for (int i = 0; i < K; i++) { Complex[] temp = new Complex[u_hat_plus.GetLength(2)]; Complex[] conjtemp = new Complex[u_hat_plus.GetLength(2)]; for (int j = 0; j < u_hat_plus.GetLength(2); j++) { temp[j] = u_hat_plus[n - 1, i, j] - u_hat_plus[n - 2, i, j]; conjtemp[j] = Complex.Conjugate(temp[j]); } var dottemp = Dot(temp, conjtemp); acc = acc + dottemp / (double)T; } uDiff = acc.Magnitude; } N = Math.Min(N, n); omega = new double[N, omega_plus.GetLength(1)]; for (int i = 0; i < omega_plus.GetLength(1); ++i) { for (int j = 0; j < N; j++) { omega[j, i] = omega_plus[j, i].Real; } } u_hat = Matrix.Zeros <Complex>(T, K); for (int i = T / 2; i < T; i++) { for (int j = 0; j < K; j++) { //var v = u_hat_plus[N - 1, j, i]; u_hat[i, j] = u_hat_plus[N - 1, j, i]; } } for (int i = 0; i < T / 2; i++) { for (int j = 0; j < K; j++) { //u_hat[i, j] = Complex.Conjugate(u_hat_plus[N - 1, j, T - i - 1]); u_hat[i, j] = Complex.Conjugate(u_hat_plus[N - 1, j, i]); } } //for (int i = T / 2 - 1; i >= 0; i--) // for (int j = 0; j < K; j++) // { // var v = Complex.Conjugate(u_hat_plus[N - 1, j, T - i - 1]); // u_hat[i, j] = Complex.Conjugate(u_hat_plus[N - 1, j, T - i - 1]); // } for (int i = 0; i < u_hat.GetLength(1); i++) { u_hat[0, i] = Complex.Conjugate(u_hat[u_hat.GetLength(1) - 1, i]); //Complex.Conjugate( u_hat[N - 1, i]); } u = Matrix.Zeros <double>(K, save_T); for (k = 0; k < K; k++) { Complex[] u_hat_col = ExtractColFromMatrixXcd(u_hat, k, T); u_hat_col = circshift(u_hat_col, (int)(Math.Floor((double)T / 2))); FourierTransform2.FFT(u_hat_col, FourierTransform.Direction.Backward); for (int t = 0; t < save_T; t++) { u[k, t] = u_hat_col[t + T / 4].Real; } } //u_hat = Matrix.Zeros<Complex>(T, K); //double[] result_timevec = Vector.Zeros<double>(save_T); //for (int i = 0; i < save_T; i += 1) //{ // result_timevec[i] = (double)(i + 1) / save_T; //} //for (k = 0; k < K; k++) //{ // Complex[] u_row = ExtractRowFromMatrixXd(u, k, save_T); // FourierTransform2.FFT(u_row,FourierTransform.Direction.Backward); // u_row = circshift(u_row, save_T / 2); // for (int t = 0; t < save_T; t++) // u[k, t] = u_row[t].Real; //} }
public static List <Complex> InverseDiscreteFourierTransformation(Complex[] data) { FourierTransform2.DFT(data, Accord.Math.FourierTransform.Direction.Backward); return(data.OfType <Complex>().ToList()); }
private void VocoderInput(double pitchRate) { var hop = this._windowLength / 2; for (var i = 0; i < this._vocoderInputBuffer.Length; i++) { var destIndex = (hop + i) % this._windowLength; this._fftBuffer[destIndex] = this._vocoderInputBuffer[i] * this._window[i]; } FourierTransform2.FFT(this._fftBuffer, FourierTransform.Direction.Forward); for (var i = 0; i < this._fftBuffer.Length; i++) { this._magnitudeSpectrum[i] = this._fftBuffer[i].Magnitude; this._phaseSpectrum[i] = this._fftBuffer[i].Phase; } // ピッチ変更 //for (var i = 0; i < hop; i++) //{ // var pos = i / pitchRate; // var a = (int)pos; // double newMag; // if (a >= this._windowLength) // { // // 範囲外なので諦める // newMag = 0; // } // else if (a == this._windowLength - 1 || a == pos) // { // newMag = this._magnitudeSpectrum[a]; // } // else // { // // 補間 // newMag = this._magnitudeSpectrum[a] // + (this._magnitudeSpectrum[a + 1] - this._magnitudeSpectrum[a]) // * (pos - a); // } // this._modifiedMagnitudeSpectrum[i] = newMag; // this._modifiedMagnitudeSpectrum[this._windowLength - i - 1] = newMag; //} Array.Copy(this._magnitudeSpectrum, this._modifiedMagnitudeSpectrum, this._windowLength); if (this._isFirstVocoder) { this._isFirstVocoder = false; // 初回 for (var i = 0; i < this._phaseSpectrum.Length; i++) { this._lastPhase[i] = this._phaseSpectrum[i]; this._targetPhase[i] = this._phaseSpectrum[i] + this._omega[i]; } } else { for (var i = 0; i < this._windowLength; i++) { var principleArg = this._phaseSpectrum[i] - this._targetPhase[i]; var unwrappedPhaseDiff = (principleArg + Math.PI) % (-2.0 * Math.PI) + Math.PI; var instantaneousFreq = (this._omega[i] + unwrappedPhaseDiff) / hop; this._lastPhase[i] += instantaneousFreq; this._targetPhase[i] = this._phaseSpectrum[i] + this._omega[i]; } } for (var i = 0; i < this._fftBuffer.Length; i++) { this._fftBuffer[i] = Complex.FromPolarCoordinates(this._modifiedMagnitudeSpectrum[i], this._lastPhase[i]); } FourierTransform2.FFT(this._fftBuffer, FourierTransform.Direction.Backward); for (var i = 0; i < this._vocoderOutputBuffer.Length; i++) { this._vocoderOutputBuffer[i] = (float)this._fftBuffer[(hop + i) % this._windowLength].Real * this._window[i]; } }
private static WavechartBox show(String title, bool hold, params Tuple <Signal, int>[] series) { WavechartBox form = null; Thread formThread = null; AutoResetEvent stopWaitHandle = new AutoResetEvent(false); formThread = new Thread(() => { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Show control in a form form = new WavechartBox(); form.Text = title; form.formThread = formThread; if (!String.IsNullOrEmpty(title)) { form.zedGraphControl.GraphPane.Title.IsVisible = true; form.zedGraphControl.GraphPane.Title.Text = title; } var sequence = new ColorSequenceCollection(series.Length); for (int i = 0; i < series.Length; i++) { var signal = series[i].Item1; int channel = series[i].Item2; ComplexSignal complex = signal as ComplexSignal; if (complex != null && complex.Status != ComplexSignalStatus.Normal) { double[] spectrum = FourierTransform2.GetPowerSpectrum(complex.GetChannel(channel)); double[] frequencies = FourierTransform2.GetFrequencyVector(signal.Length, signal.SampleRate); form.series.Add(new LineItem(i.ToString(), frequencies, spectrum, sequence.GetColor(i), SymbolType.None)); form.zedGraphControl.GraphPane.XAxis.Title.Text = "Frequency"; form.zedGraphControl.GraphPane.YAxis.Title.Text = "Power"; } else { double[] values; if (signal.NumberOfChannels == 1) { values = signal.ToDouble(); } else { ExtractChannel extract = new ExtractChannel(channel); values = extract.Apply(signal).ToDouble(); } form.series.Add(new LineItem(i.ToString(), Vector.Range(0, signal.Length).ToDouble(), values, sequence.GetColor(i), SymbolType.None)); form.zedGraphControl.GraphPane.XAxis.Title.Text = "Time"; form.zedGraphControl.GraphPane.YAxis.Title.Text = "Amplitude"; } } form.zedGraphControl.GraphPane.AxisChange(); stopWaitHandle.Set(); Application.Run(form); }); formThread.SetApartmentState(ApartmentState.STA); formThread.Start(); stopWaitHandle.WaitOne(); if (!hold) { formThread.Join(); } return(form); }
/// <summary> /// Calculates the auto correlation function using Wiener–Khinchin theorem. /// </summary> /// /// <param name="vector"> /// A vector of observations whose AutoCorrelation Function will be calculated. /// It is assumed that the vector is a 1-D array of type double. /// </param> /// <param name="nlag"> /// Number of lags to return autocorrelation for. Integer. /// </param> /// /// <returns> /// Returns a vector of type double giving the autocorrelation function upto given lags. /// </returns> /// public static double[] AutoCorrelationFunction(double[] vector, int nlag) { int nTime = vector.Length; if (nlag < 1) { nlag = nTime; } if (nTime <= 1) { return new double[] { } } ; // padding the length to be the power of 2 to facilitate FFT speed. int newLength = Convert.ToInt32(Math.Pow(2, Math.Ceiling(Math.Log(nTime, 2)))); // define and calculate FFT double VecMean = vector.Mean(); Complex[] Frf = new Complex[newLength]; for (int k = 0; k < newLength; k++) { if (k < nTime) { Frf[k] = new Complex(vector[k] - VecMean, 0); } } FourierTransform2.FFT(Frf, Accord.Math.FourierTransform.Direction.Forward); // calculate inverse(backward) FFT of ( Frf*Conjugate(Frf) ) Complex[] iFTFTj = new Complex[Frf.Length]; for (int k = 0; k < Frf.Length; k++) { Complex FrfConj = Complex.Conjugate(Frf[k]); double RealPart = Frf[k].Real * FrfConj.Real - Frf[k].Imaginary * FrfConj.Imaginary; double ImaginaryPart = Frf[k].Real * FrfConj.Imaginary + Frf[k].Imaginary * FrfConj.Real; iFTFTj[k] = new Complex(RealPart, ImaginaryPart); } FourierTransform2.FFT(iFTFTj, Accord.Math.FourierTransform.Direction.Backward); // calculate ACF, normalized against the first item double normalizer = 1.0; int newlag = nTime < nlag ? nTime : nlag; double[] acf = new double[newlag]; for (int k = 0; k < acf.Length; k++) { acf[k] = iFTFTj[k].Real / (nTime * normalizer); if (k == 0) { normalizer = acf[0]; acf[0] = 1.0; } } return(acf); }
public void LoadForEqualizer(string fileName, List <FrequencyBand> bands) { using (var reader = new WaveFileReader(fileName)) { Samples = new List <float[]>(); var buffer = new byte[reader.Length]; var read = reader.Read(buffer, 0, buffer.Length); var sampleBuffer = new short[read / 2]; Buffer.BlockCopy(buffer, 0, sampleBuffer, 0, read); var filterLength = 33; var windowSize = 512; var samplingFrequency = reader.WaveFormat.SampleRate; var filters = new List <System.Numerics.Complex[]>(); var globalFilterBuffer = new List <short>(); var windowLength = windowSize - filterLength + 1; var windows = sampleBuffer.Length / windowLength; var fourierN = windowLength + filterLength - 1; Points = new List <DataPoint>(); //for (int k = 0; k < 19980; k++) //{ // Points.Add(new DataPoint(k, 0)); //} //double[] x = Enumerable.Repeat(0.0, 1024).ToArray(); //x[0] = 1;// input signal (delta function example) //var y = new List<double>(); // output signal //ParametricEqualizer peq = new ParametricEqualizer(4, 1000, new double[] { 200, 250, 300, 350 }, new double[] { 5, 5, 5, 5 }, new double[] { 9, 9, 9, 9 }, new double[] { 0, 0, 0, 0 }, new double[] { 8, 10, 12, 14 }); //peq.run(x.ToList(), ref y); //for (int i = 0; i < y.Count; i++) //{ // Points.Add(new DataPoint(i, y[i])); //} double[] x = Enumerable.Repeat(0.0, samplingFrequency).ToArray(); x[0] = 1; // input signal (delta function example) var y = new List <double>(); // output signal var peq = new ParametricEqualizer( bands.Count, samplingFrequency, bands.Select(band => (double)band.CenterFrequency).ToArray(), bands.Select(band => (double)band.Width).ToArray(), new double[] { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }, new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, bands.Select(band => (double)band.Scale).ToArray()); peq.Run(x.ToList(), ref y); for (int i = 0; i < y.Count; i++) { Points.Add(new DataPoint(i, y[i])); } //foreach (var band in bands.Take(1)) //{ //var filter = new double[filterLength]; //var f = new Section(band.CenterFrequency, band.Width/4.0, 9, 0, 3 * band.Scale, samplingFrequency); //var test = new List<double>(); //for (int k = 20; k < 20000; k++) //{ // test.Add(1); //} //f.run(test, out var outTest); //for (int k = 0; k < 19980; k++) //{ // Points[k] = new DataPoint(k, Points[k].Y + outTest[k]); //} //for (int i = 0; i < filterLength; i++) //{ // //filter[i] = Math.Sqrt((1 + Math.Pow(i / band.StartFreq, 2)) / //boost above // // (1 + Math.Pow(i / band.StopFreq, 2))) * band.Scale; //attuneate above // //if ((i - (filterLength - 1) / 2) == 0) // //{ // // filter[i] = ((i - (filterLength - 1) / 2.0) * (i - (filterLength - 1) / 2.0) + // // band.CenterFrequency * band.CenterFrequency); // //} // //else // //{ // // filter[i] = ((i - (filterLength - 1) / 2.0) * (i - (filterLength - 1) / 2.0) + band.CenterFrequency * band.CenterFrequency) / (i - (filterLength - 1) / 2.0) * (i - (filterLength - 1) / 2.0) + band.Width * (i - (filterLength - 1) / 2.0) + // // band.CenterFrequency * band.CenterFrequency; // //} //} //for (int i = 0; i < filterLength; i++) //{ // filter[i] *= FastFourierTransform.HammingWindow(i, windowSize); //} //var fourierFilter = filter.Select(d => new System.Numerics.Complex(d, 0)).ToArray(); //fourierFilter = fourierFilter // .Concat(Enumerable.Repeat(new System.Numerics.Complex(0, 0), fourierN - filterLength)).ToArray(); //FourierTransform.FFT(fourierFilter, FourierTransform.Direction.Forward); //filters.Add(fourierFilter); //} var fourierFilter = y.Take(fourierN).ToArray(); var complexPoints = Points.Select(point => new System.Numerics.Complex(point.Y, 0)).ToArray(); FourierTransform2.FFT(complexPoints, FourierTransform.Direction.Forward); int z = 0; Points = complexPoints.Take(complexPoints.Length / 2).Select(complex => new DataPoint(z++ *1000 / 1024.0, complex.Magnitude)).ToList(); for (int w = 0; w < windows; w++) { var samples = sampleBuffer.Skip(windowLength * w).Take(windowLength).ToArray(); samples = samples .Concat(Enumerable.Repeat((short)0, fourierN - windowLength)).ToArray(); var complexSamples = samples.Select(s => new System.Numerics.Complex(s, 0)).ToArray(); FourierTransform.FFT(complexSamples, FourierTransform.Direction.Forward); var multiplied = new System.Numerics.Complex[complexSamples.Length]; for (int i = 0; i < complexSamples.Length; i++) { multiplied[i] = complexSamples[i] * fourierFilter[i]; } FourierTransform.FFT(multiplied, FourierTransform.Direction.Backward); globalFilterBuffer.AddRange(multiplied.Select(complex => (short)(complex.Real * 10))); //var filtered = new short[windowLength + filterLength -1]; //for (int i = filterLength; i < samples.Length - filterLength; i++) //{ // double y = 0; // for (int j = 0; j < filterLength; j++) // { // y += samples[i - j] * filter[j]; // } // filtered[i] = (short) y; //} } Filtered = globalFilterBuffer.ToArray(); } }