-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvideo_osc.go
90 lines (73 loc) · 2 KB
/
video_osc.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
package effects
import (
"github.com/brianewing/redshift/strip"
"github.com/brianewing/redshift/osc"
"strconv"
"strings"
)
// VideoOSC is an Effect which copies pixel values from OSC messages in the form used by the VideoOSC Android app, e.g.
// /vosc/red1 [255] /vosc/green1 [255] /vosc/blue1 [255]
// /vosc/red2 [255] /vosc/green2 [255] /vosc/blue2 [255]
// onto LED strip buffer, where /vosc/red1 specifies the "0th" LED color's red component,
// and so on.
type VideoOSC struct {
Prefix string
Blend *Blend
stop chan struct{}
}
func NewVideoOSC() *VideoOSC {
return &VideoOSC{
Prefix: "/vosc/",
Blend: NewBlend(),
}
}
func (e *VideoOSC) Init() {
e.stop = make(chan struct{})
go func() {
msgs, done := osc.StreamMessages()
for {
select {
case msg := <-msgs:
e.receiveOSCMessage(msg)
case <-e.stop:
done <- struct{}{}
return
}
}
}()
}
func (e *VideoOSC) Destroy() {
e.stop <- struct{}{}
}
func (e *VideoOSC) Render(s *strip.LEDStrip) {
if len(e.Blend.Buffer) != int(s.Size) {
e.Blend.Buffer = strip.NewBuffer(s.Size)
}
e.Blend.Render(s)
}
func (e *VideoOSC) receiveOSCMessage(msg osc.OscMessage) {
if desc := strings.TrimPrefix(msg.Address, e.Prefix); len(msg.Address) > len(desc) {
if len(msg.Arguments) > 0 {
value, _ := msg.Arguments[0].(float64)
var ledNum int
var component uint8
if numStr := strings.TrimPrefix(desc, "red"); len(desc) > len(numStr) {
ledNum, _ = strconv.Atoi(numStr)
} else if numStr := strings.TrimPrefix(desc, "green"); len(desc) > len(numStr) {
ledNum, _ = strconv.Atoi(numStr)
component = 1
} else if numStr := strings.TrimPrefix(desc, "blue"); len(desc) > len(numStr) {
ledNum, _ = strconv.Atoi(numStr)
component = 2
}
ledNum-- // VideoOSC indexes pixels from 1
e.updatePixelComponent(ledNum, component, uint8(value))
}
}
}
func (e *VideoOSC) updatePixelComponent(pixel int, component, value uint8) {
if pixel >= len(e.Blend.Buffer) {
return
}
e.Blend.Buffer[pixel][component] = value
}