From c7f887a174bf0a95a858e6d31f113da7b6bfffd8 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 5 Apr 2020 19:04:21 +0200 Subject: begin of major change: switching from midi to OSC --- pkg/mixer/mixer.go | 288 ++++++++++++++++++++++++----------------------------- 1 file changed, 130 insertions(+), 158 deletions(-) (limited to 'pkg/mixer/mixer.go') diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go index afa1534..8782765 100644 --- a/pkg/mixer/mixer.go +++ b/pkg/mixer/mixer.go @@ -24,20 +24,11 @@ package mixer import ( "container/list" - "errors" "fmt" - "log" - "strings" + // "log" + "net" "sync" - "time" - - "github.com/scgolang/midi" -) - -// TODO: make this configurable -const ( - CC_MUTE = byte(0xB1) - CC_FADER = byte(0xB0) + // "github.com/scgolang/osc" ) type Channel uint8 @@ -59,21 +50,20 @@ func (et EventType) String() string { } } -type FaderLevel uint8 +type FaderLevel float32 -// TODO: make the values configurable const ( - FaderLevelUnknown = FaderLevel(0xFF) - FaderLevelMax = FaderLevel(0x7F) - FaderLevel0db = FaderLevel(0x60) - FaderLevelOff = FaderLevel(0x00) + FaderLevelUnknown = FaderLevel(-1.0) + FaderLevelMax = FaderLevel(1.00) + FaderLevel0db = FaderLevel(0.75) + FaderLevelOff = FaderLevel(0.00) ) func (fl FaderLevel) String() string { if fl > FaderLevelMax { return "unknown" } - val := fmt.Sprintf("%3d", fl) + val := fmt.Sprintf("%3f", fl) switch fl { case FaderLevelMax: return val + " (max)" @@ -123,38 +113,24 @@ type subscriber struct { type Mixer struct { config Config - devIn *midi.Device - devOutLock sync.Mutex - devOut *midi.Device + client *net.UDPConn + clientLock sync.Mutex subscribersLock sync.Mutex subscribers map[Channel]*list.List } -func openDevice(devices []*midi.Device, prefix string) (d *midi.Device, err error) { - for _, device := range devices { - if strings.HasPrefix(device.Name, prefix) { - d = device - } - } - if d == nil { - return nil, errors.New("could not find device with prefix: " + prefix) - } - return d, d.Open() -} - func NewMixer(c Config) (*Mixer, error) { - devices, err := midi.Devices() - if err != nil { - return nil, err + if c.Port == "" { + c.Port = "10023" } - - // TODO: add support for devIn == devOut m := &Mixer{config: c} - if m.devIn, err = openDevice(devices, c.DevIn); err != nil { + + server, err := net.ResolveUDPAddr("udp", c.Host+":"+c.Port) + if err != nil { return nil, err } - m.devIn.QueueSize = 100 - if m.devOut, err = openDevice(devices, c.DevOut); err != nil { + m.client, err = net.DialUDP("udp", nil, server) + if err != nil { return nil, err } @@ -162,56 +138,56 @@ func NewMixer(c Config) (*Mixer, error) { return m, nil } -func (m *Mixer) reopenInput() { - for { - time.Sleep(time.Second) - - devices, err := midi.Devices() - if err != nil { - log.Printf("mixer: error listing midi devices: %v, retrying...", err) - continue - } - - if m.devIn, err = openDevice(devices, m.config.DevIn); err != nil { - log.Printf("mixer: error re-opening midi input device: %v, retrying...", err) - continue - } - - if err = m.Init(); err != nil { - log.Printf("mixer: error re-initializing midi input device: %v, retrying...", err) - - continue - } - - log.Printf("mixer: successfully re-initialized midi input device") - break - } -} - -func (m *Mixer) reopenOutput() { - for { - time.Sleep(time.Second) - - devices, err := midi.Devices() - if err != nil { - log.Printf("mixer: error listing midi devices: %v, retrying...", err) - continue - } - - newOut, err := openDevice(devices, m.config.DevOut) - if err != nil { - log.Printf("mixer: error re-opening midi output device: %v, retrying...", err) - continue - } - - log.Printf("mixer: successfully re-opened midi output device") - - m.devOutLock.Lock() - defer m.devOutLock.Unlock() - m.devOut = newOut - break - } -} +// func (m *Mixer) reopenInput() { +// for { +// time.Sleep(time.Second) + +// devices, err := midi.Devices() +// if err != nil { +// log.Printf("mixer: error listing midi devices: %v, retrying...", err) +// continue +// } + +// if m.devIn, err = openDevice(devices, m.config.DevIn); err != nil { +// log.Printf("mixer: error re-opening midi input device: %v, retrying...", err) +// continue +// } + +// if err = m.Init(); err != nil { +// log.Printf("mixer: error re-initializing midi input device: %v, retrying...", err) + +// continue +// } + +// log.Printf("mixer: successfully re-initialized midi input device") +// break +// } +// } + +// func (m *Mixer) reopenOutput() { +// for { +// time.Sleep(time.Second) + +// devices, err := midi.Devices() +// if err != nil { +// log.Printf("mixer: error listing midi devices: %v, retrying...", err) +// continue +// } + +// newOut, err := openDevice(devices, m.config.DevOut) +// if err != nil { +// log.Printf("mixer: error re-opening midi output device: %v, retrying...", err) +// continue +// } + +// log.Printf("mixer: successfully re-opened midi output device") + +// m.devOutLock.Lock() +// defer m.devOutLock.Unlock() +// m.devOut = newOut +// break +// } +// } func (m *Mixer) publishEvent(ev Event) { m.subscribersLock.Lock() @@ -246,57 +222,53 @@ func (m *Mixer) publishEvent(ev Event) { } } -func (m *Mixer) handleMidiPacket(p midi.Packet) { - ev := Event{Level: FaderLevelUnknown, Mute: MuteUnknown} - ev.Channel = Channel(p.Data[1]) - switch p.Data[0] { - case CC_FADER: - ev.Type = EventFaderChange - ev.Level = FaderLevel(p.Data[2]) - case CC_MUTE: - ev.Type = EventMute - ev.Mute = MuteUnmuted - if p.Data[2] > 0 { - ev.Mute = MuteMuted - } - default: - return - } - m.publishEvent(ev) -} +// func (m *Mixer) handleMidiPacket(p midi.Packet) { +// ev := Event{Level: FaderLevelUnknown, Mute: MuteUnknown} +// ev.Channel = Channel(p.Data[1]) +// switch p.Data[0] { +// case CC_FADER: +// ev.Type = EventFaderChange +// ev.Level = FaderLevel(p.Data[2]) +// case CC_MUTE: +// ev.Type = EventMute +// ev.Mute = MuteUnmuted +// if p.Data[2] > 0 { +// ev.Mute = MuteMuted +// } +// default: +// return +// } +// m.publishEvent(ev) +// } func (m *Mixer) Init() error { - ch, err := m.devIn.Packets() - if err != nil { - return err - } - - go func() { - for { - ps := <-ch - for _, p := range ps { - if p.Err != nil { - log.Printf("mixer: got fatal error from midi input device: %v, trying to reopen it...", p.Err) - m.devIn.Close() - m.devIn = nil - go m.reopenInput() - return - } - m.handleMidiPacket(p) - } - } - }() + // ch, err := m.devIn.Packets() + // if err != nil { + // return err + // } + + // go func() { + // for { + // ps := <-ch + // for _, p := range ps { + // if p.Err != nil { + // log.Printf("mixer: got fatal error from midi input device: %v, trying to reopen it...", p.Err) + // // m.devIn.Close() + // // m.devIn = nil + // // go m.reopenInput() + // // return + // } + // // m.handleMidiPacket(p) + // } + // } + // }() return nil } func (m *Mixer) Shutdown() error { - if m.devIn != nil { - m.devIn.Close() - m.devIn = nil - } - if m.devOut != nil { - m.devOut.Close() - m.devOut = nil + if m.client != nil { + m.client.Close() + m.client = nil } m.subscribersLock.Lock() @@ -319,30 +291,30 @@ func (m *Mixer) Shutdown() error { return nil } -func (m *Mixer) sendMidiMessage(msg []byte) error { - m.devOutLock.Lock() - defer m.devOutLock.Unlock() - - if m.devOut == nil { - return errors.New("mixer: output device is not ready.") - } - - n, err := m.devOut.Write(msg) - if err != nil { - log.Printf("mixer: got fatal error from midi output device: %v, trying to reopen it...", err) - m.devOut.Close() - m.devOut = nil - go m.reopenOutput() - return err - } - if n != len(msg) { - return errors.New("sending midi message failed: short write") - } +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.") + // } + + // n, err := m.devOut.Write(msg) + // if err != nil { + // log.Printf("mixer: got fatal error from midi output device: %v, trying to reopen it...", err) + // m.devOut.Close() + // m.devOut = nil + // go m.reopenOutput() + // return err + // } + // if n != len(msg) { + // return errors.New("sending midi message failed: short write") + // } return nil } func (m *Mixer) sendMute(channel byte, value byte) error { - return m.sendMidiMessage([]byte{CC_MUTE, channel, value}) + return nil // m.sendMidiMessage([]byte{CC_MUTE, channel, value}) } func (m *Mixer) Mute(ch Channel) error { @@ -357,7 +329,7 @@ func (m *Mixer) SetLevel(ch Channel, level FaderLevel) error { if level > FaderLevelMax { level = FaderLevelMax } - return m.sendMidiMessage([]byte{CC_FADER, byte(ch), byte(level)}) + return nil // m.sendMidiMessage([]byte{CC_FADER, byte(ch), byte(level)}) } func (m *Mixer) Subscribe(ch Channel, out chan<- Event) chan<- struct{} { -- cgit v1.2.3 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 --- cmd/dolmetschctld/dolmetschctld.go | 2 +- pkg/mixer/mixer.go | 75 ++++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 9 deletions(-) (limited to 'pkg/mixer/mixer.go') diff --git a/cmd/dolmetschctld/dolmetschctld.go b/cmd/dolmetschctld/dolmetschctld.go index 7105ae1..a6d9ed8 100644 --- a/cmd/dolmetschctld/dolmetschctld.go +++ b/cmd/dolmetschctld/dolmetschctld.go @@ -51,7 +51,7 @@ func main() { } defer m.Shutdown() - log.Printf("successfully connected to mixer!") + log.Printf("successfully connected to mixer: %s", m.String()) if err = m.Init(); err != nil { log.Printf("Error initializeing the mixer: %v", err) 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 From dfb57bb771d5b8c06e932ef90ae09a3c8bf70dca Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Mon, 6 Apr 2020 00:47:02 +0200 Subject: new mixer interface mostly done, remaining issues with floats and rounding errors... --- cmd/dolmetschctld/dolmetschctld.go | 4 +- cmd/dolmetschctld/statemachine.go | 9 +- pkg/mixer/mixer.go | 231 +++++++++++++++++-------------------- 3 files changed, 113 insertions(+), 131 deletions(-) (limited to 'pkg/mixer/mixer.go') diff --git a/cmd/dolmetschctld/dolmetschctld.go b/cmd/dolmetschctld/dolmetschctld.go index a6d9ed8..3242dde 100644 --- a/cmd/dolmetschctld/dolmetschctld.go +++ b/cmd/dolmetschctld/dolmetschctld.go @@ -67,8 +67,8 @@ func main() { log.Printf("state machine successfully initialized!") // TODO: make this configurable - addLanguage(sm, "en", 0x20, 0x24) - addLanguage(sm, "de", 0x22, 0x25) + addLanguage(sm, "en", "auxin/01", "auxin/05") + addLanguage(sm, "de", "auxin/03", "auxin/06") sm.Start() defer sm.Shutdown() diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go index 15f0e41..b6d46ba 100644 --- a/cmd/dolmetschctld/statemachine.go +++ b/cmd/dolmetschctld/statemachine.go @@ -178,12 +178,7 @@ func (sm *StateMachine) handleMixerEvent(ev mixer.Event) { // make sure that our state and the mixer are in sync func (sm *StateMachine) initMixer() { for _, mcs := range sm.languages { - sm.mixer.SetLevel(mcs.original.num, mixer.FaderLevel0db-1) - sm.mixer.SetLevel(mcs.original.num, mixer.FaderLevel0db) mcs.original.target.level = mixer.FaderLevel0db - - sm.mixer.SetLevel(mcs.interpreter.num, mixer.FaderLevelOff+1) - sm.mixer.SetLevel(mcs.interpreter.num, mixer.FaderLevelOff) mcs.interpreter.target.level = mixer.FaderLevelOff } sm.language = "" @@ -226,9 +221,9 @@ func calcNextLevel(target, current mixer.FaderLevel) mixer.FaderLevel { next := target if current != mixer.FaderLevelUnknown { if next > current { - next = current + 1 + next = current + 0.01 } else { - next = current - 1 + next = current - 0.01 } } return next diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go index ef94eba..58ae20b 100644 --- a/pkg/mixer/mixer.go +++ b/pkg/mixer/mixer.go @@ -26,15 +26,20 @@ import ( "container/list" "errors" "fmt" - // "log" + "log" "net" + "strings" "sync" "time" "github.com/scgolang/osc" ) -type Channel uint8 +const ( + OSCSubscriptionTimeFactor = 0 +) + +type Channel string type EventType int const ( @@ -79,7 +84,7 @@ func (fl FaderLevel) String() string { } } -type Mute int8 +type Mute int const ( MuteUnknown = Mute(-1) @@ -106,7 +111,7 @@ type Event struct { } func (e Event) String() string { - return fmt.Sprintf("Event(%s) for channel %d: level=%s, muted=%s", e.Type, e.Channel, e.Level, e.Mute) + return fmt.Sprintf("Event(%s) for channel '%s': level=%s, muted=%s", e.Type, e.Channel, e.Level, e.Mute) } type subscriber struct { @@ -199,57 +204,6 @@ 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) - -// devices, err := midi.Devices() -// if err != nil { -// log.Printf("mixer: error listing midi devices: %v, retrying...", err) -// continue -// } - -// if m.devIn, err = openDevice(devices, m.config.DevIn); err != nil { -// log.Printf("mixer: error re-opening midi input device: %v, retrying...", err) -// continue -// } - -// if err = m.Init(); err != nil { -// log.Printf("mixer: error re-initializing midi input device: %v, retrying...", err) - -// continue -// } - -// log.Printf("mixer: successfully re-initialized midi input device") -// break -// } -// } - -// func (m *Mixer) reopenOutput() { -// for { -// time.Sleep(time.Second) - -// devices, err := midi.Devices() -// if err != nil { -// log.Printf("mixer: error listing midi devices: %v, retrying...", err) -// continue -// } - -// newOut, err := openDevice(devices, m.config.DevOut) -// if err != nil { -// log.Printf("mixer: error re-opening midi output device: %v, retrying...", err) -// continue -// } - -// log.Printf("mixer: successfully re-opened midi output device") - -// m.devOutLock.Lock() -// defer m.devOutLock.Unlock() -// m.devOut = newOut -// break -// } -// } - func (m *Mixer) publishEvent(ev Event) { m.subscribersLock.Lock() defer m.subscribersLock.Unlock() @@ -283,52 +237,80 @@ func (m *Mixer) publishEvent(ev Event) { } } -// func (m *Mixer) handleMidiPacket(p midi.Packet) { -// ev := Event{Level: FaderLevelUnknown, Mute: MuteUnknown} -// ev.Channel = Channel(p.Data[1]) -// switch p.Data[0] { -// case CC_FADER: -// ev.Type = EventFaderChange -// ev.Level = FaderLevel(p.Data[2]) -// case CC_MUTE: -// ev.Type = EventMute -// ev.Mute = MuteUnmuted -// if p.Data[2] > 0 { -// ev.Mute = MuteMuted -// } -// default: -// return -// } -// m.publishEvent(ev) -// } +type oscDispatcher struct { + mixer *Mixer +} + +func (d oscDispatcher) Dispatch(bundle osc.Bundle, exactMatch bool) error { + // TODO: X32 seems to not use bundles at the momemnt - ingoring them for now + return nil +} + +func (d oscDispatcher) Invoke(msg osc.Message, exactMatch bool) error { + addrParts := strings.Split(strings.TrimPrefix(msg.Address, "/"), "/") + if len(addrParts) < 4 { + return nil + } + if addrParts[2] != "mix" { + return nil + } + if len(msg.Arguments) != 1 { + return nil + } + + ev := Event{Level: FaderLevelUnknown, Mute: MuteUnknown} + ev.Channel = Channel(addrParts[0] + "/" + addrParts[1]) + switch addrParts[3] { + case "on": + ev.Type = EventMute + arg, err := msg.Arguments[0].ReadInt32() + if err != nil { + return err + } + ev.Mute = Mute(arg) + case "fader": + ev.Type = EventFaderChange + arg, err := msg.Arguments[0].ReadFloat32() + if err != nil { + return err + } + ev.Level = FaderLevel(arg) + default: + return nil + } + + d.mixer.publishEvent(ev) + return nil +} func (m *Mixer) Init() error { + go func() { + for { + dispatcher := oscDispatcher{mixer: m} + err := m.client.Serve(1, dispatcher) + if err != nil { + log.Printf("mixer: failed to dispatch message: %v", err) + time.Sleep(time.Second) + } + } + }() + + go func() { + for { + time.Sleep(5 * time.Second) + err := m.client.Send(osc.Message{Address: "/renew"}) + if err != nil { + log.Printf("mixer: failed to renew subsciptions: %v", err) + } + } + }() - // ch, err := m.devIn.Packets() - // if err != nil { - // return err - // } - - // go func() { - // for { - // ps := <-ch - // for _, p := range ps { - // if p.Err != nil { - // log.Printf("mixer: got fatal error from midi input device: %v, trying to reopen it...", p.Err) - // // m.devIn.Close() - // // m.devIn = nil - // // go m.reopenInput() - // // return - // } - // // m.handleMidiPacket(p) - // } - // } - // }() return nil } func (m *Mixer) Shutdown() error { if m.client != nil { + m.client.Send(osc.Message{Address: "/unsubscribe"}) m.client.Close() m.client = nil } @@ -353,56 +335,61 @@ func (m *Mixer) Shutdown() error { return nil } -func (m *Mixer) sendOSCMessage(msg []byte) error { - // if m.devOut == nil { - // return errors.New("mixer: output device is not ready.") - // } - - // n, err := m.devOut.Write(msg) - // if err != nil { - // log.Printf("mixer: got fatal error from midi output device: %v, trying to reopen it...", err) - // m.devOut.Close() - // m.devOut = nil - // go m.reopenOutput() - // return err - // } - // if n != len(msg) { - // return errors.New("sending midi message failed: short write") - // } - return nil -} - -func (m *Mixer) sendMute(channel byte, value byte) error { - return nil // m.sendMidiMessage([]byte{CC_MUTE, channel, value}) +func (m *Mixer) sendMute(channel Channel, value string) error { + msg := osc.Message{Address: "/" + string(channel) + "/mix/on"} + msg.Arguments = append(msg.Arguments, osc.String(value)) + return m.client.Send(msg) } func (m *Mixer) Mute(ch Channel) error { - return m.sendMute(byte(ch), 0x7F) + return m.sendMute(ch, "OFF") } func (m *Mixer) Unmute(ch Channel) error { - return m.sendMute(byte(ch), 0x00) + return m.sendMute(ch, "ON") } -func (m *Mixer) SetLevel(ch Channel, level FaderLevel) error { +func (m *Mixer) SetLevel(channel Channel, level FaderLevel) error { if level > FaderLevelMax { level = FaderLevelMax } - return nil // m.sendMidiMessage([]byte{CC_FADER, byte(ch), byte(level)}) + msg := osc.Message{Address: "/" + string(channel) + "/mix/fader"} + msg.Arguments = append(msg.Arguments, osc.Float(level)) + return m.client.Send(msg) } -func (m *Mixer) Subscribe(ch Channel, out chan<- Event) chan<- struct{} { +func (m *Mixer) sendSubscribe(channel Channel) (err error) { + msg := osc.Message{Address: "/subscribe"} + msg.Arguments = append(msg.Arguments, osc.String("/"+string(channel)+"/mix/on"), osc.Int(OSCSubscriptionTimeFactor)) + if err = m.client.Send(msg); err != nil { + return + } + + msg = osc.Message{Address: "/subscribe"} + msg.Arguments = append(msg.Arguments, osc.String("/"+string(channel)+"/mix/fader"), osc.Int(OSCSubscriptionTimeFactor)) + if err = m.client.Send(msg); err != nil { + return + } + + return +} + +func (m *Mixer) Subscribe(channel Channel, out chan<- Event) (chan<- struct{}, error) { m.subscribersLock.Lock() defer m.subscribersLock.Unlock() - subs, exists := m.subscribers[ch] + subs, exists := m.subscribers[channel] if !exists { subs = list.New() - m.subscribers[ch] = subs + m.subscribers[channel] = subs + } + + if err := m.sendSubscribe(channel); err != nil { + return nil, err } // log.Printf("mixer: subscribing '%v' to events for channel: %v", out, ch) unsubscribe := make(chan struct{}) subs.PushBack(subscriber{publish: out, unsubscribe: unsubscribe}) - return unsubscribe + return unsubscribe, nil } -- cgit v1.2.3 From 89f471f9f129e2c9876091b4c229caac426db93d Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sun, 12 Apr 2020 20:22:27 +0200 Subject: basic functionality works now --- cmd/dolmetschctld/statemachine.go | 20 ++++++++++++-------- pkg/mixer/mixer.go | 15 ++++++++++----- 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'pkg/mixer/mixer.go') diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go index b6d46ba..3e7461b 100644 --- a/cmd/dolmetschctld/statemachine.go +++ b/cmd/dolmetschctld/statemachine.go @@ -168,8 +168,8 @@ func (sm *StateMachine) handleMixerEvent(ev mixer.Event) { } switch ev.Type { - case mixer.EventFaderChange: - mc.current.level = ev.Level + // case mixer.EventFaderChange: + // mc.current.level = ev.Level case mixer.EventMute: mc.current.mute = ev.Mute } @@ -220,10 +220,10 @@ func (sm *StateMachine) setOriginal2InterpreterRatio(r float32) error { func calcNextLevel(target, current mixer.FaderLevel) mixer.FaderLevel { next := target if current != mixer.FaderLevelUnknown { - if next > current { - next = current + 0.01 - } else { - next = current - 0.01 + if next > (current + mixer.FaderLevelIncrement/2) { + next = current + mixer.FaderLevelIncrement + } else if next < (current - mixer.FaderLevelIncrement/2) { + next = current - mixer.FaderLevelIncrement } } return next @@ -249,11 +249,15 @@ func (sm *StateMachine) reconcile(ticker bool) { sm.state = types.StateSettled for _, mcs := range sm.languages { if mcs.original.target.level != mcs.original.current.level { - sm.mixer.SetLevel(mcs.original.num, calcNextLevel(mcs.original.target.level, mcs.original.current.level)) + nextLevel := calcNextLevel(mcs.original.target.level, mcs.original.current.level) + sm.mixer.SetLevel(mcs.original.num, nextLevel) + mcs.original.current.level = nextLevel sm.state = types.StateSettling } if mcs.interpreter.target.level != mcs.interpreter.current.level { - sm.mixer.SetLevel(mcs.interpreter.num, calcNextLevel(mcs.interpreter.target.level, mcs.interpreter.current.level)) + nextLevel := calcNextLevel(mcs.interpreter.target.level, mcs.interpreter.current.level) + sm.mixer.SetLevel(mcs.interpreter.num, nextLevel) + mcs.interpreter.current.level = nextLevel sm.state = types.StateSettling } } diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go index 58ae20b..dbc4dae 100644 --- a/pkg/mixer/mixer.go +++ b/pkg/mixer/mixer.go @@ -61,10 +61,11 @@ func (et EventType) String() string { type FaderLevel float32 const ( - FaderLevelUnknown = FaderLevel(-1.0) - FaderLevelMax = FaderLevel(1.00) - FaderLevel0db = FaderLevel(0.75) - FaderLevelOff = FaderLevel(0.00) + FaderLevelUnknown = FaderLevel(-1.0) + FaderLevelMax = FaderLevel(1.00) + FaderLevel0db = FaderLevel(0.75) + FaderLevelOff = FaderLevel(0.00) + FaderLevelIncrement = FaderLevel(0.01) ) func (fl FaderLevel) String() string { @@ -267,7 +268,11 @@ func (d oscDispatcher) Invoke(msg osc.Message, exactMatch bool) error { if err != nil { return err } - ev.Mute = Mute(arg) + if arg == 0 { + ev.Mute = MuteMuted + } else { + ev.Mute = MuteUnmuted + } case "fader": ev.Type = EventFaderChange arg, err := msg.Arguments[0].ReadFloat32() -- cgit v1.2.3