package dsp import ( "math" "math/cmplx" ) // FFT computes the discrete Fourier transform of x (in-place, radix-2). // len(x) must be a power of 2. func FFT(x []complex128) { n := len(x) if n <= 1 { return } // Bit-reversal permutation j := 0 for i := 1; i < n; i++ { bit := n >> 1 for j&bit != 0 { j ^= bit bit >>= 1 } j ^= bit if i < j { x[i], x[j] = x[j], x[i] } } // Cooley-Tukey butterfly for size := 2; size <= n; size <<= 1 { half := size >> 1 wn := cmplx.Exp(complex(0, -2*math.Pi/float64(size))) for start := 0; start < n; start += size { w := complex(1, 0) for k := 0; k < half; k++ { u := x[start+k] v := x[start+k+half] * w x[start+k] = u + v x[start+k+half] = u - v w *= wn } } } } // IFFT computes the inverse DFT of x (in-place). func IFFT(x []complex128) { n := len(x) // Conjugate, FFT, conjugate, scale for i := range x { x[i] = cmplx.Conj(x[i]) } FFT(x) scale := 1.0 / float64(n) for i := range x { x[i] = cmplx.Conj(x[i]) * complex(scale, 0) } } // HannWindow fills w with a Hann window of length n. func HannWindow(w []float64) { n := len(w) for i := range w { w[i] = 0.5 * (1.0 - math.Cos(2*math.Pi*float64(i)/float64(n))) } }