public void ComputeInverseMatrixUsingLomontTableFFT(Matrix m, int column, ref double[] signal, int winsize, int overlap) { double[] spectrogramWindow = m.GetColumn(column); // extend window with the inverse duplicate array int len = spectrogramWindow.Length; var extendedWindow = new double[len * 2]; Array.Copy(spectrogramWindow, extendedWindow, len); for (int i = 1; i < len; i++) { extendedWindow[len + i] = spectrogramWindow[len - i]; } double[] complexSignal = FFTUtils.DoubleToComplexDouble(extendedWindow); lomonFFT.TableFFT(complexSignal, false); double[] window = win.Window; // multiply by window w/ overlap-add int N = complexSignal.Length / 2; var returnArray = new double[N]; for (int j = 0; j < N; j++) { double re = complexSignal[2 * j] / Math.Sqrt(winsize); //double img = complexSignal[2*j + 1]; returnArray[j] = re * window[j]; // smooth yet another time (also did this when doing FFT) // overlap-add method // scale with 2 just because the volume got so much lower when using a second smoothing filter when reconstrcting signal[j + overlap * column] = signal[j + overlap * column] + returnArray[j]; // * 3; } }
/// <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[][] CreateSpectrogramFFTWLIB_INPLACE(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][]; var signal = new double[fftWindowsSize]; for (int i = 0; i < numberOfSegments; i++) { // apply Hanning Window for (int j = 0; j < fftWindowsSize; j++) { // Weight by Hann Window signal[j] = (double)(windowArray[j] * samples[i * fftOverlap + j]); } // perform the FFT FFTW_FFT_R2R(ref signal, ref signal, fftWindowsSize, FFTMethod.DFT); // get the result double[] complexDout = FFTUtils.HC2C(signal); frames[i] = Abs(complexDout); } return(frames); }
public void ComputeMatrixUsingLomontTableFFT(ref Matrix m, int column, float[] audiodata, int pos) { // apply the window method (e.g HammingWindow, HannWindow etc) win.Apply(ref data, audiodata, pos); double[] complexSignal = FFTUtils.FloatToComplexDouble(data); lomonFFT.TableFFT(complexSignal, true); int row = 0; for (int i = 0; i < complexSignal.Length / 4; i += 2) { double re = complexSignal[2 * i]; double img = complexSignal[2 * i + 1]; m.MatrixData[row][column] = Math.Sqrt((re * re + img * img) * complexSignal.Length / 2); row++; } }
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); }
// seem to the be the fastest FFT? static double[] FFTWLIB(double[] signal) { var complexSignal = FFTUtils.DoubleToComplexDouble(signal); // prepare the input arrays var complexInput = new fftw_complexarray(complexSignal); var complexOutput = new fftw_complexarray(complexSignal.Length / 2); fftw_plan fft = fftw_plan.dft_1d(complexSignal.Length / 2, complexInput, complexOutput, fftw_direction.Forward, fftw_flags.Estimate); // perform the FFT fft.Execute(); // get the result var spectrum_fft_abs = complexOutput.Abs; //Export.ExportCSV("audio_buffer_padded2.csv", signal); //Export.ExportCSV("spectrum_fft_abs2.csv", spectrum_fft_abs2, fftSize); // free up memory complexInput = null; complexOutput = null; return(spectrum_fft_abs); }