Skip to content

Commit f626ed7

Browse files
committed
added pressure events for Pro Mk3 in XY mode
1 parent 5242dd3 commit f626ed7

File tree

5 files changed

+128
-20
lines changed

5 files changed

+128
-20
lines changed

README.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ Successfully tested with Ubuntu 18.04-LTS+. Requires compiling your own PyGame t
9393
- fixed MF64 LedCtrlString() to correctly work with the background color
9494
- updated hello.py demo file for Midi Fighter 64
9595
- updated demo files to new and recommended default device search strategy
96+
- added Pro Mk3 ButtonStateXY() pressure events
97+
- added demo file "launchpad_pressure_xy()" for new XY pressure events (Pro Mk3, so far)
98+
- fixed MF64 minor init flaw
9699

97100

98101
### CHANGES 2020/08/XX:
@@ -580,8 +583,9 @@ Supported and tested red/green LED Launchpad devices, here referred to as "Clas
580583
Supported and tested full RGB Launchpad devices:
581584

582585
- Launchpad Pro
586+
- Launchpad Pro Mk3
583587
- Launchpad Mk2
584-
- Launchpad Mk3
588+
- Launchpad Mini Mk3
585589
- Launchpad LPX
586590

587591
Supported completely different stuff:
@@ -590,6 +594,7 @@ Supported completely different stuff:
590594
- Launch Control XL
591595
- LaunchKey (Mini)
592596
- Dicer
597+
- Midi Fighter 64
593598

594599
Notice that Novation now (1/2016) sells an RGB Launchpad under the same
595600
name it once shipped the first red/green LED with!
@@ -1053,7 +1058,8 @@ Btw, the fireworks demo will play whenever the Launchpad cannot be enumerated (c
10531058
---
10541059
## Launchpad "Mk2/3", "Pro", "Pro Mk3" and "X" class methods overview (valid for RGB LED devices)
10551060

1056-
Please notice that the Mk3 does not yet have all of these.
1061+
Please notice that some devices do not yet have all of these or are implemented slightly different.
1062+
Refer to the "detailed description of ..." section for each device.
10571063

10581064
### LED functions
10591065

@@ -1077,7 +1083,7 @@ Please notice that the Mk3 does not yet have all of these.
10771083
### Button functions
10781084

10791085
ButtonStateRaw( [returnPressure] )
1080-
ButtonStateXY()
1086+
ButtonStateXY( [mode], [returnPressure] )
10811087
ButtonFlush()
10821088

10831089

@@ -1567,7 +1573,7 @@ There is no possibility to control the RGB LEDs individually.
15671573
---
15681574
## Detailed description of RGB Launchpad only methods
15691575

1570-
Applies to "Pro", "Mk2", "Mk3" and "LPX" unless otherwise noted.
1576+
Applies to "Pro", "Pro Mk3", "Mk2", "Mini Mk3" and "LPX" unless otherwise noted.
15711577

15721578
### LedSetMode( mode ) *>>> PRO, MK3, LPX ONLY <<<*
15731579

@@ -1939,7 +1945,7 @@ There is no possibility to control the RGB LEDs individually.
19391945
X:
19401946
The X supports multiple pressure values. For a distinction between button events
19411947
and pressure events, "255" is added to the button number:
1942-
[ 255 + <button>, <True/False> ]
1948+
[ 255 + <button>, <pressure> ]
19431949

19441950
PARAMS:
19451951
RETURN: [ ] An empty list if no event occured, otherwise...
@@ -1955,21 +1961,42 @@ There is no possibility to control the RGB LEDs individually.
19551961
of the pressure (0..127).
19561962

19571963

1958-
### ButtonStateXY( [mode] )
1964+
### ButtonStateXY( [mode], [returnPressure] )
19591965

1960-
Returns the state of the buttons in X/Y mode.
1966+
Returns the state of the buttons in X/Y mode and optionally the pressure value.
19611967

19621968
Notice that this is not directly compatible with the "Mk1" ButtonStateRaw()
19631969
method, which returns [ <button>, <True/False> ].
19641970

1971+
Only the Pro, X and Pro Mk3 support pressure events.
1972+
They can be enables by passing "returnPressure=True" to the method call.
1973+
Notice that the Pro and X behave differently:
1974+
1975+
Pro and Pro Mk3:
1976+
There is only one pressure value for all buttons together. If multiple buttons
1977+
are pressed, the biggest value is returned. There is no possibility to determine
1978+
which button caused it. To distinguish the pressure events from button events,
1979+
fake coordinates of "255" are returned in the list: [ 255, 255, <value>].
1980+
1981+
X:
1982+
The X supports multiple pressure values. For a distinction between button events
1983+
and pressure events, "255" is added to the coordinate:
1984+
[ <x> + 255, <y> + 255, <value> ]
1985+
19651986
PARAMS: <mode> OPTIONAL: "pro" selects new x/y origin >>> PRO ONLY <<<
19661987
RETURN: [ ] An empty list if no event occured, otherwise...
19671988
[ <x>, <y>, <value> ] ... a list with three fields:
1968-
<x> and <y> are the button's coordinates. The third field, <value> determines
1969-
the intensity (0..127) with which the button was pressed.
1970-
0 means that the button was released.
1971-
Notice that "Mk2" Pads will only return either 0 or 127.
1972-
They don't have the full analog mode like the "Pro" has.
1989+
<x> and <y> are the button's coordinates. The third field, <value> determines
1990+
the intensity (0..127) with which the button was pressed.
1991+
0 means that the button was released.
1992+
Notice that "Mk2" Pads will only return either 0 or 127.
1993+
They don't have the full analog mode like the "Pro" has.
1994+
[ 255, 255, <value> ] ... PRO: a list of pressure events with two fields:
1995+
"255" as an indicator for a pressure event and <value> for the the intensity
1996+
of the pressure (0..127).
1997+
[ <x> + 255, <y> + 255, <value> ] ... LPX: a list of pressure events with two fields:
1998+
"255" added to the <x> and <y> coordinates for a pressure event and <value> for the intensity
1999+
of the pressure (0..127).
19732000

19742001

19752002

examples/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
!launchpad_rgb.py
99
!launchpad_rgb-pulse.py
1010
!launchpad_pressure.py
11+
!launchpad_pressure_xy.py
1112
!launchpad_pro_mk3_reset.py
1213
!midifighter_text.py
1314
!midifighter_led_modes.py

examples/launchpad_pressure.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,3 @@ def main():
7272

7373
if __name__ == '__main__':
7474
main()
75-

examples/launchpad_pressure_xy.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python
2+
#
3+
# Quick demo of the new, optional "pressure events" for supported Launchpads.
4+
# Works with: Pro Mk3
5+
#
6+
#
7+
# FMMT666(ASkr) 7/2013..9/2020
8+
# www.askrprojects.net
9+
#
10+
11+
import sys
12+
13+
try:
14+
import launchpad_py as launchpad
15+
except ImportError:
16+
try:
17+
import launchpad
18+
except ImportError:
19+
sys.exit("error loading launchpad.py")
20+
21+
22+
def main():
23+
24+
mode = None
25+
26+
if launchpad.LaunchpadProMk3().Check( 0 ):
27+
lp = launchpad.LaunchpadProMk3()
28+
if lp.Open( 0 ):
29+
mode = "promk3"
30+
# elif launchpad.LaunchpadPro().Check( 0 ):
31+
# lp = launchpad.LaunchpadPro()
32+
# if lp.Open( 0 ):
33+
# mode = "pro"
34+
# elif launchpad.LaunchpadLPX().Check ( 1 ):
35+
# lp = launchpad.LaunchpadLPX()
36+
# if lp.Open( 1 ):
37+
# mode = "lpx"
38+
39+
if mode is None:
40+
print("no compatible Launchpad found ...")
41+
return
42+
43+
while(True):
44+
# enable the "pressure" feature by calling ButtonStateXY with
45+
# "returnPressure" set to True
46+
events = lp.ButtonStateXY( returnPressure = True )
47+
if events != []:
48+
# x and y button codes of >=255 indicate that this is a pressure value
49+
if events[0] >= 255 and events[1] >= 255:
50+
# The pressure events are different for the Pro and X:
51+
# PRO:
52+
# The pressure value is not related to a specific button. It always returns
53+
# a fake coordinate of "255", so that the pressure events can be distinguished
54+
# from the standard button-press events.
55+
# If two or more buttons are hold at the same time, the biggest value will be returned.
56+
# Because this is the XY methods, X and Y contain 255.
57+
# LPX:
58+
# Returns a per-button pressure event.
59+
# To distinguish pressure events from button events, "255" is added to the X/Y coordinates.
60+
if mode == "pro" or mode == "promk3":
61+
print(" PRESSURE: " + str(events[2]) )
62+
else:
63+
print(" PRESSURE: " + str(events[0]-255) + " " + str(events[1]) )
64+
65+
else:
66+
# the standard button events
67+
if events[2] > 0:
68+
print(" PRESSED: ", end='')
69+
else:
70+
print(" RELEASED: ", end='')
71+
# TODO
72+
print( str(events[0]) + " " + str(events[2]) )
73+
74+
75+
if __name__ == '__main__':
76+
main()

launchpad_py/launchpad.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,7 +2855,7 @@ def __init__( self ):
28552855
self.MODE_ANIM_STAR = 52
28562856
self.MODE_ANIM_TRIANGLE = 53
28572857

2858-
return super( MidiFighter64, self ).__init__( )
2858+
super( MidiFighter64, self ).__init__( )
28592859

28602860

28612861

@@ -3340,7 +3340,7 @@ def LedAllOn( self, colorcode = None ):
33403340
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
33413341
#-- Compatibility would require checking via "== True" and not "is True".
33423342
#-------------------------------------------------------------------------------------
3343-
def ButtonStateXY( self, mode = "classic" ):
3343+
def ButtonStateXY( self, mode = "classic", returnPressure = False ):
33443344
if self.midi.ReadCheck():
33453345
a = self.midi.ReadRaw()
33463346

@@ -3349,10 +3349,12 @@ def ButtonStateXY( self, mode = "classic" ):
33493349
# events. Because we don't handle them here (yet), polling to slowly might create
33503350
# very long lags...
33513351
# 8/2020: Try to mitigate that a bit (yep, seems to work fine!)
3352-
while a[0][0][0] == 208:
3353-
a = self.midi.ReadRaw()
3354-
if a == []:
3355-
return []
3352+
# 9/2020: XY now also with pressure event functionality
3353+
if returnPressure == False:
3354+
while a[0][0][0] == 208:
3355+
a = self.midi.ReadRaw()
3356+
if a == []:
3357+
return []
33563358

33573359
if a[0][0][0] == 144 or a[0][0][0] == 176:
33583360

@@ -3369,7 +3371,10 @@ def ButtonStateXY( self, mode = "classic" ):
33693371

33703372
return [ x, y, a[0][0][2] ]
33713373
else:
3372-
return []
3374+
if a[0][0][0] == 208:
3375+
return [ 255, 255, a[0][0][1] ]
3376+
else:
3377+
return []
33733378
else:
33743379
return []
33753380

0 commit comments

Comments
 (0)