/// <summary> /// Method for computing direct STFT of a signal block. /// STFT (spectrogram) is essentially the list of spectra in time. /// </summary> /// <param name="samples">The samples of signal</param> /// <returns>STFT of the signal</returns> public List <Tuple <float[], float[]> > Direct(float[] samples) { // pre-allocate memory: var len = (samples.Length - _windowSize) / _hopSize; var stft = new List <Tuple <float[], float[]> >(); for (var i = 0; i <= len; i++) { stft.Add(new Tuple <float[], float[]>(new float[_fftSize], new float[_fftSize])); } // stft: var windowedBuffer = new float[_windowSize]; for (int pos = 0, i = 0; pos + _windowSize < samples.Length; pos += _hopSize, i++) { samples.FastCopyTo(windowedBuffer, _windowSize, pos); if (_window != WindowTypes.Rectangular) { windowedBuffer.ApplyWindow(_windowSamples); } _fft.Direct(windowedBuffer, stft[i].Item1, stft[i].Item2); } return(stft); }
/// <summary> /// Method for computing direct STFT of a signal block. /// STFT (spectrogram) is essentially the list of spectra in time. /// </summary> /// <param name="samples">The samples of signal</param> /// <returns>STFT of the signal</returns> public List <(float[], float[])> Direct(float[] samples) { // pre-allocate memory: var len = (samples.Length - _windowSize) / _hopSize; var stft = new List <(float[], float[])>(len + 1); for (var i = 0; i <= len; i++) { stft.Add((new float[_fftSize], new float[_fftSize])); } // stft: var windowedBuffer = new float[_fftSize]; for (int pos = 0, i = 0; pos + _windowSize < samples.Length; pos += _hopSize, i++) { samples.FastCopyTo(windowedBuffer, _windowSize, pos); windowedBuffer.ApplyWindow(_windowSamples); var(re, im) = stft[i]; _fft.Direct(windowedBuffer, re, im); } return(stft); }
/// <summary> /// Method for computing direct STFT of a signal block. /// STFT (spectrogram) is essentially the list of spectra in time. /// </summary> /// <param name="input">Samples of input signal</param> /// <returns>STFT of the signal</returns> public List <(float[], float[])> Direct(float[] input) { // pre-allocate memory: var len = (input.Length - _windowSize) / _hopSize + 1; var stft = new List <(float[], float[])>(len); for (var i = 0; i < len; i++) { stft.Add((new float[_fftSize], new float[_fftSize])); } // stft: var windowedBuffer = new float[_fftSize]; var pos = 0; for (var i = 0; i < len; pos += _hopSize, i++) { input.FastCopyTo(windowedBuffer, _windowSize, pos); windowedBuffer.ApplyWindow(_windowSamples); var(re, im) = stft[i]; _fft.Direct(windowedBuffer, re, im); } // last (incomplete) frame: stft.Add((new float[_fftSize], new float[_fftSize])); Array.Clear(windowedBuffer, 0, _fftSize); input.FastCopyTo(windowedBuffer, input.Length - pos, pos); windowedBuffer.ApplyWindow(_windowSamples); var(lre, lim) = stft.Last(); _fft.Direct(windowedBuffer, lre, lim); return(stft); }
/// <summary> /// Does Fast Mellin Transform. /// </summary> /// <param name="input">Input array of samples</param> /// <param name="outRe">Output array of real parts</param> /// <param name="outIm">Output array of imaginary parts</param> public void Direct(float[] input, float[] outRe, float[] outIm) { MathUtils.InterpolateLinear(_linScale, input, _expScale, outRe); for (var i = 0; i < outRe.Length; i++) { outRe[i] *= (float)Math.Pow(_expScale[i], _beta); outIm[i] = 0; } _fft.Direct(outRe, outRe, outIm); }