72 lines
1.3 KiB
Go
72 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
|
|
"gitlab.com/gomidi/midi/v2"
|
|
"github.com/bendahl/uinput"
|
|
)
|
|
|
|
type ControllerList []*Controller
|
|
|
|
func (cl ControllerList) Stop() {
|
|
for _, controller := range cl {
|
|
controller.Stop()
|
|
}
|
|
}
|
|
|
|
type Controller struct {
|
|
midiInput *MidiInput
|
|
mappings []Mapping
|
|
abortChan chan interface{}
|
|
virtGamepad uinput.Gamepad
|
|
}
|
|
|
|
func NewController(portName string, vendorID, productID uint16) (*Controller, error) {
|
|
midiInput, err := NewMidiInput(portName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
virtGamepad, err := uinput.CreateGamepad("/dev/uinput", []byte(portName), vendorID, productID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
abortChan := make(chan interface{})
|
|
|
|
controller := &Controller{midiInput, nil, abortChan, virtGamepad}
|
|
|
|
go func() {
|
|
for {
|
|
select {
|
|
case midiMessage := <-midiInput.Messages:
|
|
controller.update(midiMessage)
|
|
case <-abortChan:
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
return controller, nil
|
|
}
|
|
|
|
func (c *Controller) AddMapping(mapping Mapping) {
|
|
c.mappings = append(c.mappings, mapping)
|
|
}
|
|
|
|
func (c Controller) Stop() {
|
|
c.midiInput.Stop()
|
|
c.abortChan <- struct{}{}
|
|
c.virtGamepad.Close()
|
|
}
|
|
|
|
func (c Controller) update(msg midi.Message) {
|
|
for _, mapping := range c.mappings {
|
|
err := mapping.TriggerIfMatch(msg, c.virtGamepad)
|
|
if err != nil {
|
|
log.Printf("Error in Mapping \"%s\": %v\n", mapping.Comment(), err)
|
|
}
|
|
}
|
|
}
|