forked from noriah/catnip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
visulizer.go
78 lines (59 loc) · 1.67 KB
/
visulizer.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
package main
import (
"math"
"github.com/noriah/catnip/dsp"
"github.com/noriah/catnip/dsp/window"
"github.com/noriah/catnip/fft"
"github.com/noriah/catnip/graphic"
"github.com/noriah/catnip/input"
"github.com/noriah/catnip/util"
)
type visualizer struct {
cfg *Config
slowWindow util.MovingWindow
fastWindow util.MovingWindow
fftBuf []complex128
inputBufs [][]input.Sample
barBufs [][]float64
plans []*fft.Plan
spectrum dsp.Spectrum
bars int
display graphic.Display
}
// Process runs one draw refresh with the visualizer on the termbox screen.
func (vis *visualizer) Process() {
if n := vis.display.Bars(vis.cfg.ChannelCount); n != vis.bars {
vis.bars = vis.spectrum.Recalculate(n)
}
var peak float64
for idx := range vis.barBufs {
window.Lanczos(vis.inputBufs[idx])
vis.plans[idx].Execute()
buf := vis.barBufs[idx]
for bIdx := range buf[:vis.bars] {
v := vis.spectrum.ProcessBin(idx, bIdx, vis.fftBuf)
if peak < v {
peak = v
}
buf[bIdx] = v
}
}
var scale = 1.0
// do some scaling if we are above the PeakThreshold
if peak >= PeakThreshold {
vis.fastWindow.Update(peak)
vMean, vSD := vis.slowWindow.Update(peak)
// if our slow window finally has more values than our fast window
if length := vis.slowWindow.Len(); length >= vis.fastWindow.Cap() {
// no idea what this is doing
if math.Abs(vis.fastWindow.Mean()-vMean) > (ScalingResetDeviation * vSD) {
// drop some values and continue
vMean, vSD = vis.slowWindow.Drop(int(float64(length) * ScalingDumpPercent))
}
}
if t := vMean + (1.5 * vSD); t > 1.0 {
scale = t
}
}
vis.display.Draw(vis.barBufs, vis.cfg.ChannelCount, vis.bars, scale)
}