feat(deadzone): Implemented deadzone and improved debug logging verbosity

This commit is contained in:
2025-08-09 16:47:56 +02:00
parent 8a7254a467
commit ff859d6bf7
3 changed files with 24 additions and 10 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/goccy/go-yaml" "github.com/goccy/go-yaml"
"github.com/bendahl/uinput" "github.com/bendahl/uinput"
"github.com/charmbracelet/log"
) )
type Config struct { type Config struct {
@@ -28,6 +29,7 @@ type MappingConfig struct {
Button ButtonName `yaml:"button"` Button ButtonName `yaml:"button"`
Axis AxisName `yaml:"axis"` Axis AxisName `yaml:"axis"`
IsSigned bool `yaml:"isSigned"` IsSigned bool `yaml:"isSigned"`
Deadzone float64 `yaml:"deadzone"`
} }
type MappingType string type MappingType string
@@ -116,6 +118,8 @@ func (mc MappingConfig) Construct() (Mapping, error) {
return ButtonMapping{}, err return ButtonMapping{}, err
} }
log.Debug("Parsed button mapping", "comment", mc.Comment, "midiChannel", mc.MidiChannel, "midiKey", mc.MidiKey, "button", button)
return ButtonMapping{mc.Comment, mc.MidiChannel, mc.MidiKey, button}, nil return ButtonMapping{mc.Comment, mc.MidiChannel, mc.MidiKey, button}, nil
case ControlMappingType: case ControlMappingType:
axis, err := mc.Axis.Construct() axis, err := mc.Axis.Construct()
@@ -123,7 +127,9 @@ func (mc MappingConfig) Construct() (Mapping, error) {
return ControlMapping{}, err return ControlMapping{}, err
} }
return ControlMapping{mc.Comment, mc.MidiChannel, mc.MidiController, axis, mc.IsSigned}, nil log.Debug("Parsed control mapping", "comment", mc.Comment, "midiChannel", mc.MidiChannel, "midiController", mc.MidiController, "axis", axis, "isSigned", mc.IsSigned, "deadzone", mc.Deadzone)
return ControlMapping{mc.Comment, mc.MidiChannel, mc.MidiController, axis, mc.IsSigned, mc.Deadzone}, nil
default: default:
return ButtonMapping{}, fmt.Errorf("Invalid mapping type") return ButtonMapping{}, fmt.Errorf("Invalid mapping type")
} }

View File

@@ -39,9 +39,11 @@ controller:
midiController: 1 midiController: 1
axis: left-x axis: left-x
isSigned: true isSigned: true
deadzone: 0.01
- comment: Filter right - comment: Filter right
type: control type: control
midiChannel: 2 midiChannel: 2
midiController: 1 midiController: 1
axis: right-x axis: right-x
isSigned: true isSigned: true
deadzone: 0.01

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"math"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"gitlab.com/gomidi/midi/v2" "gitlab.com/gomidi/midi/v2"
@@ -39,12 +40,12 @@ func (m ButtonMapping) TriggerIfMatch(msg midi.Message, virtGamepad uinput.Gamep
switch msg.Type() { switch msg.Type() {
case midi.NoteOnMsg: case midi.NoteOnMsg:
if velocity != 0 { if velocity != 0 {
log.Debugf("%s: Button down", m.comment) log.Debug(m.comment, "status", "down")
return virtGamepad.ButtonDown(m.gamepadKey) return virtGamepad.ButtonDown(m.gamepadKey)
} }
fallthrough // if reached here, velocity is 0 -> NoteOff fallthrough // if reached here, velocity is 0 -> NoteOff
case midi.NoteOffMsg: case midi.NoteOffMsg:
log.Debugf("%s: Button up", m.comment) log.Debug(m.comment, "status", "up")
return virtGamepad.ButtonUp(m.gamepadKey) return virtGamepad.ButtonUp(m.gamepadKey)
default: default:
return fmt.Errorf("Invalid message type triggered ButtonMapping") return fmt.Errorf("Invalid message type triggered ButtonMapping")
@@ -73,6 +74,7 @@ type ControlMapping struct {
midiController uint8 midiController uint8
axis ControllerAxis axis ControllerAxis
isSigned bool isSigned bool
deadzone float64
} }
func (m ControlMapping) Is(msg midi.Message) bool { func (m ControlMapping) Is(msg midi.Message) bool {
@@ -89,29 +91,33 @@ func (m ControlMapping) TriggerIfMatch(msg midi.Message, virtGamepad uinput.Game
if m.Is(msg) { if m.Is(msg) {
var ( var (
valueAbsolute uint8 valueAbsolute uint8
valueNormalised float32 valueNormalised float64
) )
msg.GetControlChange(nil, nil, &valueAbsolute) msg.GetControlChange(nil, nil, &valueAbsolute)
// value is 0-127, normalise // value is 0-127, normalise
valueNormalised = float32(valueAbsolute) / 127 valueNormalised = float64(valueAbsolute) / 127
if m.isSigned { if m.isSigned {
valueNormalised *= 2 valueNormalised *= 2
valueNormalised -= 1 valueNormalised -= 1
} }
log.Debugf("%s: value %v", m.comment, valueNormalised) if math.Abs(valueNormalised) < m.deadzone {
valueNormalised = 0
}
log.Debug(m.comment, "value", valueNormalised, "deadzone", m.deadzone)
switch m.axis { switch m.axis {
case LeftX: case LeftX:
return virtGamepad.LeftStickMoveX(valueNormalised) return virtGamepad.LeftStickMoveX(float32(valueNormalised))
case LeftY: case LeftY:
return virtGamepad.LeftStickMoveY(valueNormalised) return virtGamepad.LeftStickMoveY(float32(valueNormalised))
case RightX: case RightX:
return virtGamepad.RightStickMoveX(valueNormalised) return virtGamepad.RightStickMoveX(float32(valueNormalised))
case RightY: case RightY:
return virtGamepad.RightStickMoveY(valueNormalised) return virtGamepad.RightStickMoveY(float32(valueNormalised))
} }
} }