From 75e70d8eb3346b610dbe1725d5705e5caac81380 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 5 Apr 2020 19:49:54 +0200 Subject: mixer: basic osc message handling for /info operation --- pkg/mixer/mixer.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 8 deletions(-) (limited to 'pkg/mixer') diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go index 8782765..ef94eba 100644 --- a/pkg/mixer/mixer.go +++ b/pkg/mixer/mixer.go @@ -24,11 +24,14 @@ package mixer import ( "container/list" + "errors" "fmt" - // "log" + // "log" "net" "sync" - // "github.com/scgolang/osc" + "time" + + "github.com/scgolang/osc" ) type Channel uint8 @@ -111,14 +114,51 @@ type subscriber struct { unsubscribe <-chan struct{} } +type MixerInfo struct { + ServerVersion string + ServerName string + ConsoleModel string + ConsoleVersion string +} + type Mixer struct { config Config - client *net.UDPConn - clientLock sync.Mutex + client *osc.UDPConn + info MixerInfo subscribersLock sync.Mutex subscribers map[Channel]*list.List } +func waitForInfo(client *osc.UDPConn, infoCh chan<- MixerInfo, errCh chan<- error) { + err := client.Serve(1, osc.PatternMatching{ + "/info": osc.Method(func(msg osc.Message) (err error) { + mi := MixerInfo{} + if len(msg.Arguments) != 4 { + return errors.New("invalid number of arguments in /info response") + } + if mi.ServerVersion, err = msg.Arguments[0].ReadString(); err != nil { + return + } + if mi.ServerName, err = msg.Arguments[1].ReadString(); err != nil { + return + } + if mi.ConsoleModel, err = msg.Arguments[2].ReadString(); err != nil { + return + } + if mi.ConsoleVersion, err = msg.Arguments[3].ReadString(); err != nil { + return + } + + infoCh <- mi + return nil + }), + }) + errCh <- err + + close(infoCh) + close(errCh) +} + func NewMixer(c Config) (*Mixer, error) { if c.Port == "" { c.Port = "10023" @@ -129,15 +169,36 @@ func NewMixer(c Config) (*Mixer, error) { if err != nil { return nil, err } - m.client, err = net.DialUDP("udp", nil, server) + m.client, err = osc.DialUDP("udp", nil, server) if err != nil { return nil, err } + if err = m.client.Send(osc.Message{Address: "/info"}); err != nil { + return nil, err + } + + infoCh := make(chan MixerInfo) + errCh := make(chan error) + go waitForInfo(m.client, infoCh, errCh) + + select { + case <-time.After(10 * time.Second): + return nil, errors.New("timeout") + case err := <-errCh: + return nil, err + case info := <-infoCh: + m.info = info + } + m.subscribers = make(map[Channel]*list.List) return m, nil } +func (m *Mixer) String() string { + return fmt.Sprintf("Model %s (Firmware-Version: %s)", m.info.ConsoleModel, m.info.ConsoleVersion) +} + // func (m *Mixer) reopenInput() { // for { // time.Sleep(time.Second) @@ -242,6 +303,7 @@ func (m *Mixer) publishEvent(ev Event) { // } func (m *Mixer) Init() error { + // ch, err := m.devIn.Packets() // if err != nil { // return err @@ -292,9 +354,6 @@ func (m *Mixer) Shutdown() error { } func (m *Mixer) sendOSCMessage(msg []byte) error { - m.clientLock.Lock() - defer m.clientLock.Unlock() - // if m.devOut == nil { // return errors.New("mixer: output device is not ready.") // } -- cgit v1.2.3