[LAU] strange behaviour with novation launchpad

Fons Adriaensen fons at linuxaudio.org
Fri Jul 13 08:59:16 UTC 2012


On Fri, Jul 13, 2012 at 08:50:18AM +0200, Atte André Jensen wrote:
> On 2012-07-12 23:02, Fons Adriaensen wrote:
> 
> >That is because the LP sends MIDI using running status, and there
> >is no way to reset it (i.e. force a status byte on the next message),
> >except a power cycle. The top row uses controller events while the
> >rest uses key up/down. After re-opening the device the driver code
> >needs a status byte, and usually using the top row will provide one
> >(assuming the last event in the previous session was a key one).
> 
> Ok, thanks, that sounds like a sane explanation. However it
> surprises me a bit (maybe it shouldn't), since I read this in the
> "Launchpad programmers reference" (pdf released by novation http://d19ulaff0trnck.cloudfront.net/cdn/farfuture/zJMvGWWVN-T4_9ocxl0S-99M-z5_0iKUygahuvyL2lc/mtime:1340816776/sites/default/files/downloads/4080/launchpad-programmers-reference2.pdf):
> 
> "Hence a Launchpad MIDI message is always three bytes long. (For
> good reasons, the driver does
> not support running status.)"

That seems to apply only to messages sent *to* the LP: it wants
a status byte in each one. But doesn't do the same in the LP->
app direction. 

I also tried the reset command, but it too does not clear the
running status. AFAIK only a power cycle will.

> Is there anyway to get a status byte to the driver/launchpad from my
> code, so I don't have to rely on presses after opening a new batch
> of chuck code? Could I for instance emulate "unplug" and "plug in"
> the launchpad or it's driver from code?

You'd have to switch the power on the USB socket... It's not the
USB drivers failing to reset, but the LP firware.

> I've been using the launcpad a bit with renoise, esp the duplex
> tool, and somehow the launchpad works perfectly normal there, so
> something tells me there is a way.

It is possible if you have LP-specific driver code. Only two keys
are ambiguous without a status byte: both have 0x68 as the first
data byte (the second is press/release, encoded the same way in
all cases). For all others you can infer the status byte form the
data.

When I got my LP I wrote a python extension and class that uses
it directly via libusb, without going via ALSA, and it  solves
the problem, except if the first event has data byte 0x68.
This is part of the code, with _cstat being the current status,
initialised to 0, and p is an array of n received bytes:

    i = 0;
    while (i < n)
    {
        t = p [i++];
        if (t & 0x80)  // First byte is status ?
        {
            _cstat = t & 0xF0;
            t = p [i++];
        }
        v = p [i++] ? 1 : 0;
        // If we don't have status, find it from the data.
        if (! _cstat && (t != 0x68))
        {
            _cstat = ((t & 0x0F) > 8) ? 0xB0 : 0x90;
        }
        // Keys are encoded with x,y = 0...8.
        // x == 8 means the right column.  
        // y == 8 means the top row.
        if (_cstat == 0x90) rx_action (v, t & 0x0F, t >> 4);   
        if (_cstat == 0xB0) rx_action (v, t & 0x07, 8);  
    }.  

Ciao,

-- 
FA

A world of exhaustive, reliable metadata would be an utopia.
It's also a pipe-dream, founded on self-delusion, nerd hubris
and hysterically inflated market opportunities. (Cory Doctorow)



More information about the Linux-audio-user mailing list