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());
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        public override void FFT(bool forward)
        {
            data.CopyTo(copy, 0);

            FourierTransform2.FFT(copy, forward ?
                                  FourierTransform.Direction.Forward :
                                  FourierTransform.Direction.Backward);
        }
Exemple #5
0
 /// <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;
     }
 }
Exemple #6
0
        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}");
            }
        }
Exemple #7
0
        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));
        }
Exemple #9
0
        /// <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));
            }
        }
Exemple #10
0
        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);
        }
Exemple #14
0
        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);
        }
Exemple #16
0
        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)));
        }
Exemple #17
0
 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;
         }
     }
 }
Exemple #18
0
        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);
        }
Exemple #19
0
        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;
        }
Exemple #21
0
        /// <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);
        }
Exemple #24
0
        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);
        }
Exemple #25
0
        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;
            //}
        }
Exemple #26
0
        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];
            }
        }
Exemple #28
0
        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);
        }
Exemple #29
0
        /// <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);
        }
Exemple #30
0
        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();
            }
        }