Bitwig Studio Tutorial 3:
Separate Midi Channels

In this Tutorial I want to explain how you can create separate Midi Channel Inputs for your Controller and also go over some basic concepts.
As an example I use a Script I created for the use with the CopperLan Virtual Midi Cables VMidi1 and VMidi2.
I needed separate Midi Channels since I often use it to send generative Midi Data I generate in Processing to my Host.
On each Midi Channel a different Sequence is playing, so Omni Mode is not pretty ;-)

Here are the Scripts for you to follow along:

Edit: Updated for Bitwig Studio 2.x. Please use the scripts from Github only!!!
These tutorials were originally created for Bitwig Studio 1.0, so make sure to check the latest API docs to prevent problems!

You can find the latest versions of my scripts on Github:

CopperLan VMidi1 and VMidi2 Scripts

One thing that threw me off completely at the beginning was, that BWS internally has what I would call two “Streams” for controller data. The first is what is sent to factory instruments and VSTs on tracks and the second is used for assigning Controllers to GUI elements and the deeper Controller integration.

The first “Stream” I would call the “Note Stream”. It includes what we send to BWS for instance with a line like this in the VMidi 1 Script:

VMidi1  = host.getMidiInPort(0).createNoteInput("VMidi 1 - Channel 1", "?0????");
VMidi2  = host.getMidiInPort(0).createNoteInput("VMidi 1 - Channel 2", "?1????");
VMidi3  = host.getMidiInPort(0).createNoteInput("VMidi 1 - Channel 3", "?2????");

We create a NoteInput for the MidiInPort of our device, give it a name and assign a filter to it. In this case I let everything through but filter by Midi Channel, which happens to be the second byte. Since this is hexadecimal, the Channels go from “0” to “f”. (Scroll down to the end for a link to a tutorial on this Midi Filter).
I also assign the NoteInput to a Variable so that I can reference it later.
Check the script to see it for all the channels.

Incoming Midi Data goes through these NoteInputs to the internal instruments and VSTs on tracks and includes all the usual data like Note On and Off with Velocity, ModWheel, PitchBend CCs etc. This is also used by the modulation assignments inside for instance the PolySynth or Midi Learn inside of VSTS (directly in their own GUI).
So overall, this is the part that you use to play an instrument.

Since this is filtered by Midi Channel, you have all CCs available for all 16 Channels separately (if your controller allows you to send them per-Channel). That should be plenty to go around…

The second “Stream” of Midi Data in a Bitwig Controller Script is used for the Data that goes to the Bitwig GUI, like if you click on a Macro Knob in a Bitwig Device and select “Learn Controller Assignment…”, but also everything that is used for advanced Controller functions like selecting Clips, Start, Stop, Play etc.

Normally, everything that is being sent to the “Note Stream” is not sent to the GUI/Controller Stream. But musicians usually want a lot of freedom, in one project they may drive a Macro Knob with the Mod Wheel, in the next use it for standard Midi Modulation so the default is not ideal…

To enable the sending of all Events to both Streams, I added the following line for each Note Input:


This command tells the Note Input to not “consume” the events sent to it but hand them on to the other areas of the script.
In our case, this allows the VMidi Script to also assign CCs to Macro Knobs and other GUI elements which use the GUI/Controller Stream Data.

One other thing in this script is the Polyphonic Aftertouch Conversion to the Bitwig “Timbre” per-Note-Expression.

(This is no longer needed, as of version 1.2, Bitwig now supports Polyphonic Aftertouch directly as a note expression! You should actually remove this from your scripts now to not create problems with MPE controllers.)

As of Version 1.0.5, PolyAT isn’t supported directly (for unknown Reasons – since it is the only native and wide-spread per-Note-Controller the Midi Standard offers, it is strange that Bitwig with it’s great per-Note capabilities doesn’t support it).
The only way to use it is converting it to for instance the Timbre Note Expression, which is only supported by Bitwig Studio Factory Instruments ATM.
This is how you do it:

VMidi1.assignPolyphonicAftertouchToExpression(0,   NoteExpression.TIMBRE_UP, 5);
VMidi2.assignPolyphonicAftertouchToExpression(1,   NoteExpression.TIMBRE_UP, 5);
VMidi3.assignPolyphonicAftertouchToExpression(2,   NoteExpression.TIMBRE_UP, 5);

We tell a specific Note Input (via it’s assigned Variable) on a specific Midi Channel to convert PolyAT to a Note Expression, in this case TIMBRE_UP (which means it’s upwards going from 0 to 127) and over a range of 5 halftones (which is non-consequential for Timbre and only of relevance for “PITCH” NoteExpressions).

All right, that’s basically it for now, I hope this is helpful for your usage of Bitwig Studio.
If you find any errors, please let me know in the comments.

But wait, there’s more… ;-)

I also created another Script as a more versatile replacement of the Generic Midi Keyboard Script that comes with BWS.
I called it “TomsGenericKeys” and it offers the following features:
– An Omni Input as well as 16 separate Midi Channels.
– Sends Midi to the GUI as well as to the Note Channel, so you can record and play CCs and also map GUI controls.
– Sends Out MidiBeatClock.  (Deprecated since Bitwig Studio 2.x has dedicated Settings for this).
– Supports Polyphonic Aftertouch per Channel (Omni only on Channel 1 for now I fear)
– In and Output.

Download it here:

Toms Generic Keys

And there is even more more ;-)

At first I didn’t understand how to make the separate Midi Channels available for Midi-Learning in the GUI, but when another User asked if that would be possible, I suddenly had a hunch how it could work and yes, here is a Script that – in addition to the above  – allows Midi-Mapping of GUI Controls on all 16 Midi Channels separately…

Toms Generic Multi Control



You can also find the latest versions of my scripts on Github:

P.S. Factotumo has a tutorial on how the Midi Filter works – check it out:

Posted in Audio, English, General, Tutorials | Tagged , , , | 7 Comments

7 Responses to Bitwig Studio Tutorial 3:
Separate Midi Channels

  1. Jaxter says:

    Hi, I was googling ways to get my arduino MIDI controller to play different tracks based on which channel was used, and I stumbled on this. I don’t really get everything that’s going on. Do I need to use CopperLAN? I already have virtual MIDI routing. I went through the script for the Generic Multi Control, and I don’t get what’s going on there either.

    My question is essentially, what do I need to do to be able to play different VSTs on different MIDI channels?

    • Thomas says:

      I guess your controller would simply have to send the different tracks on different Midi Channels and you would have to set up Bitwig Studio to receive those different Midi Channels on different tracks that contain the VSTs you want to address. You may or may not need any virtual Midi routing, that depends on how your controller works.
      Open a thread on the Bitwig KVR Forum, explain what your controller does, what it’s sending etc. and I can try to get you up and running.



  2. Zirds says:


    Sorry for my english.
    I have Arturia Analog Exp The Laboratory 49 and I don’t know how can I Learn my keyboard buttons (Transport :PLay, Stop, Rec, Rev, FF and Loop) to Bitwig Transport buttons. Could You explain me this problem?

  3. Zirds says:

    Thank You very much!

  4. Bernd says:


    what steps are needed to implement/activate the script, to be able to send e.g. Midichannel 1 to Instrumenttrack 1 and Midichannel 2 to Instrumenttrack 2? I want to play/record two different Softsynths at the same time with two different Midikeyboards (Keyboard and Footbasspedal). Is there a tutorial (Link)

Leave a Reply

Your email address will not be published. Required fields are marked *