// // dolmetschctl // // // Copyright (C) 2019 Christian Pointner // // 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 . // package controller import ( "errors" "fmt" "strings" "github.com/scgolang/midi" ) const ( NOTE_OFFSET_BUTTON = byte(0x00) NUM_BUTTONS = 4 CC_LED = byte(0xB0) NOTE_OFFSET_LED = byte(0x00) NUM_LEDS = 4 LED_OFF = byte(0x00) LED_ON = byte(0x01) LED_TOGGLE = byte(0x02) LED_BLINK_MIN = byte(0x03) LED_BLINK_MAX = byte(0x7f) ) type Controller struct { Dev *midi.Device } func openDevice(devices []*midi.Device, prefix string) (d *midi.Device, err error) { for _, device := range devices { if strings.HasPrefix(device.Name, prefix) { d = device } } if d == nil { return nil, errors.New("could not find device with prefix: " + prefix) } return d, d.Open() } func NewController(c Config) (*Controller, error) { devices, err := midi.Devices() if err != nil { return nil, err } ctrl := &Controller{} if ctrl.Dev, err = openDevice(devices, c.Dev); err != nil { return nil, err } ctrl.Dev.QueueSize = 100 return ctrl, nil } func (c *Controller) Init() error { return nil } func (c *Controller) Shutdown() error { if c.Dev != nil { c.Dev.Close() } // TODO: also close all subscribed channels // terminate go-routine started by Init() return nil } func (c *Controller) setLed(num byte, value byte) error { if num >= NUM_LEDS { return fmt.Errorf("this controller has only %d leds.", NUM_LEDS) } n, err := c.Dev.Write([]byte{CC_LED, NOTE_OFFSET_LED + num, value}) if err != nil { // reopen device? return err } if n != 3 { return errors.New("sending LED command failed.") } return nil } func (c *Controller) LedOff(num byte) error { return c.setLed(num, LED_OFF) } func (c *Controller) LedOn(num byte) error { return c.setLed(num, LED_ON) } func (c *Controller) LedToggle(num byte) error { return c.setLed(num, LED_TOGGLE) } func (c *Controller) LedBlink(num, wait byte) error { if (wait + LED_BLINK_MIN) > LED_BLINK_MAX { return fmt.Errorf("blink wait must be between 0 and %d.", LED_BLINK_MAX-LED_BLINK_MIN) } return c.setLed(num, wait+LED_BLINK_MIN) }