@@ -246,7 +246,6 @@ def GetTime( self ):
246
246
########################################################################################
247
247
### CLASS LaunchpadBase
248
248
###
249
- ### Todo: Could be abstract, but "abc" and "ABCMeta" are somehow a PITA...
250
249
########################################################################################
251
250
class LaunchpadBase ( object ):
252
251
@@ -512,7 +511,10 @@ def LedCtrlAutomap( self, number, red, green ):
512
511
if number < 0 or number > 7 :
513
512
return
514
513
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 )
516
518
led = self .LedGetColor ( red , green )
517
519
518
520
self .midi .RawWrite ( 176 , 104 + number , led )
@@ -554,40 +556,39 @@ def LedCtrlChar( self, char, red, green, offsx = 0, offsy = 0 ):
554
556
555
557
556
558
#-------------------------------------------------------------------------------------
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.
558
560
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
559
561
#-- The delays were a dirty hack, but there's little to nothing one can do here.
560
562
#-- So that's how the <waitms> parameter came into play...
561
563
#-- NEW 12/2016: More than one char on display \o/
562
564
#-- IDEA: variable spacing for seamless scrolling, e.g.: "__/\_"
563
565
#-------------------------------------------------------------------------------------
564
- def LedCtrlString ( self , string , red , green , direction = None , waitms = 150 ):
566
+ def LedCtrlString ( self , text , red , green , direction = None , waitms = 150 ):
565
567
566
568
limit = lambda n , mini , maxi : max (min (maxi , n ), mini )
567
569
568
570
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 )
573
575
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 )
575
577
time .wait (waitms )
576
578
elif direction == self .SCROLL_RIGHT :
577
579
# TODO: Just a quick hack (screen is erased before scrolling begins).
578
580
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
579
581
# 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 )
585
587
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 )
587
589
time .wait (waitms )
588
590
else :
589
- # TODO: ah, uh, oh, wat?
590
- for i in string :
591
+ for i in text :
591
592
for n in range (4 ): # pseudo repetitions to compensate the timing a bit
592
593
self .LedCtrlChar (i , red , green )
593
594
time .wait (waitms )
@@ -812,7 +813,7 @@ def LedCtrlBpm( self, bpm ):
812
813
# basically int( 1000 / ( bpm * 24 / 60.0 ) ):
813
814
td = int ( 2500 / bpm )
814
815
815
- for i in range ( 28 ):
816
+ for _ in range ( 28 ):
816
817
self .midi .RawWrite ( 248 , 0 , 0 )
817
818
time .wait ( td )
818
819
@@ -1053,7 +1054,7 @@ def LedCtrlChar( self, char, red, green, blue = None, offsx = 0, offsy = 0 ):
1053
1054
1054
1055
1055
1056
#-------------------------------------------------------------------------------------
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.
1057
1058
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
1058
1059
#-- If <blue> is omitted, "Classic" compatibility mode is turned on and the old
1059
1060
#-- 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 ):
1062
1063
#-- IDEA: variable spacing for seamless scrolling, e.g.: "__/\_"
1063
1064
#-- TODO: That <blue> compatibility thing sucks... Should be removed.
1064
1065
#-------------------------------------------------------------------------------------
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 ):
1066
1067
1067
1068
# compatibility mode
1068
1069
if blue is None :
@@ -1073,28 +1074,27 @@ def LedCtrlString( self, string, red, green, blue = None, direction = None, wait
1073
1074
limit = lambda n , mini , maxi : max (min (maxi , n ), mini )
1074
1075
1075
1076
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 )
1080
1081
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 )
1082
1083
time .wait (waitms )
1083
1084
elif direction == self .SCROLL_RIGHT :
1084
1085
# TODO: Just a quick hack (screen is erased before scrolling begins).
1085
1086
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
1086
1087
# 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 )
1092
1093
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 )
1094
1095
time .wait (waitms )
1095
1096
else :
1096
- # TODO: not a good idea :)
1097
- for i in string :
1097
+ for i in text :
1098
1098
for n in range (4 ): # pseudo repetitions to compensate the timing a bit
1099
1099
self .LedCtrlChar (i , red , green , blue )
1100
1100
time .wait (waitms )
@@ -1195,7 +1195,6 @@ def ButtonStateRaw( self, returnPressure = False ):
1195
1195
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
1196
1196
#-- <value> is the intensity from 0..127.
1197
1197
#-- >0 = button pressed; 0 = button released
1198
- #-- A constant force ("push longer") is suppressed here... (TODO)
1199
1198
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
1200
1199
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
1201
1200
#-- Compatibility would require checking via "== True" and not "is True".
@@ -1204,12 +1203,6 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
1204
1203
if self .midi .ReadCheck ():
1205
1204
a = self .midi .ReadRaw ()
1206
1205
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
1213
1206
if returnPressure == False :
1214
1207
while a [0 ][0 ][0 ] == 208 :
1215
1208
a = self .midi .ReadRaw ()
@@ -2334,7 +2327,6 @@ class LaunchpadMiniMk3( LaunchpadPro ):
2334
2327
#-- Uses search string "MiniMk3", by default.
2335
2328
#-------------------------------------------------------------------------------------
2336
2329
# Overrides "LaunchpadPro" method
2337
- # TODO: Find a fix for the two MK3 MIDI devices
2338
2330
def Open ( self , number = 0 , name = "MiniMK3" ):
2339
2331
retval = super ( LaunchpadMiniMk3 , self ).Open ( number = number , name = name )
2340
2332
if retval == True :
@@ -2759,7 +2751,6 @@ def ButtonStateRaw( self, returnPressure = False ):
2759
2751
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
2760
2752
#-- <value> is the intensity from 0..127.
2761
2753
#-- >0 = button pressed; 0 = button released
2762
- #-- A constant force ("push longer") is suppressed here... (TODO)
2763
2754
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
2764
2755
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
2765
2756
#-- Compatibility would require checking via "== True" and not "is True".
@@ -2769,12 +2760,7 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
2769
2760
if self .midi .ReadCheck ():
2770
2761
a = self .midi .ReadRaw ()
2771
2762
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...
2776
2763
# 8/2020: Copied from the Pro.
2777
- # Try to mitigate that a bit (yep, seems to work fine!)
2778
2764
# 9/2020: now also _with_ pressure :)
2779
2765
if returnPressure == False :
2780
2766
while a [0 ][0 ][0 ] == 160 :
@@ -2985,38 +2971,37 @@ def LedCtrlChar( self, char, colorcode, offsx = 0, offsy = 0, coloroff = 0 ):
2985
2971
2986
2972
2987
2973
#-------------------------------------------------------------------------------------
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.
2989
2975
#-- <direction> specifies: -1 to left, 0 no scroll, 1 to right
2990
2976
#-- Notice that the call to this method is not compatible to the Launchpad variants,
2991
2977
#-- because the Midi Fighter lacks support for RGB.
2992
2978
#-------------------------------------------------------------------------------------
2993
- def LedCtrlString ( self , string , colorcode , coloroff = 0 , direction = None , waitms = 150 ):
2979
+ def LedCtrlString ( self , text , colorcode , coloroff = 0 , direction = None , waitms = 150 ):
2994
2980
2995
2981
limit = lambda n , mini , maxi : max (min (maxi , n ), mini )
2996
2982
2997
2983
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 )
3002
2988
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 )
3004
2990
time .wait (waitms )
3005
2991
elif direction == self .SCROLL_RIGHT :
3006
2992
# TODO: Just a quick hack (screen is erased before scrolling begins).
3007
2993
# Characters at odd positions from the right (1, 3, 5), with pixels at the left,
3008
2994
# 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 )
3014
3000
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 )
3016
3002
time .wait (waitms )
3017
3003
else :
3018
- # TODO: not a good idea :)
3019
- for i in string :
3004
+ for i in text :
3020
3005
for n in range (4 ): # pseudo repetitions to compensate the timing a bit
3021
3006
self .LedCtrlChar (i , colorcode , coloroff = coloroff )
3022
3007
time .wait (waitms )
@@ -3106,10 +3091,6 @@ def ButtonStateXY( self ):
3106
3091
#-------------------------------------------------------------------------------------
3107
3092
def Reset ( self ):
3108
3093
# 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.
3113
3094
# self.LedAllOn( 0 )
3114
3095
pass
3115
3096
@@ -3149,7 +3130,6 @@ class LaunchpadProMk3( LaunchpadPro ):
3149
3130
# +---+---+---+---+---+---+---+---+
3150
3131
# |101|102| | | | | |108|
3151
3132
# +---+---+---+---+---+---+---+---+
3152
- # +---+---+---+---+---+---+---+---+
3153
3133
# | 1| 2| | | | | | 8|
3154
3134
# +---+---+---+---+---+---+---+---+
3155
3135
#
@@ -3223,7 +3203,6 @@ class LaunchpadProMk3( LaunchpadPro ):
3223
3203
#-- Uses search string "ProMK3", by default.
3224
3204
#-------------------------------------------------------------------------------------
3225
3205
# Overrides "LaunchpadPro" method
3226
- # TODO: Find a fix for the two ProMk3 MIDI devices
3227
3206
def Open ( self , number = 0 , name = "ProMk3" ):
3228
3207
retval = super ( LaunchpadProMk3 , self ).Open ( number = number , name = name )
3229
3208
if retval == True :
@@ -3346,7 +3325,6 @@ def LedAllOn( self, colorcode = None ):
3346
3325
#-- [ <x>, <y>, <value> ], in which <x> and <y> are the buttons coordinates and
3347
3326
#-- <value> is the intensity from 0..127.
3348
3327
#-- >0 = button pressed; 0 = button released
3349
- #-- A constant force ("push longer") is suppressed here... (TODO)
3350
3328
#-- Notice that this is not (directly) compatible with the original ButtonStateRaw()
3351
3329
#-- method in the "Classic" Launchpad, which only returned [ <button>, <True/False> ].
3352
3330
#-- Compatibility would require checking via "== True" and not "is True".
@@ -3355,11 +3333,7 @@ def ButtonStateXY( self, mode = "classic", returnPressure = False ):
3355
3333
if self .midi .ReadCheck ():
3356
3334
a = self .midi .ReadRaw ()
3357
3335
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!)
3363
3337
# 9/2020: XY now also with pressure event functionality
3364
3338
if returnPressure == False :
3365
3339
while a [0 ][0 ][0 ] == 208 :
0 commit comments