-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
221 lines (178 loc) · 9.55 KB
/
main.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package goorp
import (
"bufio"
"io"
"math"
"math/rand"
)
const echoSizeSamples float64 = 1000.0
func levelWithFading(level, t, fastPeriod, mediumPeriod, longPeriod, extralongPeriod float64) float64 {
return level + 0.4*level*math.Sin(t/extralongPeriod) + 0.3*level*math.Sin(t/longPeriod) + 0.2*level*math.Sin(t/mediumPeriod) + 0.1*level*math.Sin(t/fastPeriod)
}
//Processor ...
type Processor struct {
signalLevelMKV float64
signalFadingFastPeriodRate float64
signalFadingMediumPeriodRate float64
signalFadingLongPeriodRate float64
signalFadingExtralongPeriodRate float64
signalFadingFastPeriodIncreaser float64
signalFadingMediumPeriodIncreaser float64
signalFadingLongPeriodIncreaser float64
signalFadingExtralongPerioIncreaser float64
echoLevelMKV float64
echoFadingFastPeriodRate float64
echoFadingMediumPeriodRate float64
echoFadingLongPeriodRate float64
echoFadingExtralongPeriodRate float64
echoFadingFastPeriodIncreaser float64
echoFadingMediumPeriodIncreaser float64
echoFadingLongPeriodIncreaser float64
echoFadingExtralongPeriodIncreaser float64
bgSignalLevelMKV float64
bgSignalFadingFastPeriodRate float64
bgSignalFadingMediumPeriodRate float64
bgSignalFadingLongPeriodRate float64
bgSignalFadingExtralongPeriodRate float64
bgSignalFadingFastPeriodIncreaser float64
bgSignalFadingMediumPeriodIncreaser float64
bgSignalFadingLongPeriodIncreaser float64
bgSignalFadingExtralongPeriodIncreaser float64
interferenceNoiseLevelMKV float64
interferenceNoiseFadingFastPeriodRate float64
interferenceNoiseFadingMediumPeriodRate float64
interferenceNoiseFadingLongPeriodRate float64
interferenceNoiseFadingExtralongPeriodRate float64
interferenceNoiseFadingFastPeriodIncreaser float64
interferenceNoiseFadingMediumPeriodIncreaser float64
interferenceNoiseFadingLongPeriodIncreaser float64
interferenceNoiseFadingExtralongPeriodIncreaser float64
interferenceNoiseFreqFactorRate float64
interferenceNoiseFreqFactorIncreaser float64
interferenceNoiseFreqFactorAdditional float64
// White (or brown) noise
noiseLevelMKV float64
}
//NewProcessor ...
func NewProcessor() *Processor {
proc := &Processor{
signalLevelMKV: 10.0,
signalFadingFastPeriodRate: 1000,
signalFadingMediumPeriodRate: 15000,
signalFadingLongPeriodRate: 40000,
signalFadingExtralongPeriodRate: 200000,
signalFadingFastPeriodIncreaser: 300,
signalFadingMediumPeriodIncreaser: 17500,
signalFadingLongPeriodIncreaser: 60000,
signalFadingExtralongPerioIncreaser: 150000,
echoLevelMKV: 0.3,
echoFadingFastPeriodRate: 2000,
echoFadingMediumPeriodRate: 7000,
echoFadingLongPeriodRate: 50000,
echoFadingExtralongPeriodRate: 200000,
echoFadingFastPeriodIncreaser: 1500,
echoFadingMediumPeriodIncreaser: 4000,
echoFadingLongPeriodIncreaser: 25000,
echoFadingExtralongPeriodIncreaser: 150000,
bgSignalLevelMKV: 0.2,
bgSignalFadingFastPeriodRate: 2000,
bgSignalFadingMediumPeriodRate: 7000,
bgSignalFadingLongPeriodRate: 50000,
bgSignalFadingExtralongPeriodRate: 200000,
bgSignalFadingFastPeriodIncreaser: 1500,
bgSignalFadingMediumPeriodIncreaser: 4000,
bgSignalFadingLongPeriodIncreaser: 25000,
bgSignalFadingExtralongPeriodIncreaser: 150000,
interferenceNoiseLevelMKV: 0.02,
interferenceNoiseFadingFastPeriodRate: 2000,
interferenceNoiseFadingMediumPeriodRate: 7000,
interferenceNoiseFadingLongPeriodRate: 50000,
interferenceNoiseFadingExtralongPeriodRate: 200000,
interferenceNoiseFadingFastPeriodIncreaser: 1500,
interferenceNoiseFadingMediumPeriodIncreaser: 4000,
interferenceNoiseFadingLongPeriodIncreaser: 25000,
interferenceNoiseFadingExtralongPeriodIncreaser: 150000,
interferenceNoiseFreqFactorRate: 1000,
interferenceNoiseFreqFactorIncreaser: 1.0,
interferenceNoiseFreqFactorAdditional: 3000.0,
noiseLevelMKV: 0.1,
}
return proc
}
//ProcessPipes ...
func (proc Processor) ProcessPipes(mainPipe io.Reader, bgPipe io.Reader, freq int64, outChan chan byte, errChan chan error) {
// Randomize from frequency value
rand.Seed(freq)
// Signal component levels
// Payload signal
signalFadingFastPeriod := math.Mod(rand.Float64(), proc.SignalFadingFastPeriodRate()) + proc.SignalFadingFastPeriodIncreaser()
signalFadingMediumPeriod := math.Mod(rand.Float64(), proc.SignalFadingMediumPeriodRate()) + proc.SignalFadingMediumPeriodIncreaser()
signalFadingLongPeriod := math.Mod(rand.Float64(), proc.SignalFadingLongPeriodRate()) + proc.SignalFadingLongPeriodIncreaser()
signalFadingExtralongPeriod := math.Mod(rand.Float64(), proc.SignalFadingExtralongPeriodRate()) + proc.SignalFadingExtralongPerioIncreaser()
// Payload signal echo
echoFadingFastPeriod := math.Mod(rand.Float64(), proc.EchoFadingFastPeriodRate()) + proc.EchoFadingFastPeriodIncreaser()
echoFadingMediumPeriod := math.Mod(rand.Float64(), proc.EchoFadingMediumPeriodRate()) + proc.EchoFadingMediumPeriodIncreaser()
echoFadingLongPeriod := math.Mod(rand.Float64(), proc.EchoFadingLongPeriodRate()) + proc.EchoFadingLongPeriodIncreaser()
echoFadingExtralongPeriod := math.Mod(rand.Float64(), proc.EchoFadingExtralongPeriodRate()) + proc.EchoFadingExtralongPeriodIncreaser()
// Background signal
bgSignalFadingFastPeriod := math.Mod(rand.Float64(), proc.BgSignalFadingFastPeriodRate()) + proc.BgSignalFadingFastPeriodIncreaser()
bgSignalFadingMediumPeriod := math.Mod(rand.Float64(), proc.BgSignalFadingMediumPeriodRate()) + proc.BgSignalFadingMediumPeriodIncreaser()
bgSignalFadingLongPeriod := math.Mod(rand.Float64(), proc.BgSignalFadingLongPeriodRate()) + proc.BgSignalFadingLongPeriodIncreaser()
bgSignalFadingExtralongPeriod := math.Mod(rand.Float64(), proc.BgSignalFadingExtralongPeriodRate()) + proc.BgSignalFadingExtralongPeriodIncreaser()
// Interference noise
interferenceNoiseFreqFactor := math.Mod(rand.Float64(), proc.InterferenceNoiseFreqFactorRate())/proc.InterferenceNoiseFreqFactorAdditional() + proc.InterferenceNoiseFreqFactorIncreaser()
interferenceNoiseFadingFastPeriod := math.Mod(rand.Float64(), proc.InterferenceNoiseFadingFastPeriodRate()) + proc.InterferenceNoiseFadingFastPeriodIncreaser()
interferenceNoiseFadingMediumPeriod := math.Mod(rand.Float64(), proc.InterferenceNoiseFadingMediumPeriodRate()) + proc.InterferenceNoiseFadingMediumPeriodIncreaser()
interferenceNoiseFadingLongPeriod := math.Mod(rand.Float64(), proc.InterferenceNoiseFadingLongPeriodRate()) + proc.InterferenceNoiseFadingLongPeriodIncreaser()
interferenceNoiseFadingExtralongPeriod := math.Mod(rand.Float64(), proc.InterferenceNoiseFadingExtralongPeriodRate()) + proc.InterferenceNoiseFadingExtralongPeriodIncreaser()
// Signal component values
var signal, echo, bgSignal, noise, noiseSrc, interference float64
// Current levels
var signalCurLevel, echoCurLevel, bgSignalCurLevel, noiseCurLevel, interferenceCurLevel, commonCurLevel, commonSignalSrc float64
// Other vars
var output, prevOutput float64
// Time counter
var timeCounter float64
mainPP := bufio.NewReader(mainPipe)
bgPP := bufio.NewReader(bgPipe)
var echoBuffer [int(echoSizeSamples)]float64
for continueProcessing := true; continueProcessing; {
mainSignalRune, err := mainPP.ReadByte()
if err != nil {
errChan <- ErrMainPipeEnded
continueProcessing = false
}
signal = float64(mainSignalRune)
bgSignalByte, err := bgPP.ReadByte()
if err != nil {
errChan <- ErrBackgroundPipeEnded
continueProcessing = false
}
bgSignal = float64(bgSignalByte)
echo = echoBuffer[int(math.Mod(timeCounter, echoSizeSamples))]
interference = 100 + 100*math.Sin(timeCounter/interferenceNoiseFreqFactor)
noiseSrc = math.Mod(rand.Float64(), 256)
noise = 0.5*noise + 0.5*noiseSrc
// Current levels
signalCurLevel = levelWithFading(proc.SignalLevelMKV(), timeCounter, signalFadingFastPeriod, signalFadingMediumPeriod, signalFadingLongPeriod, signalFadingExtralongPeriod)
echoCurLevel = levelWithFading(proc.EchoLevelMKV(), timeCounter, echoFadingFastPeriod, echoFadingMediumPeriod, echoFadingLongPeriod, echoFadingExtralongPeriod)
bgSignalCurLevel = levelWithFading(proc.BgSignalLevelMKV(), timeCounter, bgSignalFadingFastPeriod, bgSignalFadingMediumPeriod, bgSignalFadingLongPeriod, bgSignalFadingExtralongPeriod)
noiseCurLevel = proc.NoiseLevelMKV()
interferenceCurLevel = levelWithFading(proc.InterferenceNoiseLevelMKV(), timeCounter, interferenceNoiseFadingFastPeriod, interferenceNoiseFadingMediumPeriod, interferenceNoiseFadingLongPeriod, interferenceNoiseFadingExtralongPeriod)
// Common level
commonCurLevel = signalCurLevel + echoCurLevel + bgSignalCurLevel + noiseCurLevel + interferenceCurLevel
// Common signal
commonSignalSrc = signal*signalCurLevel + echo*echoCurLevel + bgSignal*bgSignalCurLevel + noise*noiseCurLevel + interference*interferenceCurLevel
// Output with AGC
output = commonSignalSrc / commonCurLevel
outputPrepared := 0.5*output + 0.5*prevOutput
outChan <- byte(outputPrepared)
echoBuffer[int(math.Mod(timeCounter, echoSizeSamples))] = signal
prevOutput = output
if (math.MaxFloat64 - echoSizeSamples) < timeCounter {
timeCounter = 0
}
timeCounter++
}
}
//| oggenc -Q -r -B 8 -R 8000 -C 1 - -o - | ezstream -c /radio/config/play-to-stream-vorbis-${RADIO_FREQ}am.xml &