/// <summary> /// Create log-spectrogram (spaced according to manager's parameters) /// </summary> /// <param name = "proxy">Proxy used in generating the spectrogram</param> /// <param name = "filename">Filename to be processed</param> /// <param name = "milliseconds">Milliseconds to be analyzed</param> /// <param name = "startmilliseconds">Starting point</param> /// <returns>Logarithmically spaced bins within the power spectrum</returns> public float[][] CreateLogSpectrogram(IAudio proxy, string filename, int milliseconds, int startmilliseconds) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = proxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); //NormalizeInPlace(samples); int overlap = Overlap; int fftWindowsSize = WdftSize; double[] windowArray = FFTWindowFunctions.GetWindowFunction(FFTWindowFunctions.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) (_windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); frames[i] = ExtractLogBins(complexSignal); } return(frames); }
/// <summary> /// Create spectrogram of the input file /// </summary> /// <param name = "proxy">Proxy used to read from file</param> /// <param name = "filename">Filename</param> /// <param name = "milliseconds">Milliseconds to process</param> /// <param name = "startmilliseconds">Starting point of the processing</param> /// <returns>Spectrogram</returns> public float[][] CreateSpectrogram(IAudio proxy, string filename, int milliseconds, int startmilliseconds, bool doNormalise) { //read 5512 Hz, Mono, PCM, with a specific proxy float[] samples = proxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds); if (doNormalise) { NormalizeInPlace(samples); } int overlap = Overlap; int fftWindowsSize = WdftSize; // aka N = FFT Length double[] windowArray = FFTWindowFunctions.GetWindowFunction(FFTWindowFunctions.HANNING, fftWindowsSize); int width = (samples.Length - fftWindowsSize) / overlap; /*width of the image*/ float[][] frames = new float[width][]; float[] complexSignal = new float[2 * fftWindowsSize]; /*even - Re, odd - Img*/ for (int i = 0; i < width; i++) { //take 371 ms each 11.6 ms (2048 samples each 64 samples) // apply Hanning Window for (int j = 0; j < fftWindowsSize /*2048*/; j++) { // Weight by Hann Window complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]); //complexSignal[2*j] = (float) ((4.0/(fftWindowsSize - 1)) * windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/ complexSignal[2 * j + 1] = 0; // need to clear out as fft modifies buffer } //FFT transform for gathering the spectrum Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward); float[] band = new float[fftWindowsSize / 2 + 1]; for (int j = 0; j < fftWindowsSize / 2 + 1; j++) { double re = complexSignal[2 * j]; double img = complexSignal[2 * j + 1]; //double img = 0.0; // TODO: Zero out the imaginary component (phase) ? / need to clear out as fft modifies buffer band[j] = (float)Math.Sqrt(re * re + img * img); } frames[i] = band; } return(frames); }