|
@@ -0,0 +1,131 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import "time"
|
|
|
+import "log"
|
|
|
+import "fmt"
|
|
|
+import "os"
|
|
|
+import "os/signal"
|
|
|
+import "syscall"
|
|
|
+import "github.com/stianeikeland/go-rpio/v4"
|
|
|
+import "github.com/hypebeast/go-osc/osc"
|
|
|
+
|
|
|
+const (
|
|
|
+ // TX series codes
|
|
|
+ AMP_Input_CD = 0x020 // ATEM
|
|
|
+ AMP_Input_MD = 0x030
|
|
|
+ AMP_Input_Tape = 0x070
|
|
|
+ AMP_Input_DVD = 0x120
|
|
|
+ AMP_Input_CDR = 0x130 // Assigned to tape by holding button for 3 secs
|
|
|
+ AMP_Input_HDD = 0x170 // Assigned to video or tape by holding button for 3 secs
|
|
|
+ AMP_Input_Video = 0x1a0
|
|
|
+
|
|
|
+ AMP_PowerOn_OrMask = 0x0f
|
|
|
+
|
|
|
+ // These work only when video input is selected
|
|
|
+ AMP_Vol_up = 0x1a2
|
|
|
+ AMP_Vol_down = 0x1a3
|
|
|
+ AMP_Vol_mute = 0x1a4
|
|
|
+ AMP_Vol_unmute = 0x1a5
|
|
|
+ AMP_Off = 0x1ae
|
|
|
+ AMP_On = 0x1af
|
|
|
+
|
|
|
+ // Dimmer
|
|
|
+ AMP_DimmerHi = 0x2b0
|
|
|
+ AMP_DimmerMid = 0x2b1
|
|
|
+ AMP_DimmerLo = 0x2b2
|
|
|
+
|
|
|
+ // Test modes
|
|
|
+ Test_mode = 0x421
|
|
|
+)
|
|
|
+
|
|
|
+type IR struct {
|
|
|
+ pin rpio.Pin
|
|
|
+}
|
|
|
+
|
|
|
+func NewIR() *IR {
|
|
|
+ if err := rpio.Open(); err != nil {
|
|
|
+ log.Fatal(err)
|
|
|
+ }
|
|
|
+ //defer rpio.Close()
|
|
|
+
|
|
|
+ pin := rpio.Pin(26)
|
|
|
+ pin.Output() // Output mode
|
|
|
+ return &IR{pin}
|
|
|
+}
|
|
|
+
|
|
|
+// Encode a bit of IR information
|
|
|
+func (ir *IR) sendHiLo(hi time.Duration, lo time.Duration) {
|
|
|
+ ir.pin.High()
|
|
|
+ time.Sleep(hi * time.Millisecond)
|
|
|
+
|
|
|
+ ir.pin.Low()
|
|
|
+ time.Sleep(lo * time.Millisecond)
|
|
|
+}
|
|
|
+
|
|
|
+func (ir *IR) sendCode(code int) {
|
|
|
+ // Send header
|
|
|
+ ir.sendHiLo(3, 1)
|
|
|
+
|
|
|
+ // Send 12 bits of command
|
|
|
+ for mask := 0x800; mask != 0; mask >>= 1 {
|
|
|
+ if code&mask != 0 {
|
|
|
+ ir.sendHiLo(1, 2) // 1
|
|
|
+ } else {
|
|
|
+ ir.sendHiLo(1, 1) // 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Send end gap
|
|
|
+ ir.sendHiLo(1, 21)
|
|
|
+ fmt.Printf("Sent code: %03x\n", code)
|
|
|
+}
|
|
|
+
|
|
|
+func getOSCInt(msg *osc.Message) int32 {
|
|
|
+ for _, arg := range msg.Arguments {
|
|
|
+ switch arg.(type) {
|
|
|
+ case int32:
|
|
|
+ return arg.(int32)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func main() {
|
|
|
+ ir := NewIR()
|
|
|
+
|
|
|
+ // Setup and spawn the OSC server
|
|
|
+ addr := "0.0.0.0:9137"
|
|
|
+ d := osc.NewStandardDispatcher()
|
|
|
+
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/tape", func(msg *osc.Message) { ir.sendCode(AMP_Input_Tape) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/md", func(msg *osc.Message) { ir.sendCode(AMP_Input_MD) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/cd", func(msg *osc.Message) { ir.sendCode(AMP_Input_CD) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/cdr", func(msg *osc.Message) { ir.sendCode(AMP_Input_CDR) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/dvd", func(msg *osc.Message) { ir.sendCode(AMP_Input_DVD) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/hdd", func(msg *osc.Message) { ir.sendCode(AMP_Input_HDD) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/input/video", func(msg *osc.Message) { ir.sendCode(AMP_Input_Video) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/vol/up", func(msg *osc.Message) { ir.sendCode(AMP_Vol_up) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/vol/down", func(msg *osc.Message) { ir.sendCode(AMP_Vol_down) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/vol/mute", func(msg *osc.Message) { ir.sendCode(AMP_Vol_mute) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/vol/unmute", func(msg *osc.Message) { ir.sendCode(AMP_Vol_unmute) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/power/on", func(msg *osc.Message) { ir.sendCode(AMP_On) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/power/off", func(msg *osc.Message) { ir.sendCode(AMP_Off) })
|
|
|
+ d.AddMsgHandler("/8bus/amp/code", func(msg *osc.Message) { ir.sendCode(int(getOSCInt(msg))) })
|
|
|
+
|
|
|
+ // Set up and start OSC server
|
|
|
+ go func() {
|
|
|
+ server := &osc.Server{Addr: addr, Dispatcher: d}
|
|
|
+ if err := server.ListenAndServe(); err != nil {
|
|
|
+ log.Fatal("error: ", err.Error())
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ // Wait for signal
|
|
|
+ ch := make(chan os.Signal, 1)
|
|
|
+ signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT)
|
|
|
+
|
|
|
+ d.AddMsgHandler("/8bus/amp/halt", func(msg *osc.Message) { ch <- syscall.SIGINT })
|
|
|
+ <-ch
|
|
|
+
|
|
|
+ fmt.Println("sent")
|
|
|
+}
|