forked from fogleman/nes
/
filter.go
57 lines (49 loc) · 1.05 KB
/
filter.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
package nes
import "math"
type Filter interface {
Step(x float32) float32
}
// First order filters are defined by the following parameters.
// y[n] = B0*x[n] + B1*x[n-1] - A1*y[n-1]
type FirstOrderFilter struct {
B0 float32
B1 float32
A1 float32
prevX float32
prevY float32
}
func (f *FirstOrderFilter) Step(x float32) float32 {
y := f.B0*x + f.B1*f.prevX - f.A1*f.prevY
f.prevY = y
f.prevX = x
return y
}
// sampleRate: samples per second
// cutoffFreq: oscillations per second
func LowPassFilter(sampleRate float32, cutoffFreq float32) Filter {
c := sampleRate / math.Pi / cutoffFreq
a0i := 1 / (1 + c)
return &FirstOrderFilter{
B0: a0i,
B1: a0i,
A1: (1 - c) * a0i,
}
}
func HighPassFilter(sampleRate float32, cutoffFreq float32) Filter {
c := sampleRate / math.Pi / cutoffFreq
a0i := 1 / (1 + c)
return &FirstOrderFilter{
B0: c * a0i,
B1: -c * a0i,
A1: (1 - c) * a0i,
}
}
type FilterChain []Filter
func (fc FilterChain) Step(x float32) float32 {
if fc != nil {
for i := range fc {
x = fc[i].Step(x)
}
}
return x
}