├── Akai └── lpk25.control.js ├── Generic ├── midisport.control.js └── virmidi.control.js └── README /Akai/lpk25.control.js: -------------------------------------------------------------------------------- 1 | loadAPI(1); 2 | host.defineController("Akai", "LPK25", "1.0", "6ee2e190-b9a2-11e3-a5e2-0800200c9a66"); 3 | host.defineMidiPorts(1, 1); 4 | host.addDeviceNameBasedDiscoveryPair(["LPK25 MIDI 1"], ["LPK25 MIDI 1"]); 5 | host.addDeviceNameBasedDiscoveryPair(["LPK25"], ["LPK25"]); 6 | 7 | var LOWEST_CC = 2; 8 | var HIGHEST_CC = 119; 9 | 10 | function init() 11 | { 12 | host.getMidiInPort(0).createNoteInput("LPK25"); 13 | // host.getMidiOutPort(0).createNoteOutput("LPK25"); 14 | host.getMidiInPort(0).setMidiCallback(onMidi); 15 | // host.getMidiOutPort(0).setMidiCallback(onMidi); 16 | 17 | userControls = host.createUserControlsSection(HIGHEST_CC - LOWEST_CC + 1); 18 | 19 | for(var i=LOWEST_CC; i<=HIGHEST_CC; i++) 20 | { 21 | userControls.getControl(i - LOWEST_CC).setLabel("CC" + i); 22 | } 23 | } 24 | 25 | function exit() 26 | { 27 | } 28 | 29 | function onMidi(status, data1, data2) 30 | { 31 | if (isChannelController(status)) 32 | { 33 | if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC) 34 | { 35 | var index = data1 - LOWEST_CC; 36 | userControls.getControl(index).set(data2, 128); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Generic/midisport.control.js: -------------------------------------------------------------------------------- 1 | loadAPI(1); 2 | host.defineController("MidiMan", "MIDI Sport", "1.0", "95754470-c748-11e3-9c1a-0800200c9a66"); 3 | host.defineMidiPorts(1, 1); 4 | host.addDeviceNameBasedDiscoveryPair(["MidiSport 2x2"], ["MidiSport 2x2"]); 5 | host.addDeviceNameBasedDiscoveryPair(["MidiSport 2x2 MIDI 1"], ["MidiSport 2x2 MIDI 1"]); 6 | // host.addDeviceNameBasedDiscoveryPair(["MidiSport 2x2 MIDI 2"], ["MidiSport 2x2 MIDI 2"]); 7 | 8 | var LOWEST_CC = 2; 9 | var HIGHEST_CC = 119; 10 | 11 | function init() 12 | { 13 | host.getMidiInPort(0).createNoteInput("MidiSport 2x2"); 14 | host.getMidiInPort(0).setMidiCallback(onMidi); 15 | host.getMidiOutPort(0).setMidiCallback(sendMidi); 16 | 17 | userControls = host.createUserControlsSection(HIGHEST_CC - LOWEST_CC + 1); 18 | 19 | for(var i=LOWEST_CC; i<=HIGHEST_CC; i++) 20 | { 21 | userControls.getControl(i - LOWEST_CC).setLabel("CC" + i); 22 | } 23 | } 24 | 25 | function exit() 26 | { 27 | } 28 | 29 | function onMidi(status, data1, data2) 30 | { 31 | if (isChannelController(status)) 32 | { 33 | if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC) 34 | { 35 | var index = data1 - LOWEST_CC; 36 | userControls.getControl(index).set(data2, 128); 37 | } 38 | } 39 | } 40 | 41 | function sendMidi(status, data1, data2) 42 | { 43 | if (isChannelController(status)) 44 | { 45 | if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC) 46 | { 47 | var index = data1 - LOWEST_CC; 48 | userControls.getControl(index).set(data2, 128); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Generic/virmidi.control.js: -------------------------------------------------------------------------------- 1 | loadAPI(1); 2 | 3 | host.defineController("ALSA", "Virtual MIDI", "1.0", "6784c470-d150-11e3-9c1a-0800200c9a66"); 4 | host.defineMidiPorts(1, 1); 5 | host.addDeviceNameBasedDiscoveryPair(["Virtual Raw MIDI 1-0"], ["Virtual Raw MIDI 1-0"]); 6 | host.addDeviceNameBasedDiscoveryPair(["VirMIDI 1-0"], ["VirMIDI 1-0"]); 7 | 8 | var LOWEST_CC = 1; 9 | var HIGHEST_CC = 119; 10 | 11 | function init() 12 | { 13 | Virmidi = host.getMidiInPort(0).createNoteInput("Virmidi - Omni", "??????"); 14 | Virmidi1 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 1", "?0????"); 15 | Virmidi2 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 2", "?1????"); 16 | Virmidi3 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 3", "?2????"); 17 | Virmidi4 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 4", "?3????"); 18 | Virmidi5 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 5", "?4????"); 19 | Virmidi6 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 6", "?5????"); 20 | Virmidi7 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 7", "?6????"); 21 | Virmidi8 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 8", "?7????"); 22 | Virmidi9 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 9", "?8????"); 23 | Virmidi10 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 10", "?9????"); 24 | Virmidi11 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 11", "?A????"); 25 | Virmidi12 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 12", "?B????"); 26 | Virmidi13 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 13", "?C????"); 27 | Virmidi14 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 14", "?D????"); 28 | Virmidi15 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 15", "?E????"); 29 | Virmidi16 = host.getMidiInPort(0).createNoteInput("Virmidi - Channel 16", "?F????"); 30 | 31 | Virmidi.setShouldConsumeEvents(false); 32 | Virmidi1.setShouldConsumeEvents(false); 33 | Virmidi2.setShouldConsumeEvents(false); 34 | Virmidi3.setShouldConsumeEvents(false); 35 | Virmidi4.setShouldConsumeEvents(false); 36 | Virmidi5.setShouldConsumeEvents(false); 37 | Virmidi6.setShouldConsumeEvents(false); 38 | Virmidi7.setShouldConsumeEvents(false); 39 | Virmidi8.setShouldConsumeEvents(false); 40 | Virmidi9.setShouldConsumeEvents(false); 41 | Virmidi10.setShouldConsumeEvents(false); 42 | Virmidi11.setShouldConsumeEvents(false); 43 | Virmidi12.setShouldConsumeEvents(false); 44 | Virmidi13.setShouldConsumeEvents(false); 45 | Virmidi14.setShouldConsumeEvents(false); 46 | Virmidi15.setShouldConsumeEvents(false); 47 | Virmidi16.setShouldConsumeEvents(false); 48 | 49 | // Virmidi.assignPolyphonicAftertouchToExpression(0, NoteExpression.TIMBRE_UP, 5); 50 | // Virmidi1.assignPolyphonicAftertouchToExpression(0, NoteExpression.TIMBRE_UP, 5); 51 | // Virmidi2.assignPolyphonicAftertouchToExpression(1, NoteExpression.TIMBRE_UP, 5); 52 | // Virmidi3.assignPolyphonicAftertouchToExpression(2, NoteExpression.TIMBRE_UP, 5); 53 | // Virmidi4.assignPolyphonicAftertouchToExpression(3, NoteExpression.TIMBRE_UP, 5); 54 | // Virmidi5.assignPolyphonicAftertouchToExpression(4, NoteExpression.TIMBRE_UP, 5); 55 | // Virmidi6.assignPolyphonicAftertouchToExpression(5, NoteExpression.TIMBRE_UP, 5); 56 | // Virmidi7.assignPolyphonicAftertouchToExpression(6, NoteExpression.TIMBRE_UP, 5); 57 | // Virmidi8.assignPolyphonicAftertouchToExpression(7, NoteExpression.TIMBRE_UP, 5); 58 | // Virmidi9.assignPolyphonicAftertouchToExpression(8, NoteExpression.TIMBRE_UP, 5); 59 | // Virmidi10.assignPolyphonicAftertouchToExpression(9, NoteExpression.TIMBRE_UP, 5); 60 | // Virmidi11.assignPolyphonicAftertouchToExpression(10, NoteExpression.TIMBRE_UP, 5); 61 | // Virmidi12.assignPolyphonicAftertouchToExpression(11, NoteExpression.TIMBRE_UP, 5); 62 | // Virmidi13.assignPolyphonicAftertouchToExpression(12, NoteExpression.TIMBRE_UP, 5); 63 | // Virmidi14.assignPolyphonicAftertouchToExpression(13, NoteExpression.TIMBRE_UP, 5); 64 | // Virmidi15.assignPolyphonicAftertouchToExpression(14, NoteExpression.TIMBRE_UP, 5); 65 | // Virmidi16.assignPolyphonicAftertouchToExpression(15, NoteExpression.TIMBRE_UP, 5); 66 | 67 | host.getMidiOutPort(0).setShouldSendMidiBeatClock; 68 | host.getMidiInPort(0).setMidiCallback(onMidi); 69 | host.getMidiInPort(0).setSysexCallback(onSysex); 70 | 71 | // Make CCs 2-119 freely mappable 72 | userControls = host.createUserControlsSection(HIGHEST_CC - LOWEST_CC + 1); 73 | 74 | for(var i=LOWEST_CC; i<=HIGHEST_CC; i++) 75 | { 76 | userControls.getControl(i - LOWEST_CC).setLabel("CC" + i); 77 | } 78 | //AKAI.assignPolyphonicAftertouchToExpression(0, NoteExpression.TIMBRE_UP, 5); 79 | 80 | 81 | } 82 | 83 | function exit() 84 | { 85 | } 86 | 87 | function onMidi(status, data1, data2) 88 | { 89 | //printMidi(status, data1, data2); 90 | 91 | if (isChannelController(status)) 92 | { 93 | if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC) 94 | { 95 | var index = data1 - LOWEST_CC; 96 | userControls.getControl(index).set(data2, 128); 97 | } 98 | } 99 | } 100 | 101 | function onSysex(data) 102 | { 103 | printSysex(data); 104 | } 105 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This project directory contains two directories for some scripts written in Javascript for the Bitwig controller API. 2 | 3 | The Akai directory contains a script for the Akai LPK25 MIDI keyboard controller. The script is very basic, only sending MIDI note events. Please feel free to expand or revise it ! 4 | 5 | The Generic directory includes two scripts, one for the MidiSport 2x2 hardware MIDI interface and one for the ALSA virtual MIDI device. 6 | 7 | The MidiSport script is also very basic. It exposes the device's ports to Bitwig with their names, so connection is straightforward. 8 | 9 | The ALSA virtual MIDI script is used in conjunction with ALSA's snd-virmidi module and Bitwig's Hardware Instrument router device. 10 | 11 | If the virtual MIDI device is not already loaded, install it with this command (as root user) : 12 | 13 | modprobe snd-virmidi midi_devs=1 14 | 15 | This will create a single virtual MIDI port with 16 channels. 16 | 17 | Bitwig's Hardware Instrument router's output list will display sixteen blank entries. Select the first blank entry and set the router's Audio Input device to Stereo. 18 | 19 | Use your MIDI connections software to route the VirMidi port to your favorite synthesizer/sampler/processor/host/whatever. Be sure to connect the target's audio output to a valid audio input port, i.e. Bitwig, your system audio, or any other available port. 20 | 21 | Notes: 22 | 23 | For some reason the a2jmidi daemon is incompatible with the VirMidi script. Use JACK's raw or seq MIDI driver options if you need a JackMIDI connection. 24 | 25 | This script has been rendered somewhat redundant thanks to falkTX's Jackass VST plugin. I advise using the my script only if the plugin doesn't work for your purposes. 26 | 27 | Dave Phillips 28 | 6 June 2014 29 | 30 | --------------------------------------------------------------------------------