public static List <Complex[]> STFT(double[] audio, int hopSize, double[] window) { /** * Short Time Fourier Transform */ int num_blocks = (audio.Length - window.Length) / hopSize; //window too large or stepSize too large to get a single windowed block out of it if (num_blocks < 1) { return(null); } List <Complex[]> ffts = new List <Complex[]>(); Parallel.For(0, num_blocks, windowed_block => { FftSharp.Complex[] buffer = new FftSharp.Complex[window.Length]; int sourceIndex = windowed_block * hopSize; for (int i = 0; i < window.Length; i++) { buffer[i].Real = audio[sourceIndex + i] * window[i] / window.Length; } FftSharp.Transform.FFT(buffer); ffts.Add(buffer); }); return(ffts); }
//Modified to be equivalent to Fourier.STFT code. public Complex[][] Process(double whiteNoiseThreshold = 0) { if (FftsToProcess < 1) { return(null); } int newFftCount = FftsToProcess; Complex[][] newFfts = new Complex[newFftCount][]; Parallel.For(0, newFftCount, newFftIndex => { FftSharp.Complex[] buffer = new FftSharp.Complex[settings.FftSize]; int sourceIndex = newFftIndex * settings.StepSize; for (int i = 0; i < settings.FftSize; i++) { buffer[i].Real = newAudio[sourceIndex + i] * settings.Window[i] / settings.FftSize; } FftSharp.Transform.FFT(buffer); AudioAnalysis.Filters.WhiteNoiseFilter(buffer, whiteNoiseThreshold); newFfts[newFftIndex] = new Complex[settings.FftSize]; for (int i = 0; i < settings.FftSize; i++) { newFfts[newFftIndex][i] = buffer[i]; } }); for (int i = 0; i < newFftCount; i++) { ffts.Add(newFfts[i]); ffts_complex.Add(newFfts[i]); } FftsProcessed += newFfts.Length; newAudio.RemoveRange(0, newFftCount * settings.StepSize); PadOrTrimForFixedWidth(); return(newFfts); }