Skip to content

Commit 01bdfb9

Browse files
committed
LPX Support
1 parent 87847af commit 01bdfb9

File tree

1 file changed

+82
-18
lines changed

1 file changed

+82
-18
lines changed

launchpad_py/launchpad.py

Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,23 +2438,22 @@ class LaunchpadLPX( LaunchpadPro ):
24382438

24392439
#-------------------------------------------------------------------------------------
24402440
#-- Opens one of the attached Launchpad MIDI devices.
2441-
#-- Uses search string "Mk3", by default.
2441+
#-- Uses search string "LPX", by default.
24422442
#-------------------------------------------------------------------------------------
24432443
# Overrides "LaunchpadPro" method
24442444
# TODO: Find a fix for the two MK3 MIDI devices
24452445
def Open( self, number = 0, name = "LPX" ):
24462446
retval = super( LaunchpadLPX, self ).Open( number = number, name = name )
24472447
if retval == True:
2448-
self.LedSetMode( 0 )
2449-
self.LedSetLayout( 127 )
2448+
self.LedSetMode( 1 )
24502449

24512450
return retval
24522451

24532452

24542453
#-------------------------------------------------------------------------------------
24552454
#-- Checks if a device exists, but does not open it.
24562455
#-- Does not check whether a device is in use or other, strange things...
2457-
#-- Uses search string "Pro", by default.
2456+
#-- Uses search string "LPX", by default.
24582457
#-------------------------------------------------------------------------------------
24592458
# Overrides "LaunchpadBase" method
24602459
def Check( self, number = 0, name = "LPX" ):
@@ -2464,27 +2463,24 @@ def Check( self, number = 0, name = "LPX" ):
24642463
#-------------------------------------------------------------------------------------
24652464
#-- Sets the button layout (and codes) to the set, specified by <mode>.
24662465
#-- Valid options:
2467-
#-- 00 - Session, 01 - Drum Rack, 02 - Chromatic Note, 03 - User (Drum)
2468-
#-- 04 - Audio, 05 -Fader, 06 - Record Arm, 07 - Track Select, 08 - Mute
2469-
#-- 09 - Solo, 0A - Volume
2470-
#-- Until now, we'll need the "Session" (0x00) settings.
2466+
#-- 00 - Session, 01 - Note Mode, 04 - Custom 1, 05 - Custom 2, 06 - Custom 3
2467+
#-- 07 - Custom 4, 0D - DAW Faders (available if Session enabled), 7F - Programmer
24712468
#-------------------------------------------------------------------------------------
24722469
# TODO: ASkr, Undocumented!
24732470
# TODO: return value
24742471
def LedSetLayout( self, mode ):
2475-
2476-
# TODO!
2477-
# if mode < 0 or mode > 0x0d:
2478-
# return
2472+
ValidModes = [0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x0d, 0x7F]
2473+
if mode not in ValidModes:
2474+
return
24792475

24802476
self.midi.RawWriteSysEx( [ 0, 32, 41, 2, 12, 0, mode ] )
24812477
time.wait(10)
24822478

24832479

24842480
#-------------------------------------------------------------------------------------
24852481
#-- Selects the LPX's mode.
2486-
#-- <mode> -> 0 -> "Ableton Live mode" (what we need)
2487-
#-- 1 -> "Programmer mode" (power up default)
2482+
#-- <mode> -> 0 -> "Ableton Live mode"
2483+
#-- 1 -> "Programmer mode" (what we need)
24882484
#-------------------------------------------------------------------------------------
24892485
def LedSetMode( self, mode ):
24902486
if mode < 0 or mode > 1:
@@ -2510,6 +2506,7 @@ def LedSetButtonLayoutSession( self ):
25102506
#-- to emulate the old brightness feeling :)
25112507
#-- Notice that each message requires 10 bytes to be sent. For a faster, but
25122508
#-- unfortunately "not-RGB" method, see "LedCtrlRawByCode()"
2509+
#-- LPX color data extended to 7-bit but for compatibility we still using 6-bit values
25132510
#-------------------------------------------------------------------------------------
25142511
def LedCtrlRaw( self, number, red, green, blue = None ):
25152512

@@ -2520,13 +2517,80 @@ def LedCtrlRaw( self, number, red, green, blue = None ):
25202517
blue = 0
25212518
red *= 21
25222519
green *= 21
2523-
2520+
25242521
limit = lambda n, mini, maxi: max(min(maxi, n), mini)
25252522

2526-
red = limit( red, 0, 63 )
2527-
green = limit( green, 0, 63 )
2528-
blue = limit( blue, 0, 63 )
2523+
red = limit( red, 0, 63 ) << 1
2524+
green = limit( green, 0, 63 ) << 1
2525+
blue = limit( blue, 0, 63 ) << 1
25292526

25302527
self.midi.RawWriteSysEx( [ 0, 32, 41, 2, 12, 3, 3, number, red, green, blue ] )
2528+
25312529

2530+
#-------------------------------------------------------------------------------------
2531+
#-- Same as LedCtrlRawByCode, but with a pulsing LED.
2532+
#-- Pulsing can be stoppped by another Note-On/Off or SysEx message.
2533+
#-------------------------------------------------------------------------------------
2534+
def LedCtrlPulseByCode( self, number, colorcode = None ):
2535+
2536+
if number < 0 or number > 99:
2537+
return
2538+
2539+
if colorcode is None:
2540+
colorcode = LaunchpadPro.COLORS['white']
25322541

2542+
colorcode = min(127, max(0, colorcode))
2543+
2544+
self.midi.RawWrite( 146, number, colorcode )
2545+
2546+
2547+
#-------------------------------------------------------------------------------------
2548+
#-- Same as LedCtrlPulseByCode, but with a dual color flashing LED.
2549+
#-- The first color is the one that is already enabled, the second one is the
2550+
#-- <colorcode> argument in this method.
2551+
#-- Flashing can be stoppped by another Note-On/Off or SysEx message.
2552+
#-------------------------------------------------------------------------------------
2553+
def LedCtrlFlashByCode( self, number, colorcode = None ):
2554+
2555+
if number < 0 or number > 99:
2556+
return
2557+
2558+
if colorcode is None:
2559+
colorcode = LaunchpadPro.COLORS['white']
2560+
secondcolorcode = LaunchpadPro.COLORS['black']
2561+
2562+
colorcode = min(127, max(0, colorcode))
2563+
2564+
self.midi.RawWrite( 145, number, colorcode )
2565+
2566+
2567+
#-------------------------------------------------------------------------------------
2568+
#-- Quickly sets all all LEDs to the same color, given by <colorcode>.
2569+
#-- If <colorcode> is omitted, "white" is used.
2570+
#-------------------------------------------------------------------------------------
2571+
def LedAllOn( self, colorcode = None ):
2572+
if colorcode is None:
2573+
colorcode = LaunchpadPro.COLORS['white']
2574+
2575+
colorcode = min(127, max(0, colorcode))
2576+
2577+
for x in range(9):
2578+
for y in range(9):
2579+
self.midi.RawWrite(144, (x + 1) + ((y + 1) * 10), colorcode)
2580+
2581+
2582+
#-------------------------------------------------------------------------------------
2583+
#-- (fake to) reset the Launchpad
2584+
#-- Turns off all LEDs
2585+
#-------------------------------------------------------------------------------------
2586+
def Reset( self ):
2587+
self.LedAllOn( 0 )
2588+
2589+
2590+
#-------------------------------------------------------------------------------------
2591+
#-- Go back to custom modes before closing connection
2592+
#-- Otherwise Launchpad will stuck in programmer mode
2593+
#-------------------------------------------------------------------------------------
2594+
def Close( self ):
2595+
self.midi.CloseInput()
2596+
self.midi.CloseOutput()

0 commit comments

Comments
 (0)