summaryrefslogtreecommitdiff
path: root/pkg/mixer/mixer.go
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2019-02-10 00:10:37 +0100
committerChristian Pointner <equinox@spreadspace.org>2019-02-10 00:10:37 +0100
commit2eb9fddf09f0b398a60c3a39940b58f8c295f4a2 (patch)
tree857fead041103128861c7fe097cbe1aa046530b2 /pkg/mixer/mixer.go
parentparsing midi packet works now (diff)
mixer event subscription works now
Diffstat (limited to 'pkg/mixer/mixer.go')
-rw-r--r--pkg/mixer/mixer.go89
1 files changed, 78 insertions, 11 deletions
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)
+}