|
@@ -9,7 +9,7 @@
|
9
|
9
|
// the Free Software Foundation; either version 2.1 of the License, or (at
|
10
|
10
|
// your option) any later version.
|
11
|
11
|
|
12
|
|
-package openbaudot
|
|
12
|
+package gobaudot
|
13
|
13
|
|
14
|
14
|
import "math"
|
15
|
15
|
|
|
@@ -18,58 +18,70 @@ type dsp struct {
|
18
|
18
|
demTotal float64 // current energy output value
|
19
|
19
|
lpfOrder int // LPFOrder Low pass filter order
|
20
|
20
|
minThresh float64 // MinThresh ratio for vaild signal
|
21
|
|
- f1 *bandPass
|
22
|
|
- f0 *bandPass
|
23
|
|
- beta float64
|
24
|
|
- meter0 float64
|
25
|
|
- meter1 float64
|
26
|
|
- meter2 float64
|
27
|
|
-
|
28
|
|
- carrierDetect bool
|
29
|
|
- oneTone bool
|
30
|
|
- zeroTone bool
|
31
|
|
-
|
32
|
|
- lpfc *lpf
|
|
21
|
+
|
|
22
|
+ meter0 float64
|
|
23
|
+ meter1 float64
|
|
24
|
+ meter2 float64
|
|
25
|
+
|
|
26
|
+ bpfMark *bpf // mark bandpass filter
|
|
27
|
+ bpfSpace *bpf // space bandpass filter
|
|
28
|
+ lpfDem *lpf //
|
33
|
29
|
lpfTotal *lpf
|
34
|
30
|
|
35
|
31
|
r float64
|
36
|
32
|
}
|
37
|
33
|
|
38
|
|
-func newDsp(oneF, zeroF, sampleRate int) *dsp {
|
|
34
|
+func newDsp(markF, spaceF, sampleRate int) *dsp {
|
39
|
35
|
|
40
|
|
- lfpOrder := 20
|
41
|
|
-
|
42
|
|
- beta := .95
|
|
36
|
+ const (
|
|
37
|
+ lfpOrder = 20
|
|
38
|
+ beta = .95
|
|
39
|
+ minThresh = 3
|
|
40
|
+ )
|
43
|
41
|
|
44
|
42
|
return &dsp{
|
45
|
|
- // demLpfIn: make([]float64, lfpOrder),
|
46
|
|
- // demTotalIn: make([]float64, lfpOrder),
|
47
|
43
|
lpfOrder: lfpOrder,
|
48
|
|
- minThresh: 3,
|
49
|
|
- f1: newBandPass(oneF, sampleRate, beta),
|
50
|
|
- f0: newBandPass(zeroF, sampleRate, beta),
|
51
|
|
- lpfc: newLpf(lfpOrder),
|
|
44
|
+ minThresh: minThresh,
|
|
45
|
+ bpfMark: newBandPass(markF, sampleRate, beta),
|
|
46
|
+ bpfSpace: newBandPass(spaceF, sampleRate, beta),
|
|
47
|
+ lpfDem: newLpf(lfpOrder),
|
52
|
48
|
lpfTotal: newLpf(lfpOrder),
|
53
|
49
|
}
|
54
|
50
|
}
|
|
51
|
+
|
|
52
|
+func (d *dsp) demod(sam float64) {
|
|
53
|
+
|
|
54
|
+ // The demodulator is structured as a pair of band pass filters tuned to
|
|
55
|
+ // the mark and space frequencies. The output of each is 'rectified' and
|
|
56
|
+ // combined, and low pass filtered to produce a signal that goes positive
|
|
57
|
+ // for mark and negative for space.
|
|
58
|
+ mark := d.bpfMark.update(sam)
|
|
59
|
+ space := d.bpfSpace.update(sam)
|
|
60
|
+
|
|
61
|
+ d.demLpf = d.lpfDem.update(math.Abs(mark) - math.Abs(space))
|
|
62
|
+
|
|
63
|
+ d.demTotal = d.lpfTotal.update(math.Abs(sam))
|
|
64
|
+
|
|
65
|
+}
|
|
66
|
+
|
55
|
67
|
func (d *dsp) edgeDetected() bool {
|
56
|
|
- return d.demLpf > d.minThresh*d.demTotal
|
|
68
|
+ return math.Abs(d.demLpf) > d.demTotal*d.minThresh
|
57
|
69
|
}
|
58
|
70
|
|
59
|
71
|
func (d *dsp) carrier() bool {
|
60
|
|
- return d.carrierDetect
|
|
72
|
+ return math.Abs(d.demLpf) > d.demTotal*d.minThresh
|
61
|
73
|
}
|
62
|
74
|
|
63
|
75
|
func (d *dsp) level() (float64, float64, float64) {
|
64
|
76
|
return d.meter0, d.meter1, d.meter2
|
65
|
77
|
}
|
66
|
78
|
|
67
|
|
-func (d *dsp) onePresent() bool {
|
68
|
|
- return d.oneTone
|
|
79
|
+func (d *dsp) mark() bool {
|
|
80
|
+ return d.demLpf > d.minThresh*d.demTotal && math.Abs(d.demLpf) > d.demTotal*d.minThresh
|
69
|
81
|
}
|
70
|
82
|
|
71
|
|
-func (d *dsp) zeroPresent() bool {
|
72
|
|
- return d.zeroTone
|
|
83
|
+func (d *dsp) space() bool {
|
|
84
|
+ return -1*d.demLpf > d.minThresh*d.demTotal && math.Abs(d.demLpf) > d.demTotal*d.minThresh
|
73
|
85
|
}
|
74
|
86
|
|
75
|
87
|
type lpf struct {
|
|
@@ -84,55 +96,32 @@ func newLpf(size int) *lpf {
|
84
|
96
|
}
|
85
|
97
|
|
86
|
98
|
func (l *lpf) update(v float64) float64 {
|
87
|
|
-
|
88
|
|
- o := l.x[0]
|
|
99
|
+ l.t -= l.x[0]
|
|
100
|
+ l.t += v
|
89
|
101
|
l.x = append(l.x, v)
|
90
|
102
|
l.x = l.x[1:]
|
91
|
103
|
|
92
|
|
- l.t -= o
|
93
|
|
- l.t += v
|
94
|
|
-
|
95
|
104
|
return l.t
|
96
|
105
|
}
|
97
|
106
|
|
98
|
|
-type bandPass struct {
|
|
107
|
+type bpf struct {
|
99
|
108
|
dem0 float64
|
100
|
109
|
dem1 float64
|
101
|
110
|
w float64
|
102
|
111
|
beta float64
|
103
|
112
|
}
|
104
|
113
|
|
105
|
|
-func newBandPass(fc int, fs int, beta float64) *bandPass {
|
106
|
|
- f := new(bandPass)
|
|
114
|
+func newBandPass(fc int, fs int, beta float64) *bpf {
|
|
115
|
+ f := new(bpf)
|
107
|
116
|
f.beta = beta
|
108
|
117
|
f.w = (2 * math.Pi * float64(fc) / float64(fs))
|
109
|
118
|
|
110
|
|
- // fmt.Println("fc", fc, "fs", fs, f.beta, f.w)
|
111
|
119
|
return f
|
112
|
120
|
}
|
113
|
121
|
|
114
|
|
-func (f *bandPass) update(v float64) float64 {
|
|
122
|
+func (f *bpf) update(v float64) float64 {
|
115
|
123
|
n := v + 2.0*math.Cos(f.w)*f.beta*f.dem0 - f.beta*f.beta*f.dem1
|
116
|
124
|
f.dem1 = f.dem0
|
117
|
125
|
f.dem0 = n
|
118
|
126
|
return n
|
119
|
127
|
}
|
120
|
|
-
|
121
|
|
-func (d *dsp) demod(sam float64) {
|
122
|
|
-
|
123
|
|
- var one float64
|
124
|
|
- one = d.f1.update(sam)
|
125
|
|
-
|
126
|
|
- var zero float64
|
127
|
|
- zero = d.f0.update(sam)
|
128
|
|
-
|
129
|
|
- d.demLpf = d.lpfc.update(math.Abs(one) - math.Abs(zero))
|
130
|
|
-
|
131
|
|
- d.demTotal = d.lpfTotal.update(math.Abs(sam))
|
132
|
|
-
|
133
|
|
- d.carrierDetect = math.Abs(d.demLpf) > d.demTotal*d.minThresh
|
134
|
|
-
|
135
|
|
- d.oneTone = d.demLpf > d.minThresh*d.demTotal && d.carrierDetect
|
136
|
|
- d.zeroTone = -1*d.demLpf > d.minThresh*d.demTotal && d.carrierDetect
|
137
|
|
-
|
138
|
|
-}
|