using note inputs as controls

Post Reply New Topic
RELATED
PRODUCTS

Post

Hi everyone,

I am learning the Bitwig controller API, and I have a couple of questions.
I want to be able to use keys (note inputs) in two ways: be select-able in the Instrument track in Bitwig and and in the same time I want to be able to have them a double function when they are pressed along with some other "shift" or "program" key. So, far I could only do one or the other:
If I don't register the keys, then I can do different stuff in the onMidi() function like

Code: Select all

function onMidi(status, data1, data2) {
  if (status == 147 && data1 == 48 && data2 > 0) {
    transport.play();
  } else if (status == 147 && data1 == 50 && data2 > 0) {
    transport.stop();
  }
}
and when I do register the note inputs, like

Code: Select all

keys1 = host.getMidiInPort(0).createNoteInput("LPK25 Ch1", "90????", "80????");
keys2 = host.getMidiInPort(0).createNoteInput("LPK25 Ch2", "91????", "81????");
then even though this is useful because then I can use different midi channels on different tracks, I don't know how to grab the keys1, keys2 objects and manipulate them when the keys are actually pressed as this is now going past the onMidi() function.

I am guessing I need to attach an observer to them, but this seems to be above my head at the moment. I am just making first steps learning the API and I wish I could have access to some more info with some usage examples, etc.

Basically I have a little "sustain" button on the keyboard I am using for this little study of the API. That is Akai LPK-25 by the way. The button sends (MIDI: 176, 64, 127 [b0 40 7f ] and MIDI: 176, 64, 0 [b0 40 00 ]) messages and I am hoping to use this one as the above mentioned "shift" button.

In the onMidi function I can easily detect when the button is on and perhaps update some global var, like SHIFT_MODE, but then again I am not sure how to control the keys.
Last edited by jgaura on Sat Dec 20, 2014 12:39 am, edited 1 time in total.
- Jay

Post

Sweet, I learned and added this

Code: Select all

keys1.setShouldConsumeEvents(false);
keys2.setShouldConsumeEvents(false);
Now this seems to be doing what I wanted - passing everything to onMidi() function again, but I am still not sure if this is the best way to do this.

This is what I got this far

Code: Select all

loadAPI(1);
host.defineController("AKAI", "LPK25 II", "1.0", "3c0a5830-8728-11e4-b4a9-0800200c9a66");
host.defineMidiPorts(1, 1);
host.addDeviceNameBasedDiscoveryPair(["LPK25 MIDI 1"], ["LPK25 MIDI 1"]);
var SHIFT_MODE = false;
function init() {
  keys1 = host.getMidiInPort(0).createNoteInput("LPK25 Ch1", "90????", "80????");
  keys1.setShouldConsumeEvents(false);
  keys2 = host.getMidiInPort(0).createNoteInput("LPK25 Ch2", "91????", "81????");
  keys2.setShouldConsumeEvents(false);
  keys3 = host.getMidiInPort(0).createNoteInput("LPK25 Ch3", "92????", "82????");
  keys3.setShouldConsumeEvents(false);
  keys4 = host.getMidiInPort(0).createNoteInput("LPK25 Ch4", "93????", "83????");
  keys4.setShouldConsumeEvents(false);
  transport = host.createTransport();
  host.getMidiInPort(0).setMidiCallback(onMidi);
}

function exit() {
}

function onMidi(status, data1, data2) {
  if (isChannelController(status) && data1 == 64 && data2 == 127) {
    SHIFT_MODE = true;
  } else if (isChannelController(status) && data1 == 64 && data2 == 0) {
    SHIFT_MODE = false;
  }
  if (SHIFT_MODE) {
    if (isNoteOn(status) && data1 == 48 && data2 > 0) {
      transport.play();
    } else if (isNoteOn(status) && data1 == 50 && data2 > 0) {
      transport.stop();
    }
  }
}
There are 4 channels supported and C3 triggers playing the track and D3 stops playing (along with the sustain or "shift" button, of course). I will figure out how to add more functions once I get a sort of framework in place. And then again this is just a fun project for me, learning Bitwig scripting in practice. I hope this will be helpful to someone else. For now my problem is the note still makes a sound before it triggers the play() function. I need to make it silent.

Any suggestions? :/
- Jay

Post

There is only one way to make notes not-play dynamically I know of:
You can use a Velocity Translation Table for your Note Input:
NoteInput.setVelocityTranslationTable(table)
Where "table" by default is an array with 128 entries (0-127) from 0 to 127.

But if you set all the entries in the table to -1 (temporary while your "shift" key is pressed), those entries will not sound...

I learned that trick from Claes :-)

Cheers,

Tom
"Out beyond the ideas of wrongdoing and rightdoing, there is a field. I’ll meet you there." - Rumi
ScreenDream Instagram Mastodon

Post

Awesome, thank you, Tom! I will definitely try this and yes, this was still a problem for me, even though I did learn quite a bit in the last few days. Largely thanks to all of your guys contributions on this discussion forum. I even temporarily tried allocating channel 4 for the "controls keys", but even though it definitely did solve the problem I did not like having to press 2 keys to switch to that mode and then again for switching off (inbuilt function of switching channels on this little thing). Holding down just one key works much better for me. So, thanks again.

I am also wondering if there is a way to reprogram some of those 'internal' buttons. Like all Akai's have the arpeggiator and stuff, which I never use. I am guessing this involves the sysex messages.

For starters I wonder if there is any function to listen to them? Perhaps something similar to printMidi(..) to put inside onSysex() function?
I know there is a function to send Sysex.
Is this even feasible?
- Jay

Post

That is one of the main problems with a lot of controllers: They don't send anything for some/many of their knobs or use undocumented ways to communicate via invisible USB ports or only activate certain functions if they are set to some - again undocumented - special modes... :-(

Unless you unscramble their USB protocol and/or their firmware, there is little that can be done about it.

You can put printSysex(data); in your onSysex(data) { ... } to see if anything is sent, although for pattern matching you will need to use the non-beautified Sysex that you get from println(data);

(BTW. these are functions from the API scripts of Bitwig Studio in your factory installation Bitwig Studio\resources\controllers\api - check them out, a lot of useful stuff in there!)

Cheers,

Tom
"Out beyond the ideas of wrongdoing and rightdoing, there is a field. I’ll meet you there." - Rumi
ScreenDream Instagram Mastodon

Post

Thanks! Yes, I will be checking those as well..
- Jay

Post Reply

Return to “Controller Scripting”