summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2019-02-09 22:03:15 +0100
committerChristian Pointner <equinox@spreadspace.org>2019-02-09 22:03:15 +0100
commit7672e8d60586129e8f4f9c718d1d62f3c9c0b729 (patch)
tree1245e9010d245d83cbb27eb2e63fe88b62d544e6
parentadded telnet control interface (diff)
language selection now returns result
-rw-r--r--cmd/dolmetschctld/dolmetschctld.go8
-rw-r--r--cmd/dolmetschctld/statemachine.go92
-rw-r--r--cmd/dolmetschctld/telnet.go68
-rw-r--r--pkg/mixer/mixer.go8
4 files changed, 157 insertions, 19 deletions
diff --git a/cmd/dolmetschctld/dolmetschctld.go b/cmd/dolmetschctld/dolmetschctld.go
index 0f6793b..45536e8 100644
--- a/cmd/dolmetschctld/dolmetschctld.go
+++ b/cmd/dolmetschctld/dolmetschctld.go
@@ -60,11 +60,15 @@ func main() {
defer sm.Shutdown()
var telnet *TelnetInterface
- if telnet, err = NewTelnetInterface(sm); err != nil {
+ if telnet, err = NewTelnetInterface("127.0.0.1:1234", sm); err != nil {
log.Printf("creating telnet control interface failed: %v", err)
os.Exit(1)
}
- telnet.Run()
+ log.Printf("telnet interface successfully initialized!")
+
+ if err = telnet.Run(); err != nil {
+ log.Printf("running telnet interface failed: %v", err)
+ }
log.Printf("exiting.")
}
diff --git a/cmd/dolmetschctld/statemachine.go b/cmd/dolmetschctld/statemachine.go
index c388d24..2aba4bb 100644
--- a/cmd/dolmetschctld/statemachine.go
+++ b/cmd/dolmetschctld/statemachine.go
@@ -23,34 +23,92 @@
package main
import (
- "time"
+ "errors"
+ "log"
"spreadspace.org/dolmetschctl/pkg/mixer"
)
+type State int
+
+const (
+ StateNew = iota
+ StateSettling
+ StateSettled
+)
+
+func (s State) String() string {
+ switch s {
+ case StateNew:
+ return "new"
+ case StateSettling:
+ return "settling"
+ case StateSettled:
+ return "settled"
+ default:
+ return "unknown"
+ }
+}
+
type Language string
+type LanguageChannels struct {
+ main mixer.Channel
+ voice mixer.Channel
+}
+
+type selectLangRequest struct {
+ l Language
+ resultCh chan error
+}
+
type StateMachine struct {
mixer *mixer.Mixer
- selectLangCh chan Language
+ selectLangCh chan selectLangRequest
quitCh chan bool
exitedCh chan struct{}
+
+ languages map[Language]LanguageChannels
+
+ currentState State
+ currentLang Language
+ targetLang Language
}
func NewStateMachine(m *mixer.Mixer) (*StateMachine, error) {
sm := &StateMachine{mixer: m}
- sm.selectLangCh = make(chan Language, 10)
+ sm.selectLangCh = make(chan selectLangRequest, 10)
sm.quitCh = make(chan bool, 1)
sm.exitedCh = make(chan struct{})
+
+ sm.languages = make(map[Language]LanguageChannels)
+ sm.languages["en"] = LanguageChannels{0x20, 0x24}
+ sm.languages["de"] = LanguageChannels{0x22, 0x25}
+
+ sm.currentState = StateNew
+ sm.currentLang = ""
+ sm.targetLang = ""
+
return sm, nil
}
-func (sm *StateMachine) selectLang(l Language) {
- sm.mixer.UnMute(0x24)
- sm.mixer.SetLevel(0x24, 42)
- time.Sleep(2 * time.Second)
- sm.mixer.Mute(0x24)
- sm.mixer.SetLevel(0x24, mixer.FaderLevel0db)
+func (sm *StateMachine) selectLang(l Language) error {
+ if l != "" {
+ if _, exists := sm.languages[l]; !exists {
+ return errors.New("language '" + string(l) + "' does not exist")
+ }
+ }
+ sm.targetLang = l
+ log.Printf("new target language: '%s'", sm.targetLang)
+ return nil
+}
+
+func (sm *StateMachine) reconcile() {
+ if sm.targetLang == sm.currentLang {
+ sm.currentState = StateSettled
+ return
+ }
+ sm.currentState = StateSettling
}
func (sm *StateMachine) run() {
@@ -58,11 +116,17 @@ func (sm *StateMachine) run() {
for {
select {
- case l := <-sm.selectLangCh:
- sm.selectLang(l)
+ case req := <-sm.selectLangCh:
+ req.resultCh <- sm.selectLang(req.l)
case <-sm.quitCh:
return
}
+
+ oldState := sm.currentState
+ sm.reconcile()
+ if oldState != sm.currentState {
+ log.Printf("new state: %s", sm.currentState)
+ }
}
}
@@ -70,8 +134,10 @@ func (sm *StateMachine) Start() {
go sm.run()
}
-func (sm *StateMachine) SelectLanguage(l Language) {
- sm.selectLangCh <- l
+func (sm *StateMachine) SelectLanguage(l Language) error {
+ resultCh := make(chan error)
+ sm.selectLangCh <- selectLangRequest{l, resultCh}
+ return <-resultCh
}
func (sm *StateMachine) Shutdown() {
diff --git a/cmd/dolmetschctld/telnet.go b/cmd/dolmetschctld/telnet.go
new file mode 100644
index 0000000..d2f7fc3
--- /dev/null
+++ b/cmd/dolmetschctld/telnet.go
@@ -0,0 +1,68 @@
+//
+// dolmetschctl
+//
+//
+// Copyright (C) 2019 Christian Pointner <equinox@spreadspace.org>
+//
+// This file is part of dolmetschctl.
+//
+// dolmetschctl is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// dolmetschctl is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with dolmetschctl. If not, see <http://www.gnu.org/licenses/>.
+//
+
+package main
+
+import (
+ "fmt"
+
+ "github.com/spreadspace/telgo"
+)
+
+type TelnetInterface struct {
+ server *telgo.Server
+}
+
+func telnetCmdLang(c *telgo.Client, args []string, sm *StateMachine) bool {
+ if len(args) != 2 {
+ c.Sayln("usage: lang <language>")
+ return false
+ }
+ lang := args[1]
+ if lang == "none" {
+ lang = ""
+ }
+ if err := sm.SelectLanguage(Language(lang)); err != nil {
+ c.Sayln(fmt.Sprintf("selecting language failed: %v", err))
+ }
+ return false
+}
+
+func telnetQuit(c *telgo.Client, args []string) bool {
+ return true
+}
+
+func (telnet *TelnetInterface) Run() error {
+ return telnet.server.Run()
+}
+
+func NewTelnetInterface(addr string, sm *StateMachine) (telnet *TelnetInterface, err error) {
+ telnet = &TelnetInterface{}
+
+ cmdlist := make(telgo.CmdList)
+ cmdlist["lang"] = func(c *telgo.Client, args []string) bool { return telnetCmdLang(c, args, sm) }
+ cmdlist["quit"] = telnetQuit
+
+ telnet.server, err = telgo.NewServer(addr, "dolmetschctl> ", cmdlist, nil)
+
+ return
+}
diff --git a/pkg/mixer/mixer.go b/pkg/mixer/mixer.go
index c3040fe..8dfda64 100644
--- a/pkg/mixer/mixer.go
+++ b/pkg/mixer/mixer.go
@@ -29,7 +29,7 @@ import (
"github.com/scgolang/midi"
)
-type MixerChannel uint8
+type Channel uint8
type FaderLevel uint8
type Mixer struct {
@@ -102,15 +102,15 @@ func (m *Mixer) sendMute(channel byte, value byte) error {
return nil
}
-func (m *Mixer) Mute(ch MixerChannel) error {
+func (m *Mixer) Mute(ch Channel) error {
return m.sendMute(byte(ch), 0x7F)
}
-func (m *Mixer) UnMute(ch MixerChannel) error {
+func (m *Mixer) UnMute(ch Channel) error {
return m.sendMute(byte(ch), 0x00)
}
-func (m *Mixer) SetLevel(ch MixerChannel, level FaderLevel) error {
+func (m *Mixer) SetLevel(ch Channel, level FaderLevel) error {
if level > FaderLevelMax {
level = FaderLevelMax
}