static double[] FFTWLIB_INPLACE(double[] signal) { int N = signal.Length; double[] din = signal; var dout = new double[N]; // perform the FFT FFTUtils.FFTW_FFT_R2R(ref din, ref dout, N, FFTUtils.FFTMethod.DFT); // get the result double[] complexDout = FFTUtils.HC2C(dout); var spectrum_fft_abs = FFTUtils.Abs(complexDout); //Export.ExportCSV("audio_buffer_padded.csv", din); //Export.ExportCSV("spectrum_fft_abs.csv", spectrum_fft_abs, fftSize); return(spectrum_fft_abs); }
/// <summary> /// Generate a spectrogram array spaced linearily /// </summary> /// <param name="samples">audio data</param> /// <param name="fftWindowsSize">fft window size</param> /// <param name="fftOverlap">overlap in number of samples (normaly half of the fft window size) [low number = high overlap]</param> /// <returns>spectrogram jagged array</returns> public static double[][] CreateSpectrogramFFTW(float[] samples, int fftWindowsSize, int fftOverlap) { int numberOfSamples = samples.Length; // overlap must be an integer smaller than the window size // half the windows size is quite normal double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); // width of the segment - e.g. split the file into 78 time slots (numberOfSegments) and do analysis on each slot int numberOfSegments = (numberOfSamples - fftWindowsSize) / fftOverlap; var frames = new double[numberOfSegments][]; // even - Re, odd - Img var realSignal = new double[fftWindowsSize]; double lengthSqrt = Math.Sqrt(fftWindowsSize); for (int i = 0; i < numberOfSegments; i++) { // apply Hanning Window for (int j = 0; j < fftWindowsSize; j++) { // Weight by Hann Window realSignal[j] = (double)(windowArray[j] * samples[i * fftOverlap + j]); } // FFT transform for gathering the spectrum var complexOutput = FFTWPaddedFFT(ref realSignal); // 4096 real numbers on input processed by FFTW dft_r2c_1d transform gives // 4096/2+1 = 2049 complex numbers at output // remove the value as FFTW returns one extra complex value not needed var complexFixed = new double[complexOutput.Length - 1]; Array.Copy(complexOutput, complexFixed, complexFixed.Length); // get the result var spectrum_fft_abs = FFTUtils.Abs(complexFixed); frames[i] = spectrum_fft_abs; } return(frames); }