forked from DylanMeeus/GoAudio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dft.go
64 lines (51 loc) 路 1.34 KB
/
dft.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package math
import (
"github.com/DylanMeeus/GoAudio/wave"
"math"
"math/cmplx"
)
const (
tau = 2. * math.Pi
)
// DFT is a discrete fourier transformation on the input frames
// DEPRECATED
// Please use FFT unless you are sure you want this one..
func DFT(input []wave.Frame) []complex128 {
N := len(input)
output := make([]complex128, len(input))
reals := make([]float64, len(input))
imgs := make([]float64, len(input))
for i, frame := range input {
for n := 0; n < N; n++ {
reals[i] += float64(frame) * math.Cos(float64(i*n)*tau/float64(N))
imgs[i] += float64(frame) * math.Sin(float64(i*n)*tau/float64(N))
}
reals[i] /= float64(N)
imgs[i] /= float64(N)
}
for i := 0; i < len(reals); i++ {
output[i] = complex(reals[i], imgs[i])
}
return output
}
// HFFT mutates freqs!
func HFFT(input []wave.Frame, freqs []complex128, n, step int) {
if n == 1 {
freqs[0] = complex(input[0], 0)
return
}
h := n / 2
HFFT(input, freqs, h, 2*step)
HFFT(input[step:], freqs[h:], h, 2*step)
for k := 0; k < h; k++ {
a := -2 * math.Pi * float64(k) * float64(n)
e := cmplx.Rect(1, a) * freqs[k+h]
freqs[k], freqs[k+h] = freqs[k]+e, freqs[k]-e
}
}
// FFT (Fast Fourier Transform) implementation
func FFT(input []wave.Frame) []complex128 {
freqs := make([]complex128, len(input))
HFFT(input, freqs, len(input), 1)
return freqs
}