public static Complex ComputeAt(Complex x, Vector<float> coeffs) { Complex val = new Complex(coeffs[coeffs.Count - 1], 0.0f); Complex xn = x; for(int c = coeffs.Count - 2; c >= 0; --c) { val = new Complex(val.Real + coeffs.At(c) * xn.Real, val.Imaginary + coeffs.At(c) * xn.Imaginary); xn *= x; } return val; }
public Complex At(Complex x) { Complex val = new Complex(Coefficents.At(Rank), 0.0f); Complex xn = x; for(int c = Rank - 1; c >= 0; --c) { val = new Complex(val.Real + Coefficents.At(c) * xn.Real, val.Imaginary + Coefficents.At(c) * xn.Imaginary); xn *= x; } return val; }
private double[] LowPassFilter(double[] pcm, double cutOffFrequency = 500, double sampleRate = 8000) { // it really should be a power of 2 int fft_size = pcm.Length; // create a complex data object we will use to shuffle data around MathNet.Numerics.Complex32[] complex = new MathNet.Numerics.Complex32[fft_size]; // prepare the windowing function int windowSize = 1000; double[] window = new double[pcm.Length]; for (int i = 0; i < window.Length; i++) { if (i < windowSize) { int distanceFromEdge = i; window[i] = (double)distanceFromEdge / windowSize; } else if (i > window.Length - windowSize) { int distanceFromEdge = window.Length - i; window[i] = (double)distanceFromEdge / windowSize; } else { window[i] = 1; } } // load original PCM data into the complex array for (int i = 0; i < fft_size; i++) { float val = (float)(pcm[i] * window[i]); complex[i] = new MathNet.Numerics.Complex32(val, 0); } // perform the forward FFT MathNet.Numerics.IntegralTransforms.Fourier.Forward(complex); // blank-out the high frequency stuff for (int i = 0; i < fft_size / 2; i++) { double freq = (double)(i * sampleRate * 2) / fft_size; if (i == fft_size / 2 - 1) { System.Console.WriteLine(freq); } if (freq < cutOffFrequency) { continue; } complex[i] = new MathNet.Numerics.Complex32(0, 0); complex[fft_size - i - 1] = new MathNet.Numerics.Complex32(0, 0); } // perform the inverse FFT MathNet.Numerics.IntegralTransforms.Fourier.Inverse(complex); // extract the real component into the original PCM array and return it for (int i = 0; i < fft_size; i++) { pcm[i] = complex[i].Real; } return(pcm); }