Initial commit

This commit is contained in:
2025-08-03 16:21:33 +02:00
commit 0c0e1e985e
7 changed files with 163 additions and 0 deletions

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# midi-hid
This software allows mapping and translating of MIDI commands to HID inputs on Linux.

53
controller.go Normal file
View File

@@ -0,0 +1,53 @@
package main
import (
"log"
"gitlab.com/gomidi/midi/v2"
)
type Controller struct {
midiInput *MidiInput
mappings []Mapping
abortChan chan interface{}
}
func NewController(portName string) (*Controller, error) {
midiInput, err := NewMidiInput(portName)
if err != nil {
return nil, err
}
abortChan := make(chan interface{})
controller := &Controller{midiInput, nil, abortChan}
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{}{}
}
func (c Controller) update(msg midi.Message) {
for _, mapping := range c.mappings {
if mapping.Is(msg) {
log.Println("Mapping triggered!\n")
}
}
}

5
go.mod Normal file
View File

@@ -0,0 +1,5 @@
module datalore/midi-hid
go 1.24.5
require gitlab.com/gomidi/midi/v2 v2.3.16

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
gitlab.com/gomidi/midi/v2 v2.3.16 h1:yufWSENyjnJ4LFQa9BerzUm4E4aLfTyzw5nmnCteO0c=
gitlab.com/gomidi/midi/v2 v2.3.16/go.mod h1:jDpP4O4skYi+7iVwt6Zyp18bd2M4hkjtMuw2cmgKgfw=

25
main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"log"
"time"
"gitlab.com/gomidi/midi/v2"
)
func must[T any](obj T, err error) T {
if err != nil {
log.Fatal(err)
}
return obj
}
func main() {
defer midi.CloseDriver()
midiInput := must(NewMidiInput("DJControl Inpulse 500 MIDI 1"))
time.Sleep(time.Second * 20)
midiInput.Stop()
}

40
mapping.go Normal file
View File

@@ -0,0 +1,40 @@
package main
import (
"gitlab.com/gomidi/midi/v2"
)
type Mapping interface {
Is(midi.Message) bool
}
type ButtonMapping struct {
midiChannel uint8
midiKey uint8
}
func (m ButtonMapping) Is(msg midi.Message) bool {
var channel, key uint8
switch {
case msg.GetNoteOn(&channel, &key, nil), msg.GetNoteOff(&channel, &key, nil):
return (m.midiChannel == channel && m.midiKey == key)
default:
return false
}
}
type ControlMapping struct {
midiChannel uint8
midiController uint8
}
func (m ControlMapping) Is(msg midi.Message) bool {
var channel, controller uint8
if msg.GetControlChange(&channel, &controller, nil) {
return (m.midiChannel == channel && m.midiController == controller)
} else {
return false
}
}

35
midi.go Normal file
View File

@@ -0,0 +1,35 @@
package main
import (
"gitlab.com/gomidi/midi/v2"
"gitlab.com/gomidi/midi/v2/drivers"
_ "gitlab.com/gomidi/midi/v2/drivers/rtmididrv"
)
type MidiInput struct {
input drivers.In
Messages chan midi.Message
Stop func()
}
func NewMidiInput(portName string) (*MidiInput, error) {
input, err := midi.FindInPort(portName)
if err != nil {
return nil, err
}
messages := make(chan midi.Message)
midiListener := func(msg midi.Message, timestampMs int32) {
if msg.IsOneOf(midi.NoteOnMsg, midi.NoteOffMsg, midi.ControlChangeMsg) {
messages <- msg
}
}
stopFunc, err := midi.ListenTo(input, midiListener, midi.UseSysEx())
if err != nil {
return nil, err
}
return &MidiInput{input, messages, stopFunc}, nil
}