public static Complex[] padded_FFT(ref double[] @in) { Debug.Assert(@in.Length > 0); int n = @in.Length; int padded = n > 256 ? Util.NextLowPrimes(n) : n; Array.Resize <double>(ref @in, padded); // 4096 real numbers on input processed by FFTW dft_r2c_1d transform gives // 4096/2+1 = 2049 complex numbers at output // prepare the input arrays var fftwInput = new FFTW.DoubleArray(@in); int complexSize = (padded >> 1) + 1; // this is the same as (padded / 2 + 1); var fftwOutput = new FFTW.ComplexArray(complexSize); FFTW.ForwardTransform(fftwInput, fftwOutput); Array.Resize <double>(ref @in, n); // free up memory GC.Collect(); return(FFTUtils.ComplexDoubleToComplex(fftwOutput.ComplexValues)); }
public static double[] padded_IFFT(ref Complex[] @in, bool doProperScaling=false) { Debug.Assert(@in.Length > 1); int originalLength = @in.Length; int n = (@in.Length - 1) * 2; int padded = n > 256 ? Util.NextLowPrimes(n) : n; Array.Resize<Complex>(ref @in, padded / 2 + 1); // prepare the input arrays var complexDouble = FFTUtils.ComplexToComplexDouble(@in); var fftwBackwardInput = new FFTW.ComplexArray(complexDouble); var fftwBackwardOutput = new FFTW.DoubleArray(padded); // this method needs that the backwards transform uses the output.length as it's N // i.e. FFTW.dft_c2r_1d(output.Length, input.Handle, output.Handle, Flags.Estimate); FFTW.BackwardTransform(fftwBackwardInput, fftwBackwardOutput); double[] @out = null; if (doProperScaling) { @out = fftwBackwardOutput.ValuesDivedByN; } else { // in the original method it wasn't scaled correctly (meaning ValuesDivedByN) @out = fftwBackwardOutput.Values; } Array.Resize<Complex>(ref @in, n / 2 + 1); // free up memory GC.Collect(); return @out; }
private double[] MagnitudeSpectrum(float[] frame) { // prepare the input arrays FFTW.DoubleArray fftwInput = new FFTW.DoubleArray(MathUtils.FloatToDouble(frame)); int complexSize = (frame.Length >> 1) + 1; FFTW.ComplexArray fftwOutput = new FFTW.ComplexArray(complexSize); FFTW.ForwardTransform(fftwInput, fftwOutput); double[] magSpectrum = fftwOutput.Abs; /* * double[] magSpectrum = new double[frame.Length]; * * // calculate FFT for current frame * fft.ComputeFFT(frame); * * // System.err.println("FFT SUCCEED"); * // calculate magnitude spectrum * for (int k = 0; k < frame.Length; k++) * { * magSpectrum[k] = Math.Sqrt(fft.real[k] * fft.real[k] + fft.imag[k] * fft.imag[k]); * } */ return(magSpectrum); }
public static Complex[] padded_FFT(ref double[] @in) { Debug.Assert(@in.Length > 0); int n = @in.Length; int padded = n > 256 ? Util.NextLowPrimes(n) : n; Array.Resize<double>(ref @in, padded); // 4096 real numbers on input processed by FFTW dft_r2c_1d transform gives // 4096/2+1 = 2049 complex numbers at output // prepare the input arrays var fftwInput = new FFTW.DoubleArray(@in); int complexSize = (padded >> 1) + 1; // this is the same as (padded / 2 + 1); var fftwOutput = new FFTW.ComplexArray(complexSize); FFTW.ForwardTransform(fftwInput, fftwOutput); Array.Resize<double>(ref @in, n); // free up memory GC.Collect(); return FFTUtils.ComplexDoubleToComplex(fftwOutput.ComplexValues); }
public static double[] padded_IFFT(ref Complex[] @in, bool doProperScaling = false) { Debug.Assert(@in.Length > 1); int originalLength = @in.Length; int n = (@in.Length - 1) * 2; int padded = n > 256 ? Util.NextLowPrimes(n) : n; Array.Resize <Complex>(ref @in, padded / 2 + 1); // prepare the input arrays var complexDouble = FFTUtils.ComplexToComplexDouble(@in); var fftwBackwardInput = new FFTW.ComplexArray(complexDouble); var fftwBackwardOutput = new FFTW.DoubleArray(padded); // this method needs that the backwards transform uses the output.length as it's N // i.e. FFTW.dft_c2r_1d(output.Length, input.Handle, output.Handle, Flags.Estimate); FFTW.BackwardTransform(fftwBackwardInput, fftwBackwardOutput); double[] @out = null; if (doProperScaling) { @out = fftwBackwardOutput.ValuesDivedByN; } else { // in the original method it wasn't scaled correctly (meaning ValuesDivedByN) @out = fftwBackwardOutput.Values; } Array.Resize <Complex>(ref @in, n / 2 + 1); // free up memory GC.Collect(); return(@out); }