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") }