so, I'm getting started with the API scripting and I'd appreciate some help.
I've got a Behringer CMD MM-1, it's a controller laid out like a DJ mixer. Basically four channels with faders, four knobs and three buttons on each track and then some (a crossfader, yay). It's a powered USB hub, which is nice as well.
The TL;DR question is this: is it true that notes mapped on Bitwig's interface don't pass through the script's onMidi callback?
And here's the longer version:
The buttons send notes and in order to turn their LEDs on and off I need to send the device the corresponding note. I'm able to do that, no problem. But when I map a button in the interface (in the mixer, on a device, anywhere really) the script no longer sends the necessary note to the device. It doesn't do the println() line either, so I figured it just consumes the note.
Is this expected behaviour? Should I do something more?
Here's a few snippets from the script to show what I'm doing.
At the top of the file where script-wide variables are declared, I create an array to hold the status of each LED button:
Code: Select all
var ledNotes = [
//16, 3, 17, // left, encoder button, right. they send notes but can't be turned on/off
18, // button under VU meter
19, 20, 23, 24, 27, 28, 31, 32, // 4 x buttons labeled 1 & 2
48, 49, 50, 51 // cue buttons
];
// array of the status of each LED. set them off by default, init() does it on the device.
var noteStatus = [];
ledNotes.forEach(function(note) { noteStatus[note] = 00 });This is in the init() function, setting all the LEDs off when the script is loaded:
Code: Select all
// this sets the lights off. off being Behringer Orange, that is.
// would be better to read the values from the project, but it is what it is for now.
ledNotes.forEach(function(note) {
sendMidi(148, note, 00);
});Then, in the onMidi() function I catch the notes and set the lights on or off. In order to do that, the device wants the same note sent to itself, with value 00 for off and 01 for on (and 02 for blink, but haven't figured a use for that yet).
Code: Select all
// if it's a NoteOn and the note is among the LED notes:
if (isNoteOn(status) && ledNotes.indexOf(data1) != -1) {
if (noteStatus[data1] == 00) {
println("set it on " + data1 + " " + data2);
sendMidi(status, data1, 01);
noteStatus[data1] = 01;
} else {
println("set it off " + data1 + " " + data2);
sendMidi(status, data1, 00);
noteStatus[data1] = 00;
}
}
Should I do something after sending the MIDI to the device?
Setting .setShouldConsumeEvents() either true or false on the input doesn't seem to make a difference -- if the note isn't mapped to anything, the LED functions like I want it to, but when I map it, it no longer lights on or off.
I reckon when I get around using the TrackBank I can pass this all, but I'd first like to create a generic script where I can map the controls to where ever I like.
Thanks for any assistance. It also has an endless encoder that sends either value of 63 or 65 and I'd need some help with that too, but more on that later ...
Something that I did manage to get working nicely is the stereo Vu meter that it has, and this is how I got it to work (in stereo), in case someone wants to set up a stereo meter on the masterbus. I think the meter may have potential for other signaling purposes too ..
At the top of the file I declare:
Code: Select all
var showVu = 1; // 1 for yes, please make it flashy, 0 for no
var vuPeak = false; // true for peak value, false for RMS
var vuSum = false; // show the sum of left & right instead of both separatedly. true to do that, false notCode: Select all
masterTrack = host.createMasterTrack(0);
if (showVu == 1) {
// 15 is the number of LEDs available in the MM-1's Vu meter
// 0 is left, 1 is right, -1 is sum of both. vuPeak is set before init()
// .addVuMeterObserver yields only one result, so we need to make one for both sides.
if (vuSum == true) {
masterTrack.addVuMeterObserver(15, -1, vuPeak, function(vu_value) { VuMeter(-1, vu_value); });
} else {
masterTrack.addVuMeterObserver(15, 0, vuPeak, function(vu_value) { VuMeter(0, vu_value); });
masterTrack.addVuMeterObserver(15, 1, vuPeak, function(vu_value) { VuMeter(1, vu_value); });
}
}
Then the VuMeter() function:
Code: Select all
function VuMeter(side, vu_value) {
// 80 is the left side, 81 the right
switch(side) {
case -1: // sum of both: send the same value to both sides.
host.getMidiOutPort(0).sendMidi(180, 80, vu_value+48);
host.getMidiOutPort(0).sendMidi(180, 81, vu_value+48);
break;
case 0: // left side
host.getMidiOutPort(0).sendMidi(180, 80, vu_value+48);
break;
case 1: // right side
host.getMidiOutPort(0).sendMidi(180, 81, vu_value+48);
break;
}
}