-
Notifications
You must be signed in to change notification settings - Fork 7
/
frequency.go
95 lines (72 loc) · 1.91 KB
/
frequency.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package dsp
import (
"fmt"
fft2 "github.com/mjibson/go-dsp/fft"
"math/cmplx"
)
type FrequencySpectrum struct {
// Store the frequency spectrum values
Spectrum []float64
// Store the frequencies used
Frequencies []float64
}
func (s *FrequencySpectrum) String() string {
if s.Spectrum != nil && s.Frequencies != nil {
return fmt.Sprintf("Length: %v, Spectrum: 0Hz - %.1fHz", len(s.Spectrum), s.Frequencies[len(s.Frequencies)-1])
}
return "No spectrum or frequencies"
}
// FrequencySpectrum calculates the frequency spectrum of the signal.
func (s *Signal) FrequencySpectrum() (*FrequencySpectrum, error) {
// Apply the FFT on the signal to get the frequency components
fft := fft2.FFTReal(s.Signal)
// Compute the two sided spectrum
var spectrum2 []float64
length := float64(len(s.Signal))
for i := range fft {
// Get the absolute value since the fft is a complex value with both real and imaginary parts
spectrum2 = append(spectrum2, cmplx.Abs(fft[i])/length)
}
// Look at the one sided spectrum
spectrum1 := spectrum2[0 : len(spectrum2)/2]
for i := range spectrum1 {
spectrum1[i] = spectrum1[i] * 2
}
var frequencies []float64
spectrumLength := float64(len(spectrum2))
for i := range spectrum1 {
// Calculate which frequencies the spectrum contains
frequencies = append(frequencies, float64(i)*s.SampleRate/spectrumLength)
}
return &FrequencySpectrum{
Spectrum: spectrum1,
Frequencies: frequencies,
}, nil
}
func (s *FrequencySpectrum) Length() int {
return len(s.Spectrum)
}
func (s *FrequencySpectrum) Min() float64 {
if len(s.Spectrum) == 0 {
return 0
}
min := s.Spectrum[0]
for i := range s.Spectrum {
if s.Spectrum[i] < min {
min = s.Spectrum[i]
}
}
return min
}
func (s *FrequencySpectrum) Max() float64 {
if len(s.Spectrum) == 0 {
return 0
}
max := s.Spectrum[0]
for i := range s.Spectrum {
if s.Spectrum[i] > max {
max = s.Spectrum[i]
}
}
return max
}