diff --git a/.vscode/settings.json b/.vscode/settings.json index 01cf5f10..48d2e26b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ // Spell checker "cSpell.words": [ + "buttondatastrat", "capsys", "deinitialise", "dicttools", diff --git a/common/eventpattern/forwardedpattern.py b/common/eventpattern/forwardedpattern.py index a5a5cdec..ba9e888e 100644 --- a/common/eventpattern/forwardedpattern.py +++ b/common/eventpattern/forwardedpattern.py @@ -9,6 +9,8 @@ import device from typing import TYPE_CHECKING + +from common.util.events import eventToString from . import IEventPattern from common.types import eventData @@ -40,9 +42,8 @@ def matchEvent(self, event: 'eventData') -> bool: if event.sysex is None \ or not event.sysex.startswith(bytes([0xF0, 0x7D])): return False - # Check if it matches this device's name - null = event.sysex[2:].find(bytes(0)) + null = event.sysex[2:].index(b'\0') + 2 if event.sysex[2:null].decode() != device.getName(): return False @@ -66,4 +67,4 @@ def matchEvent(self, event: 'eventData') -> bool: event.sysex[null+3] ) - return super().matchEvent(decoded) + return self._pattern.matchEvent(decoded) diff --git a/common/util/events.py b/common/util/events.py index 6414b064..1fff1614 100644 --- a/common/util/events.py +++ b/common/util/events.py @@ -54,6 +54,6 @@ def eventToString(event: eventData) -> str: assert event.status is not None assert event.data1 is not None assert event.data2 is not None - return f"(0x{event.status:X}, 0x{event.data1:X}, 0x{event.data2:X})" + return f"(0x{event.status:02X}, 0x{event.data1:02X}, 0x{event.data2:02X})" else: return bytesToString(event.sysex) diff --git a/controlsurfaces/__init__.py b/controlsurfaces/__init__.py index c276d1f2..51b4a78a 100644 --- a/controlsurfaces/__init__.py +++ b/controlsurfaces/__init__.py @@ -11,6 +11,7 @@ from .controlsurface import ControlSurface from .controlshadow import ControlShadow from .controlmapping import ControlMapping +from .valuestrategies import * from .nullevent import * from .pedal import * diff --git a/devices/maudio/hammer88pro/buttondatastrat.py b/devices/maudio/hammer88pro/buttondatastrat.py new file mode 100644 index 00000000..41fc8979 --- /dev/null +++ b/devices/maudio/hammer88pro/buttondatastrat.py @@ -0,0 +1,30 @@ + +from common.types import eventData +from controlsurfaces import IValueStrategy + + +class HammerButtonStrat(IValueStrategy): + """ + Strategy for buttons on Hammer 88 Pro + + Since it mashes events together we need a special way to get the data + """ + def __init__(self, on: int) -> None: + """ + Create Hammer 88 Pro button value strategy + + ### Args: + * `on` (`int`): value interpreted as a press (all others will be + interpreted as a release) + """ + self._on = on + super().__init__() + + def getValueFromEvent(self, event: eventData): + return event.data2 == self._on + + def getValueFromFloat(self, f: float): + return f == 1.0 + + def getFloatFromValue(self, value) -> float: + return 1.0 if value else 0.0 diff --git a/devices/maudio/hammer88pro/hammer88pro.py b/devices/maudio/hammer88pro/hammer88pro.py index 97a4a042..bad73f08 100644 --- a/devices/maudio/hammer88pro/hammer88pro.py +++ b/devices/maudio/hammer88pro/hammer88pro.py @@ -23,6 +23,7 @@ DirectionNext, DirectionPrevious ) +from .buttondatastrat import HammerButtonStrat class Hammer88Pro(Device): @@ -35,10 +36,14 @@ def __init__(self) -> None: matcher.addControl(NullEvent( BasicEventPattern(0xFC, 0x0, 0x0) )) + matcher.addControl(NullEvent( + ForwardedEventPattern(3, BasicEventPattern(0xB0, 0x0F, 0x0E)) + )) + # Transport buttons matcher.addControl(PlayButton( - ForwardedEventPattern(3, BasicEventPattern(0xB0, 0xF, ...)), - ButtonSinglePressStrategy(), + ForwardedEventPattern(3, BasicEventPattern(0xB0, 0x2F, (0x44, 0x4))), + HammerButtonStrat(0x44), "transport" ))