diff options
-rw-r--r-- | cmd/dolmetschctld/statemachine.go | 8 | ||||
-rw-r--r-- | pkg/mixer/mixer.go | 89 |
2 files changed, 86 insertions, 11 deletions
diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go index 97f29c0..c5e5707 100644 --- a/cmd/dolmetschctld/statemachine.go +++ b/cmd/dolmetschctld/statemachine.go @@ -80,6 +80,7 @@ type StateMachine struct { selectLangCh chan selectLangRequest quitCh chan bool exitedCh chan struct{} + mixerEventCh chan mixer.Event languages map[Language]LanguageChannels channel2lang map[mixer.Channel]Language @@ -115,6 +116,9 @@ func (sm *StateMachine) run() { select { case req := <-sm.selectLangCh: req.resultCh <- sm.selectLang(req.l) + case ev := <-sm.mixerEventCh: + log.Printf("got event from mixer: %v", ev) + // TODO: update mixer channel states... case <-sm.quitCh: return } @@ -132,6 +136,7 @@ func NewStateMachine(m *mixer.Mixer) (*StateMachine, error) { sm.selectLangCh = make(chan selectLangRequest, 10) sm.quitCh = make(chan bool, 1) sm.exitedCh = make(chan struct{}) + sm.mixerEventCh = make(chan mixer.Event, 3) sm.languages = make(map[Language]LanguageChannels) sm.channel2lang = make(map[mixer.Channel]Language) @@ -161,6 +166,9 @@ func (sm *StateMachine) AddLanguage(name Language, main, voice mixer.Channel) er sm.languages[name] = LanguageChannels{chMain, chVoice} sm.channel2lang[main] = name sm.channel2lang[voice] = name + + sm.mixer.Subscribe(main, sm.mixerEventCh) + sm.mixer.Subscribe(voice, sm.mixerEventCh) return nil } diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go index ee25207..c774342 100644 --- a/pkg/mixer/mixer.go +++ b/pkg/mixer/mixer.go @@ -23,8 +23,9 @@ package mixer import ( + "container/list" "errors" - "log" + "fmt" "strings" "github.com/scgolang/midi" @@ -33,12 +34,41 @@ import ( type Channel uint8 type FaderLevel uint8 +type EventType int + +const ( + EventFaderChange = iota + EventMute +) + +func (et EventType) String() string { + switch et { + case EventFaderChange: + return "fader-change" + case EventMute: + return "mute" + default: + return "unknown" + } +} + +type Event struct { + Channel Channel + Type EventType + Value uint8 +} + +func (e Event) String() string { + return fmt.Sprintf("Event(%s) for channel 0x%02X, value=%d", e.Type, e.Channel, e.Value) +} + type Mixer struct { - DevIn *midi.Device - DevOut *midi.Device + DevIn *midi.Device + DevOut *midi.Device + subscribers map[Channel]*list.List } -// TODO: make this confgurable +// TODO: make this configurable const ( CC_MUTE = byte(0xB1) CC_FADER = byte(0xB0) @@ -66,31 +96,58 @@ func NewMixer(c Config) (*Mixer, error) { return nil, err } + // TODO: add support for DevIn == DevOut m := &Mixer{} if m.DevIn, err = openDevice(devices, c.DevIn); err != nil { return nil, err } + m.DevIn.QueueSize = 100 if m.DevOut, err = openDevice(devices, c.DevOut); err != nil { return nil, err } - m.DevIn.QueueSize = 100 - m.DevOut.QueueSize = 100 + m.subscribers = make(map[Channel]*list.List) return m, nil } +func (m *Mixer) sendEvent(ev Event) { + subs, exists := m.subscribers[ev.Channel] + if exists && subs != nil { + var next *list.Element + for sub := subs.Front(); sub != nil; sub = next { + next = sub.Next() + + ch, ok := (sub.Value).(chan<- Event) + if !ok { + panic(fmt.Sprintf("mixer: subscriber list element value has wrong type: %T", sub.Value)) + } + + select { + case ch <- ev: + default: + // subscriber is not respoding... + subs.Remove(sub) + } + } + } +} + func (m *Mixer) handleMidiPacket(p midi.Packet) { + ev := Event{} + ev.Channel = Channel(p.Data[1]) switch p.Data[0] { case CC_FADER: - log.Printf("mixer: fader movement on channel 0x%02X, level is now: 0x%02X", p.Data[1], p.Data[2]) + ev.Type = EventFaderChange + ev.Value = p.Data[2] case CC_MUTE: - newState := "unmuted" + ev.Type = EventMute if p.Data[2] > 0 { - newState = "muted" + ev.Value = 1 } - log.Printf("mixer: channel 0x%02X is now %s", p.Data[1], newState) + default: + return } - // TODO: send new state to subscribers + m.sendEvent(ev) } func (m *Mixer) Init() error { @@ -149,3 +206,13 @@ func (m *Mixer) SetLevel(ch Channel, level FaderLevel) error { } return nil } + +func (m *Mixer) Subscribe(ch Channel, out chan<- Event) { + subs, exists := m.subscribers[ch] + if !exists { + subs = list.New() + m.subscribers[ch] = subs + } + + subs.PushBack(out) +} |