Skip to content

Commit 6950cb7

Browse files
committed
some cleanups
1 parent da5c5ba commit 6950cb7

File tree

2 files changed

+51
-75
lines changed

2 files changed

+51
-75
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ Load and use the module with
401401
lp = launchpad_py.LaunchpadLPX()
402402
# Pro Launchpad:
403403
lp = launchpad_py.LaunchpadPro()
404+
# Pro Mk3 Launchpad:
405+
lp = launchpad_py.LaunchpadProMk3()
404406
# Control:
405407
lp = launchpad_py.LaunchControl()
406408
# Control XL:
@@ -420,6 +422,7 @@ or if you dislike typing that much, use
420422
lp = lppy.LaunchpadMiniMk3()
421423
lp = lppy.LaunchpadLPX()
422424
lp = lppy.LaunchpadPro()
425+
lp = lppy.LaunchpadProMk3()
423426
lp = lppy.LaunchControl()
424427
lp = lppy.LaunchControlXL()
425428
lp = lppy.LaunchKeyMini()
@@ -2817,7 +2820,6 @@ There is no possibility to control the RGB LEDs individually.
28172820
+---+---+---+---+---+---+---+---+
28182821
|101|102| | | | | |108|
28192822
+---+---+---+---+---+---+---+---+
2820-
+---+---+---+---+---+---+---+---+
28212823
| 1| 2| | | | | | 8|
28222824
+---+---+---+---+---+---+---+---+
28232825

launchpad_py/launchpad.py

Lines changed: 48 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ def GetTime( self ):
246246
########################################################################################
247247
### CLASS LaunchpadBase
248248
###
249-
### Todo: Could be abstract, but "abc" and "ABCMeta" are somehow a PITA...
250249
########################################################################################
251250
class LaunchpadBase( object ):
252251

@@ -512,7 +511,10 @@ def LedCtrlAutomap( self, number, red, green ):
512511
if number < 0 or number > 7:
513512
return
514513

515-
# TODO: limit red/green
514+
red = min( 0, red )
515+
red = max( 7, red )
516+
green = min( 0, green )
517+
green = max( 7, green )
516518
led = self.LedGetColor( red, green )
517519

518520
self.midi.RawWrite( 176, 104 + number, led )
@@ -554,40 +556,39 @@ def LedCtrlChar( self, char, red, green, offsx = 0, offsy = 0 ):
554556

555557

556558
#-------------------------------------------------------------------------------------
557-
#-- Scroll <string>, in colors specified by <red/green>, as fast as we can.
559+
#-- Scroll <text>, in colors specified by <red/green>, as fast as we can.
558560
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
559561
#-- The delays were a dirty hack, but there's little to nothing one can do here.
560562
#-- So that's how the <waitms> parameter came into play...
561563
#-- NEW 12/2016: More than one char on display \o/
562564
#-- IDEA: variable spacing for seamless scrolling, e.g.: "__/\_"
563565
#-------------------------------------------------------------------------------------
564-
def LedCtrlString( self, string, red, green, direction = None, waitms = 150 ):
566+
def LedCtrlString( self, text, red, green, direction = None, waitms = 150 ):
565567

566568
limit = lambda n, mini, maxi: max(min(maxi, n), mini)
567569

568570
if direction == self.SCROLL_LEFT:
569-
string += " "
570-
for n in range( (len(string) + 1) * 8 ):
571-
if n <= len(string)*8:
572-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], red, green, 8- n %16 )
571+
text += " "
572+
for n in range( (len(text) + 1) * 8 ):
573+
if n <= len(text)*8:
574+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], red, green, 8- n %16 )
573575
if n > 7:
574-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], red, green, 8-(n-8)%16 )
576+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], red, green, 8-(n-8)%16 )
575577
time.wait(waitms)
576578
elif direction == self.SCROLL_RIGHT:
577579
# TODO: Just a quick hack (screen is erased before scrolling begins).
578580
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
579581
# e.g. 'C' will have artifacts at the left (pixel repeated).
580-
string = " " + string + " " # just to avoid artifacts on full width characters
581-
# for n in range( (len(string) + 1) * 8 - 1, 0, -1 ):
582-
for n in range( (len(string) + 1) * 8 - 7, 0, -1 ):
583-
if n <= len(string)*8:
584-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], red, green, 8- n %16 )
582+
text = " " + text + " " # just to avoid artifacts on full width characters
583+
# for n in range( (len(text) + 1) * 8 - 1, 0, -1 ):
584+
for n in range( (len(text) + 1) * 8 - 7, 0, -1 ):
585+
if n <= len(text)*8:
586+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], red, green, 8- n %16 )
585587
if n > 7:
586-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], red, green, 8-(n-8)%16 )
588+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], red, green, 8-(n-8)%16 )
587589
time.wait(waitms)
588590
else:
589-
# TODO: ah, uh, oh, wat?
590-
for i in string:
591+
for i in text:
591592
for n in range(4): # pseudo repetitions to compensate the timing a bit
592593
self.LedCtrlChar(i, red, green)
593594
time.wait(waitms)
@@ -812,7 +813,7 @@ def LedCtrlBpm( self, bpm ):
812813
# basically int( 1000 / ( bpm * 24 / 60.0 ) ):
813814
td = int( 2500 / bpm )
814815

815-
for i in range( 28 ):
816+
for _ in range( 28 ):
816817
self.midi.RawWrite( 248, 0, 0 )
817818
time.wait( td )
818819

@@ -1053,7 +1054,7 @@ def LedCtrlChar( self, char, red, green, blue = None, offsx = 0, offsy = 0 ):
10531054

10541055

10551056
#-------------------------------------------------------------------------------------
1056-
#-- Scroll <string>, with color specified by <red/green/blue>, as fast as we can.
1057+
#-- Scroll <text>, with color specified by <red/green/blue>, as fast as we can.
10571058
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
10581059
#-- If <blue> is omitted, "Classic" compatibility mode is turned on and the old
10591060
#-- 0..3 color intensity range is streched by 21 to 0..63.
@@ -1062,7 +1063,7 @@ def LedCtrlChar( self, char, red, green, blue = None, offsx = 0, offsy = 0 ):
10621063
#-- IDEA: variable spacing for seamless scrolling, e.g.: "__/\_"
10631064
#-- TODO: That <blue> compatibility thing sucks... Should be removed.
10641065
#-------------------------------------------------------------------------------------
1065-
def LedCtrlString( self, string, red, green, blue = None, direction = None, waitms = 150 ):
1066+
def LedCtrlString( self, text, red, green, blue = None, direction = None, waitms = 150 ):
10661067

10671068
# compatibility mode
10681069
if blue is None:
@@ -1073,28 +1074,27 @@ def LedCtrlString( self, string, red, green, blue = None, direction = None, wait
10731074
limit = lambda n, mini, maxi: max(min(maxi, n), mini)
10741075

10751076
if direction == self.SCROLL_LEFT:
1076-
string += " " # just to avoid artifacts on full width characters
1077-
for n in range( (len(string) + 1) * 8 ):
1078-
if n <= len(string)*8:
1079-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], red, green, blue, 8- n %16 )
1077+
text += " " # just to avoid artifacts on full width characters
1078+
for n in range( (len(text) + 1) * 8 ):
1079+
if n <= len(text)*8:
1080+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], red, green, blue, 8- n %16 )
10801081
if n > 7:
1081-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], red, green, blue, 8-(n-8)%16 )
1082+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], red, green, blue, 8-(n-8)%16 )
10821083
time.wait(waitms)
10831084
elif direction == self.SCROLL_RIGHT:
10841085
# TODO: Just a quick hack (screen is erased before scrolling begins).
10851086
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
10861087
# e.g. 'C' will have artifacts at the left (pixel repeated).
1087-
string = " " + string + " " # just to avoid artifacts on full width characters
1088-
# for n in range( (len(string) + 1) * 8 - 1, 0, -1 ):
1089-
for n in range( (len(string) + 1) * 8 - 7, 0, -1 ):
1090-
if n <= len(string)*8:
1091-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], red, green, blue, 8- n %16 )
1088+
text = " " + text + " " # just to avoid artifacts on full width characters
1089+
# for n in range( (len(text) + 1) * 8 - 1, 0, -1 ):
1090+
for n in range( (len(text) + 1) * 8 - 7, 0, -1 ):
1091+
if n <= len(text)*8:
1092+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], red, green, blue, 8- n %16 )
10921093
if n > 7:
1093-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], red, green, blue, 8-(n-8)%16 )
1094+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], red, green, blue, 8-(n-8)%16 )
10941095
time.wait(waitms)
10951096
else:
1096-
# TODO: not a good idea :)
1097-
for i in string:
1097+
for i in text:
10981098
for n in range(4): # pseudo repetitions to compensate the timing a bit
10991099
self.LedCtrlChar(i, red, green, blue)
11001100
time.wait(waitms)
@@ -1195,7 +1195,6 @@ def ButtonStateRaw( self, returnPressure = False ):
11951195
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
11961196
#-- <value> is the intensity from 0..127.
11971197
#-- >0 = button pressed; 0 = button released
1198-
#-- A constant force ("push longer") is suppressed here... (TODO)
11991198
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
12001199
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
12011200
#-- Compatibility would require checking via "== True" and not "is True".
@@ -1204,12 +1203,6 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
12041203
if self.midi.ReadCheck():
12051204
a = self.midi.ReadRaw()
12061205

1207-
# TODO:
1208-
# Pressing and not releasing a button will create hundreds of "pressure value" (208)
1209-
# events. Because we don't handle them here (yet), polling to slowly might create
1210-
# very long lags...
1211-
# 8/2020: Try to mitigate that a bit (yep, seems to work fine!)
1212-
# 9/2020: Now officially with optional pressure support
12131206
if returnPressure == False:
12141207
while a[0][0][0] == 208:
12151208
a = self.midi.ReadRaw()
@@ -2334,7 +2327,6 @@ class LaunchpadMiniMk3( LaunchpadPro ):
23342327
#-- Uses search string "MiniMk3", by default.
23352328
#-------------------------------------------------------------------------------------
23362329
# Overrides "LaunchpadPro" method
2337-
# TODO: Find a fix for the two MK3 MIDI devices
23382330
def Open( self, number = 0, name = "MiniMK3" ):
23392331
retval = super( LaunchpadMiniMk3, self ).Open( number = number, name = name )
23402332
if retval == True:
@@ -2759,7 +2751,6 @@ def ButtonStateRaw( self, returnPressure = False ):
27592751
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
27602752
#-- <value> is the intensity from 0..127.
27612753
#-- >0 = button pressed; 0 = button released
2762-
#-- A constant force ("push longer") is suppressed here... (TODO)
27632754
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
27642755
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
27652756
#-- Compatibility would require checking via "== True" and not "is True".
@@ -2769,12 +2760,7 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
27692760
if self.midi.ReadCheck():
27702761
a = self.midi.ReadRaw()
27712762

2772-
# TODO:
2773-
# Pressing and not releasing a button will create hundreds of "pressure value" (160)
2774-
# events. Because we don't handle them here (yet), polling to slowly might create
2775-
# very long lags...
27762763
# 8/2020: Copied from the Pro.
2777-
# Try to mitigate that a bit (yep, seems to work fine!)
27782764
# 9/2020: now also _with_ pressure :)
27792765
if returnPressure == False:
27802766
while a[0][0][0] == 160:
@@ -2985,38 +2971,37 @@ def LedCtrlChar( self, char, colorcode, offsx = 0, offsy = 0, coloroff = 0 ):
29852971

29862972

29872973
#-------------------------------------------------------------------------------------
2988-
#-- Scroll <string>, with color specified by <colorcode>, as fast as we can.
2974+
#-- Scroll <text>, with color specified by <colorcode>, as fast as we can.
29892975
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
29902976
#-- Notice that the call to this method is not compatible to the Launchpad variants,
29912977
#-- because the Midi Fighter lacks support for RGB.
29922978
#-------------------------------------------------------------------------------------
2993-
def LedCtrlString( self, string, colorcode, coloroff=0, direction = None, waitms = 150 ):
2979+
def LedCtrlString( self, text, colorcode, coloroff=0, direction = None, waitms = 150 ):
29942980

29952981
limit = lambda n, mini, maxi: max(min(maxi, n), mini)
29962982

29972983
if direction == self.SCROLL_LEFT:
2998-
string += " " # just to avoid artifacts on full width characters
2999-
for n in range( (len(string) + 1) * 8 ):
3000-
if n <= len(string)*8:
3001-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], colorcode, 8- n %16, coloroff = coloroff )
2984+
text += " " # just to avoid artifacts on full width characters
2985+
for n in range( (len(text) + 1) * 8 ):
2986+
if n <= len(text)*8:
2987+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], colorcode, 8- n %16, coloroff = coloroff )
30022988
if n > 7:
3003-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], colorcode, 8-(n-8)%16, coloroff = coloroff )
2989+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], colorcode, 8-(n-8)%16, coloroff = coloroff )
30042990
time.wait(waitms)
30052991
elif direction == self.SCROLL_RIGHT:
30062992
# TODO: Just a quick hack (screen is erased before scrolling begins).
30072993
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
30082994
# e.g. 'C' will have artifacts at the left (pixel repeated).
3009-
string = " " + string + " " # just to avoid artifacts on full width characters
3010-
# for n in range( (len(string) + 1) * 8 - 1, 0, -1 ):
3011-
for n in range( (len(string) + 1) * 8 - 7, 0, -1 ):
3012-
if n <= len(string)*8:
3013-
self.LedCtrlChar( string[ limit( ( n //16)*2 , 0, len(string)-1 ) ], colorcode, 8- n %16, coloroff = coloroff )
2995+
text = " " + text + " " # just to avoid artifacts on full width characters
2996+
# for n in range( (len(text) + 1) * 8 - 1, 0, -1 ):
2997+
for n in range( (len(text) + 1) * 8 - 7, 0, -1 ):
2998+
if n <= len(text)*8:
2999+
self.LedCtrlChar( text[ limit( ( n //16)*2 , 0, len(text)-1 ) ], colorcode, 8- n %16, coloroff = coloroff )
30143000
if n > 7:
3015-
self.LedCtrlChar( string[ limit( (((n-8)//16)*2) + 1, 0, len(string)-1 ) ], colorcode, 8-(n-8)%16, coloroff = coloroff )
3001+
self.LedCtrlChar( text[ limit( (((n-8)//16)*2) + 1, 0, len(text)-1 ) ], colorcode, 8-(n-8)%16, coloroff = coloroff )
30163002
time.wait(waitms)
30173003
else:
3018-
# TODO: not a good idea :)
3019-
for i in string:
3004+
for i in text:
30203005
for n in range(4): # pseudo repetitions to compensate the timing a bit
30213006
self.LedCtrlChar(i, colorcode, coloroff = coloroff)
30223007
time.wait(waitms)
@@ -3106,10 +3091,6 @@ def ButtonStateXY( self ):
31063091
#-------------------------------------------------------------------------------------
31073092
def Reset( self ):
31083093
# TODO
3109-
# Nope, there's not color code for "off".
3110-
# Brightness can be set via channel 4, though it's not clear
3111-
# if that helps us here, as the manual files this under "animation settings".
3112-
# Also, setting the brightness to 0/off might cause additional trouble.
31133094
# self.LedAllOn( 0 )
31143095
pass
31153096

@@ -3149,7 +3130,6 @@ class LaunchpadProMk3( LaunchpadPro ):
31493130
# +---+---+---+---+---+---+---+---+
31503131
# |101|102| | | | | |108|
31513132
# +---+---+---+---+---+---+---+---+
3152-
# +---+---+---+---+---+---+---+---+
31533133
# | 1| 2| | | | | | 8|
31543134
# +---+---+---+---+---+---+---+---+
31553135
#
@@ -3223,7 +3203,6 @@ class LaunchpadProMk3( LaunchpadPro ):
32233203
#-- Uses search string "ProMK3", by default.
32243204
#-------------------------------------------------------------------------------------
32253205
# Overrides "LaunchpadPro" method
3226-
# TODO: Find a fix for the two ProMk3 MIDI devices
32273206
def Open( self, number = 0, name = "ProMk3" ):
32283207
retval = super( LaunchpadProMk3, self ).Open( number = number, name = name )
32293208
if retval == True:
@@ -3346,7 +3325,6 @@ def LedAllOn( self, colorcode = None ):
33463325
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
33473326
#-- <value> is the intensity from 0..127.
33483327
#-- >0 = button pressed; 0 = button released
3349-
#-- A constant force ("push longer") is suppressed here... (TODO)
33503328
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
33513329
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
33523330
#-- Compatibility would require checking via "== True" and not "is True".
@@ -3355,11 +3333,7 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
33553333
if self.midi.ReadCheck():
33563334
a = self.midi.ReadRaw()
33573335

3358-
# TODO:
3359-
# Pressing and not releasing a button will create hundreds of "pressure value" (208)
3360-
# events. Because we don't handle them here (yet), polling to slowly might create
3361-
# very long lags...
3362-
# 8/2020: Try to mitigate that a bit (yep, seems to work fine!)
3336+
# 8/2020: Try to mitigate too many pressure events that a bit (yep, seems to work fine!)
33633337
# 9/2020: XY now also with pressure event functionality
33643338
if returnPressure == False:
33653339
while a[0][0][0] == 208:

0 commit comments

Comments
 (0)