Open gene1wood opened 4 years ago
Interesting, never saw than one before. You mean this thingy with 2 potentiometers and only one button in each column, right?
Seems to be discontinued, so I can only try to implement that blindly. Could you test this if I do so?
You mean this thingy with 2 potentiometers and only one button in each column, right?
Seems to be discontinued, so I can only try to implement that blindly.
Maybe not worth it then, I'd say if this sounds interesting or if you're bored, go for it, otherwise feel free to close this issue.
Could you test this if I do so?
Yes, happily.
Could you please do me a favor and execute the file "information.py", available from the /examples folder or manually post what "lp.ListAll()" shows?
I need the MIDI devices' names.
Sure thing. I'm on Ubuntu 18.04 with pygame
installed via the python-pygame
package and launchpad.py installed with pip install --user launchpad_py
under the system Python 2.7.17.
information.py
returns
Running...
- OS : posix
- Platform: Linux
- Release : 4.15.0-96-generic
- Python : 2.7.17
- PyGame : 1.9.1release
Available MIDI devices:
('ALSA', 'Midi Through Port-0', 0, 1, 0)
('ALSA', 'Midi Through Port-0', 1, 0, 0)
('ALSA', 'Launch Control MIDI 1', 0, 1, 0)
('ALSA', 'Launch Control MIDI 1', 1, 0, 0)
goodbye ...
and here's what I get in /var/log/syslog
when plugging the device in. I'm not entirely sure if every line of this relates to the device.
Apr 18 10:45:54 carol kernel: [150091.971852] usb 1-2.3.1: new full-speed USB device number 43 using xhci_hcd
Apr 18 10:45:55 carol kernel: [150092.303775] usb 1-2.3.1: New USB device found, idVendor=1235, idProduct=0034
Apr 18 10:45:55 carol kernel: [150092.303778] usb 1-2.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Apr 18 10:45:55 carol kernel: [150092.303781] usb 1-2.3.1: Product: Launch Control
Apr 18 10:45:55 carol kernel: [150092.303782] usb 1-2.3.1: Manufacturer: Focusrite A.E. Ltd
Apr 18 10:45:55 carol mtp-probe: checking bus 1, device 43: "/sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1"
Apr 18 10:45:55 carol mtp-probe: bus: 1, device: 43 was not an MTP device
Apr 18 10:45:55 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "bind"
Apr 18 10:45:55 carol upowerd[2113]: unhandled action 'bind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1/1-2.3.1:1.1
Apr 18 10:45:55 carol systemd-udevd[29353]: Process '/usr/sbin/alsactl -E HOME=/run/alsa restore 3' failed with exit code 99.
Apr 18 10:45:55 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "bind"
Apr 18 10:45:55 carol upowerd[2113]: unhandled action 'bind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1/1-2.3.1:1.0
Apr 18 10:45:55 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "bind"
Apr 18 10:45:55 carol upowerd[2113]: unhandled action 'bind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1
Apr 18 10:45:55 carol pulseaudio[9602]: [pulseaudio] module-alsa-card.c: Failed to find a working profile.
Apr 18 10:45:55 carol pulseaudio[9602]: [pulseaudio] module.c: Failed to load module "module-alsa-card" (argument: "device_id="3" name="usb-Focusrite_A.E._Ltd_Launch_Control-00" card_name="alsa_card.usb-Focusrite_A.E._Ltd_Launch_Control-00" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1""): initialization failed.
Apr 18 10:45:55 carol colord-sane: [bjnp] create_broadcast_socket: ERROR - bind socket to local address failed - Cannot assign requested address
Apr 18 10:45:55 carol colord-sane: [bjnp] create_broadcast_socket: ERROR - bind socket to local address failed - Cannot assign requested address
Apr 18 10:46:00 carol colord-sane: io/hpmud/pp.c 627: unable to read device-id ret=-1
And here's when it gets unplugged
Apr 18 10:48:00 carol kernel: [150217.858248] usb 1-2.3.1: USB disconnect, device number 43
Apr 18 10:48:00 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "unbind"
Apr 18 10:48:00 carol upowerd[2113]: unhandled action 'unbind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1/1-2.3.1:1.1
Apr 18 10:48:00 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "unbind"
Apr 18 10:48:00 carol upowerd[2113]: unhandled action 'unbind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1/1-2.3.1:1.0
Apr 18 10:48:00 carol kdeconnectd.desktop[9810]: UdevQt: unhandled device action "unbind"
Apr 18 10:48:00 carol upowerd[2113]: unhandled action 'unbind' on /sys/devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-2/1-2.3/1-2.3.1
Apr 18 10:48:00 carol colord-sane: [bjnp] create_broadcast_socket: ERROR - bind socket to local address failed - Cannot assign requested address
Apr 18 10:48:00 carol colord-sane: [bjnp] create_broadcast_socket: ERROR - bind socket to local address failed - Cannot assign requested address
Apr 18 10:48:05 carol colord-sane: io/hpmud/pp.c 627: unable to read device-id ret=-1
Great thanks!
Ok, I added the class "LaunchControl".
The following methods are available and should work:
Open( number = 0, name = "Control MIDI", template = 0 )
Check( number = 0, name = "Control MIDI" )
Reset( )
LedAllOn( colorcode = None )
LedGetColor( red, green )
LedCtrlRaw( number, red, green )
InputFlush()
InputChanged()
InputStateRaw()
This one's prepared, but not yet functional:
LedCtrlXY( x, y, red, green )
The problem ist that, as I don't have any access to this device, I don't know any of the button or potentiometer numbers, so - well, could you please execute this and note the numbers of the potentiometers and buttons, while you turn/press them? I only need the first number in the brackets.
lp = launchpad.LaunchControl()
lp.Open()
while(True):
buts = lp.ButtonStateRaw()
if buts != []:
print( buts )
Thanks
So with #50 added, when I run this
#!/usr/bin/env python
import launchpad_py as launchpad
def main():
lp = launchpad.LaunchControl()
lp.Open()
if __name__ == '__main__':
main()
I get this
Traceback (most recent call last):
File "r.py", line 11, in <module>
main()
File "r.py", line 7, in main
lp.Open()
File "/home/gene/.local/lib/python2.7/site-packages/launchpad_py/launchpad.py", line 1849, in Open
retval = super( LaunchControl, self ).Open( number = number, name = name )
File "/home/gene/.local/lib/python2.7/site-packages/launchpad_py/launchpad.py", line 1622, in Open
self.TemplateSet( self.UserTemplate )
File "/home/gene/.local/lib/python2.7/site-packages/launchpad_py/launchpad.py", line 1874, in TemplateSet
self.midi.RawWriteSysEx( [ 0, 32, 41, 2, 10, 119, templateNum-1 ] )
File "/home/gene/.local/lib/python2.7/site-packages/launchpad_py/launchpad.py", line 167, in RawWriteSysEx
self.devOut.write_sys_ex( timeStamp, array.array('B', [0xf0] + lstMessage + [0xf7] ).tostring() )
OverflowError: unsigned byte integer is less than minimum
Exception Exception: "PortMidi: `Bad pointer'" in <pypm.Input object at 0x7fc15d186690> ignored
Exception Exception: "PortMidi: `Bad pointer'" in <pypm.Output object at 0x7fc14ad46270> ignored
Also, I suspect I won't be able to use lp.ButtonStateRaw()
as both the LaunchControl
class and it's parent the LaunchControlXL
class don't implement it. Did you mean lp.InputStateRaw()
?
This is done with the template set to User
: 1
Oh my, yes, of course; sorry.
lp = launchpad.LaunchControl()
lp.Open( 0 )
while(True):
inps = lp.InputStateRaw()
if inps != []:
print( inps )
Also fixed that overflow issue. Could you try again, please?
Thanks.
Interface | ID |
---|---|
Button 1 | 9 |
Button 2 | 10 |
Button 3 | 11 |
Button 4 | 12 |
Button 5 | 25 |
Button 6 | 26 |
Button 7 | 27 |
Button 8 | 28 |
Potentiometer 1 Top | 21 |
Potentiometer 2 Top | 22 |
Potentiometer 3 Top | 23 |
Potentiometer 4 Top | 24 |
Potentiometer 5 Top | 25 |
Potentiometer 6 Top | 26 |
Potentiometer 7 Top | 27 |
Potentiometer 8 Top | 28 |
Potentiometer 1 Bottom | 41 |
Potentiometer 2 Bottom | 42 |
Potentiometer 3 Bottom | 43 |
Potentiometer 4 Bottom | 44 |
Potentiometer 5 Bottom | 45 |
Potentiometer 6 Bottom | 46 |
Potentiometer 7 Bottom | 47 |
Potentiometer 8 Bottom | 48 |
Up Arrow | 114 |
Down Arrow | 115 |
Left Arrow | 116 |
Right Arrow | 117 |
# LED AND BUTTON NUMBERS IN RAW MODE (DEC)
#
# 0 1 2 3 4 5 6 7 8 9
#
# +---+---+---+---+---+---+---+---+ +---++---+
# 0 |21 |22 |23 |24 |25 |26 |27 |28 | |NOP||NOP|
# +---+---+---+---+---+---+---+---+ +---++---+
# 1 |41 |42 |43 |44 |45 |46 |47 |48 | |114||115|
# +---+---+---+---+---+---+---+---+ +---++---+
# +---+---+---+---+---+---+---+---+ +---++---+
# 2 |9 |10 |11 |12 |25 |26 |27 |28 | |116||117|
# +---+---+---+---+---+---+---+---+ +---++---+
Great, thanks!
I updated the "docs" and added a tiny LedControlXY() method. Reversed Y bc I think that the major action is probably going to happen at the bottom row.
Excellent.
I've not been able to get the LED controls to work. When I try something like this
import launchpad_py as launchpad
lp = launchpad.LaunchControl()
lp.Open(0)
lp.LedCtrlRaw(9, 3, 3)
lp.LedCtrlXY(0, 0, 3, 3)
lp.LedAllOn()
None of the LEDs are activated.
I see that
LedCtrlRaw
uses pygame.midi.Output().write_short(144, number, led)
LedCtrlXY
uses pygame.midi.Output().write_sys_ex(timeStamp, array.array('B', [0xf0] + [ 0, 32, 41, 2, 10, 120, 0, index, color ] + [0xf7]).tostring())
I'm unsure why these two LED activation methods use these different methods of interacting with the midi device.
Also, how do you determine these values (like 144
and 0, 32, 41, 2, 10, 120, 0
)?
Is there anything I can run to diagnose why the LED lights don't respond to the code?
I hoped it would work like the XL, but that obviously isn't the case.
Also always make sure to add some delays between the calls. Otherwise it simply might be too fast to see anything. I assume you know this, but you could simply use PyGame's internal timer:
from pygame import time
...
time.wait( <ms> )
I changed LedCtrlXY(), that shall work now, except that I don't know the order of the four control (arrow) buttons. X is from left to right, starting at 0. Y is from bottom to top, starting at 0.
lp.LedCtrlXY( 0, 0, 3, 3 ) # Pad 1 yellow
lp.LedCtrlXY( 7, 0, 3, 3 ) # Pad 8 yellow
lp.LedCtrlXY( 9, 0, 3, 3 ) # Arrow Right yellow (unsure)
lp.LedCtrlXY( 8, 1, 3, 3 ) # Arrow Up yellow (unsure)
The numbers for LedCtrlRaw()
are, at least in theory, those you sent me.
9-12, 25-28, 114-117.
lp.LedCtrlRaw( 9, 3, 0) # Pad 1 red
lp.LedCtrlRaw( 11, 0, 3) # Pad 3 green
If these number still don't work, you can just try other values (0..127). You cannot damage anything. Maybe they also start at 0? I don't know ...
Also always make sure to add some delays between the calls.
Ok, good hint.
lp.LedCtrlXY( 0, 0, 3, 3 ) # Pad 1 yellow lp.LedCtrlXY( 7, 0, 3, 3 ) # Pad 8 yellow lp.LedCtrlXY( 9, 0, 3, 3 ) # Arrow Right yellow (unsure) lp.LedCtrlXY( 8, 1, 3, 3 ) # Arrow Up yellow (unsure)
So I've tried this but it didn't light up any of the LEDs
import launchpad_py as launchpad
from pygame import time
lp = launchpad.LaunchControl()
lp.Open(0)
lp.LedCtrlXY( 0, 0, 3, 3 ) # Pad 1 yellow
time.wait(500)
lp.LedCtrlXY( 7, 0, 3, 3 ) # Pad 8 yellow
time.wait(500)
lp.LedCtrlXY( 9, 0, 3, 3 ) # Arrow Right yellow (unsure)
time.wait(500)
lp.LedCtrlXY( 8, 1, 3, 3 ) # Arrow Up yellow (unsure)
time.wait(500)
If these number still don't work, you can just try other values (0..127).
I tried iterating through all numbers 0-127 with 500ms waits between each calling lp.LedCtrlRaw( i, 3, 0)
and didn't get any of the LEDs to light up.
I'm wondering, where does the value 144
come from in the LaunchControlXL().LedCtrlRaw()
method which is what the LaunchControl
class inherits? I see that it calls self.midi.RawWrite( 144, number, led )
, what is that 144
?
Also, given that I've tried lots of number
values (0-127) I wondered if the issue is with LedGetColor
and the data2
value so I tested by bypassing the LedGetColor
method and calling lp.midi.RawWrite(144, 9, data2) and just tried numbers between 0 and 127 for the LED color. That didn't light up any LEDs either.
So, first a summary
InputStateRaw
. I'm able to see everything for User Template 1and some questions
144
number come from in the LaunchControlXL().LedCtrlRaw()
method? Could that be wrong?data2
for midi.RawWrite
for the other Novation devices? What lead to this method for setting data2
?The Control and the Control XL share exactly the same commands (except for that the SysEx ones use "10d" instead of "17d". for the Set LED command).
"144" is a MIDI "Note On" command, followed by the note and a velocity. The Launchpads use "note" as an identifier for the buttons, LEDs ... For LED activation, velocity determines the color. For the old, red/green devices, it's just a bitfield (MIDI uses 7 bits). Bits 5..4 for green and 1..0 for red. In between are "clear" and "copy", but those are not used in here (0).
The commands should be ok, this has to be something different. https://resource.novationmusic.com/sites/default/files/novation/downloads/6958/launch-control-programmers-reference-guide.pdf
Even when the output MIDI channel would be wrong, which might happen, than at least the SysEx commands shall be working, as they're completely indpendent.
Does the automatic switching of the templates work? If you manually set it to user 2..8, does it switch over to 1 after executing the lp.Open() code?
Could also be a Linux/ALSA issue. Did you compile PyGame or is this a version from PyPi?
I'm sorry I've not been able to follow up on this recently, I'll endeavor to make time to do so.
Any chance of adding support for Novation Launch Control