Posted by & filed under Bitwig Studio, Blog, Tutorials.

When I first heard about Bitwig Studio years ago, there was one feature that really caught my eye. In promotions for the software they always mentioned that they would have an ‘Open Controller Scripting API’. Coming from an environment like Ableton Live, which has an undocumented and ‘closed’ API, this was hugely exciting. In this series of articles we will walk through the creation of a basic controller script for Bitwig Studio.

Live is great, and I still use it for a most of my sound making and performing, but coding scripts without documentation, or a convenient way of debugging, makes it a laborious, and sometimes frustrating experience. Bitwig Studio on the other hand, has a completely documented scripting API, and a debugging console built into the application. This makes writing control scripts a much faster and easier process, which is very good, because in order to do anything with a controller in Bitwig, you’ll need a script. Thankfully, there are some generic scripts that are included with Bitwig that allow for note input and cc mappings, as well as quite a few scripts for popular controllers.

Before we begin, it’s worth mentioning that it would be helpful if you know at least a little bit of JavaScript, or another C-based language. These scripts don’t involve anything too complex or any hardcore programming tricks, but it will be much easier to follow along if you have a frame of reference. That being said, I’d never really used JavaScript before diving into control scripting, so this might be a good place to get your feet wet with text based coding. You can use Codecademy to get up to speed with JavaScript pretty quickly if you’re interested, or you can consult the Mozilla Developer Network to get a more thorough walkthrough. You can also access the API documentation from the Help menu in Bitwig.

Let’s get to it! First, let’s make two folders in our Controller Scripts folder in our Bitwig User directory.

Mac: Documents/Bitwig Studio/Controller Scripts
Windows: %USERPROFILE%\Documents\Bitwig Studio\Controller Scripts\

Once there, create a new folder for the manufacturer of the controller and give it a name. I’ll use ‘MyCompany’ as the name of this folder. Inside of ’MyCompany’, create a folder that will hold the control script for our device, I’ll call it ‘MyController’. Once our folder is created we need to create a javascript file. You can use any text editor you like, but one that supports js development will be helpful. Create a new file in your text editor of choice and save it inside our newly created folder with a name of ‘MyController.control.js’. Now we’re ready to start writing some code.

There are a few lines of code that every script needs to have at the top to initialize the script and make the connections. First we need to initialize the API, define our script, and define the inputs and outputs.




In the host.defineController function, we let Bitwig know what company makes the controller, what the actual device is, the version number, and a UUID. You can generate those easily HERE. It’s some sort of hardware identifier, that I’m still not totally clear on (just generate one and put it as the fourth argument of this function, ok?). After that we define the number of input and output ports. In this case I want one input and one output. If you save this file you should be able to open Bitwig, navigate to the controller preferences, and select your new script from the ‘Add controller manually’ menu. You can then assign a controller to the MIDI input and MIDI output of the script. It won’t do anything yet, but we can quickly change that with a few more lines of code.

We’ll add a few functions to our script inside of the init() function. This function is called whenever we load the script and sets things up for us. In this case we want to create our note input and a MIDI callback.




The Note input (as you may have guessed) allows us to get MIDI notes to Bitwig’s synths or third party VSTs. The MIDI callback isn’t needed now, but it’s a useful thing to setup. Basically, we create a MIDI callback that takes a function as an argument (onMidiPort1 in this case). This will call the onMidiPort1 function (which we haven’t defined yet) whenever an event happens on the specified MIDI port (which is defined by the host.getMidiInPort(0) bit). This is your gateway to creating interesting interactions using functions, conditionals, and other fun stuff, which we will talk about later.

In order for this script to not throw errors, let’s go ahead and define our onMidiPort1 function like this:




We can leave this empty for now, as we aren’t doing anything with MIDI data except passing on the notes. When we get a MIDI message this function passes the status byte, and the two data bytes of the MIDI message it received and then executes the code contained in this function.

scripting-bitwig-4One more thing to add is just a notification when you disconnect the device that connected to this script. This isn’t necessary, but it’s good to have if you need to do some cleanup on disconnection.

Now you can go ahead and save the file, connect it to Bitwig, arm an instrument track, and play notes with your MIDI controller. We have coded up about half of the Generic MIDI Keyboard script that ships with Bitwig, and in the next installment we will add support for mapping CC data.