// Compute the spectrogram of a signal with window width nfft and overlap // percentage overlap. func Compute(signal []float64, nfft int, overlap float64) Spectrogram { spectra := make([][]complex128, 0) start := 0 end := start + nfft off := int((1 - overlap) * float64(nfft)) // pre-compute the window function window := window.Hamming(nfft) // pre-allocate buffer to hold window * signal windowed := make([]float64, nfft) for end < len(signal) { for i, s := range signal[start:end] { windowed[i] = s * window[i] } spectrum := fft.FFTReal(windowed) // FIXME: memory is still used for the entire spectrum since the GC doesn't // understand and can't free internal and partial pointers, to free it must // do a copy. If this spectrum persists for a while then we should do a // copy(). spectra = append(spectra, spectrum[0:len(spectrum)/2]) start += off end += off } spectrogram := Spectrogram{spectra, nil} return spectrogram }
// ApplyHamming applies a hamming filter to each column func ApplyHamming(x [][]float64) { segments, size := len(x), len(x[0]) hamming := window.Hamming(size) for i := 0; i < segments; i++ { for j := 0; j < size; j++ { x[i][j] = x[i][j] * hamming[j] } } }