Scripts receiving MIDI CCs -- wtf?
Posted: 04 Feb 2015 11:01
I know I sound like a broken record -- "Lemur is not properly documented and it causes us to waste a lot of time"
Goal - have some controls in a template respond to MIDI CCs
Restrictions - only receive, not send; only respond if the MIDI target and channel match
Since I can't see a way to use the built-in controls for an object to receive only, I created an ON MIDI script to receive incoming Control Change messages on MIDI channels 1-16. I created 8 of these small scripts, one for each MIDI Target (0-7).
Everyone knows a MIDI Control Change message is structured like this: Bn cc vv where n is the MIDI channel (0-15), cc is the MIDI CC (1-127) and vv is the value (0-127)
So my code for MIDI Target 0 looks like this:
// midiTgt is user settable from 0-7, midiCh is user settable and internally is 0-15
if ((midiTgt == 0) && ((MIDI_ARGS[0] & 0x0F) == midiCh))
processCC(MIDI_ARGS[1], MIDI_ARGS[2]);
processCC() has a if/else structure to set the appropriate control to the value from the second parameter, except that it's never called in the above example.
The reason this fairly standard code doesn't work is that Lemur does not pass in the MIDI CC stream as-is. Instead, they chose to reformat it, maybe to make developers lives easier, but since they didn't bother to document what they did, it makes life harder temporarily.
So, instead of receiving Bn cc vv as MIDI_ARGS [0], [1], [2] we receive cc vv n as MIDI_ARGS [0], [1], [2]
If this was documented somewhere, it *would* be easier to code, since the data is nicely broken out for us. So, my above code now becomes:
// midiTgt is user settable from 0-7, midiCh is user settable and internally is 0-15
if ((midiTgt == 0) && (MIDI_ARGS[2] == midiCh))
processCC(MIDI_ARGS[0], MIDI_ARGS[1]);
Maybe this will help someone else debug a problem when they attempt to process incoming MIDI messages. I'm sure the Lemur code does something similar to most incoming messages. We know for a fact that the initial 'F0' is stripped off of incoming SYSEX messages (for example).
Goal - have some controls in a template respond to MIDI CCs
Restrictions - only receive, not send; only respond if the MIDI target and channel match
Since I can't see a way to use the built-in controls for an object to receive only, I created an ON MIDI script to receive incoming Control Change messages on MIDI channels 1-16. I created 8 of these small scripts, one for each MIDI Target (0-7).
Everyone knows a MIDI Control Change message is structured like this: Bn cc vv where n is the MIDI channel (0-15), cc is the MIDI CC (1-127) and vv is the value (0-127)
So my code for MIDI Target 0 looks like this:
// midiTgt is user settable from 0-7, midiCh is user settable and internally is 0-15
if ((midiTgt == 0) && ((MIDI_ARGS[0] & 0x0F) == midiCh))
processCC(MIDI_ARGS[1], MIDI_ARGS[2]);
processCC() has a if/else structure to set the appropriate control to the value from the second parameter, except that it's never called in the above example.
The reason this fairly standard code doesn't work is that Lemur does not pass in the MIDI CC stream as-is. Instead, they chose to reformat it, maybe to make developers lives easier, but since they didn't bother to document what they did, it makes life harder temporarily.
So, instead of receiving Bn cc vv as MIDI_ARGS [0], [1], [2] we receive cc vv n as MIDI_ARGS [0], [1], [2]
If this was documented somewhere, it *would* be easier to code, since the data is nicely broken out for us. So, my above code now becomes:
// midiTgt is user settable from 0-7, midiCh is user settable and internally is 0-15
if ((midiTgt == 0) && (MIDI_ARGS[2] == midiCh))
processCC(MIDI_ARGS[0], MIDI_ARGS[1]);
Maybe this will help someone else debug a problem when they attempt to process incoming MIDI messages. I'm sure the Lemur code does something similar to most incoming messages. We know for a fact that the initial 'F0' is stripped off of incoming SYSEX messages (for example).