summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2019-02-10 17:06:04 +0100
committerChristian Pointner <equinox@spreadspace.org>2019-02-10 17:06:04 +0100
commitc4bf287cc3991e4e52706d3cc73ecf4a577adeeb (patch)
treea2a5435dc3067c325bde1ae5bf6355973588207b
parentmixer: closer subscriber channel on unsubscribe (diff)
refactored fader levels and mute state
-rw-r--r--cmd/dolmetschctld/statemachine.go64
-rw-r--r--pkg/mixer/mixer.go76
2 files changed, 109 insertions, 31 deletions
diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go
index 1961303..e5ea0a9 100644
--- a/cmd/dolmetschctld/statemachine.go
+++ b/cmd/dolmetschctld/statemachine.go
@@ -59,15 +59,15 @@ func (l Language) String() string {
return string(l)
}
-type LanguageChannel struct {
- Num mixer.Channel
- currentLevel mixer.FaderLevel
- muted bool
+type MixerChannel struct {
+ num mixer.Channel
+ level mixer.FaderLevel
+ mute mixer.Mute
}
-type LanguageChannels struct {
- main LanguageChannel
- voice LanguageChannel
+type MixerChannels struct {
+ main MixerChannel
+ voice MixerChannel
}
type selectLangRequest struct {
@@ -82,7 +82,7 @@ type StateMachine struct {
exitedCh chan struct{}
mixerEventCh chan mixer.Event
- languages map[Language]LanguageChannels
+ languages map[Language]*MixerChannels
channel2lang map[mixer.Channel]Language
currentState State
@@ -101,6 +101,43 @@ func (sm *StateMachine) selectLang(l Language) error {
return nil
}
+func (sm *StateMachine) handleMixerEvent(ev mixer.Event) {
+ lang, exists := sm.channel2lang[ev.Channel]
+ if !exists {
+ // TODO: make this panic?
+ log.Printf("got mixer-event for unknown channel: %s", ev)
+ return
+ }
+
+ mcs, exists := sm.languages[lang]
+ if !exists {
+ panic(fmt.Sprintf("channel2lang map contains unknown language entries!"))
+ return
+ }
+
+ var mc *MixerChannel
+ switch ev.Channel {
+ case mcs.main.num:
+ mc = &mcs.main
+ case mcs.voice.num:
+ mc = &mcs.voice
+ default:
+ panic(fmt.Sprintf("channel2lang points to language that does not use the channel!"))
+ return
+ }
+
+ switch ev.Type {
+ case mixer.EventFaderChange:
+ mc.level = ev.Level
+ case mixer.EventMute:
+ mc.mute = ev.Mute
+ }
+
+ log.Printf("status of mixer channels for language '%s' is now:", lang)
+ log.Printf(" main(%d): level=%s, muted=%s", mcs.main.num, mcs.main.level, mcs.main.mute)
+ log.Printf(" voice(%d): level=%s, muted=%s", mcs.voice.num, mcs.voice.level, mcs.voice.mute)
+}
+
func (sm *StateMachine) reconcile() {
if sm.targetLang == sm.currentLang {
sm.currentState = StateSettled
@@ -117,8 +154,7 @@ func (sm *StateMachine) run() {
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...
+ sm.handleMixerEvent(ev)
case <-sm.quitCh:
return
}
@@ -138,7 +174,7 @@ func NewStateMachine(m *mixer.Mixer) (*StateMachine, error) {
sm.exitedCh = make(chan struct{})
sm.mixerEventCh = make(chan mixer.Event, 1000)
- sm.languages = make(map[Language]LanguageChannels)
+ sm.languages = make(map[Language]*MixerChannels)
sm.channel2lang = make(map[mixer.Channel]Language)
sm.currentState = StateNew
@@ -161,9 +197,9 @@ func (sm *StateMachine) AddLanguage(name Language, main, voice mixer.Channel) er
}
}
- chMain := LanguageChannel{main, mixer.FaderLevel0db, false}
- chVoice := LanguageChannel{voice, mixer.FaderLevel0db, false}
- sm.languages[name] = LanguageChannels{chMain, chVoice}
+ chMain := MixerChannel{main, mixer.FaderLevelUnknown, mixer.MuteUnknown}
+ chVoice := MixerChannel{voice, mixer.FaderLevelUnknown, mixer.MuteUnknown}
+ sm.languages[name] = &MixerChannels{chMain, chVoice}
sm.channel2lang[main] = name
sm.channel2lang[voice] = name
diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go
index 4db2c3a..a3348d9 100644
--- a/pkg/mixer/mixer.go
+++ b/pkg/mixer/mixer.go
@@ -32,9 +32,13 @@ import (
"github.com/scgolang/midi"
)
-type Channel uint8
-type FaderLevel uint8
+// TODO: make this configurable
+const (
+ CC_MUTE = byte(0xB1)
+ CC_FADER = byte(0xB0)
+)
+type Channel uint8
type EventType int
const (
@@ -53,14 +57,61 @@ func (et EventType) String() string {
}
}
+type FaderLevel uint8
+
+// TODO: make the values configurable
+const (
+ FaderLevelUnknown = FaderLevel(0xFF)
+ FaderLevelMax = FaderLevel(0x7F)
+ FaderLevel0db = FaderLevel(0x5F)
+ FaderLevelOff = FaderLevel(0x00)
+)
+
+func (fl FaderLevel) String() string {
+ if fl > FaderLevelMax {
+ return "unknown"
+ }
+ val := fmt.Sprintf("%3d", fl)
+ switch fl {
+ case FaderLevelMax:
+ return val + " (max)"
+ case FaderLevel0db:
+ return val + " (0db)"
+ case FaderLevelOff:
+ return val + " (off)"
+ default:
+ return val
+ }
+}
+
+type Mute int8
+
+const (
+ MuteUnknown = -1
+ MuteUnmuted = 0
+ MuteMuted = 1
+)
+
+func (m Mute) String() string {
+ switch m {
+ case MuteUnmuted:
+ return "unmuted"
+ case MuteMuted:
+ return "muted"
+ default:
+ return "unknown"
+ }
+}
+
type Event struct {
Channel Channel
Type EventType
- Value uint8
+ Level FaderLevel
+ Mute Mute
}
func (e Event) String() string {
- return fmt.Sprintf("Event(%s) for channel 0x%02X, value=%d", e.Type, e.Channel, e.Value)
+ return fmt.Sprintf("Event(%s) for channel %d: level=%s, muted=%s", e.Type, e.Channel, e.Level, e.Mute)
}
type Mixer struct {
@@ -69,16 +120,6 @@ type Mixer struct {
subscribers map[Channel]*list.List
}
-// TODO: make this configurable
-const (
- CC_MUTE = byte(0xB1)
- CC_FADER = byte(0xB0)
-
- FaderLevelMax = FaderLevel(0x7F)
- FaderLevel0db = FaderLevel(0x60)
- FaderLevelOff = FaderLevel(0x00)
-)
-
func openDevice(devices []*midi.Device, prefix string) (d *midi.Device, err error) {
for _, device := range devices {
if strings.HasPrefix(device.Name, prefix) {
@@ -136,16 +177,17 @@ func (m *Mixer) sendEvent(ev Event) {
}
func (m *Mixer) handleMidiPacket(p midi.Packet) {
- ev := Event{}
+ ev := Event{Level: FaderLevelUnknown, Mute: MuteUnknown}
ev.Channel = Channel(p.Data[1])
switch p.Data[0] {
case CC_FADER:
ev.Type = EventFaderChange
- ev.Value = p.Data[2]
+ ev.Level = FaderLevel(p.Data[2])
case CC_MUTE:
ev.Type = EventMute
+ ev.Mute = MuteUnmuted
if p.Data[2] > 0 {
- ev.Value = 1
+ ev.Mute = MuteMuted
}
default:
return