A push for Track.setChannel(). Make recording multiple devices on the fly easy!

RELATED
PRODUCTS

Post

tl;dr Track.setChannel() allows for changing the recording track for multiple instruments quickly and easily. It's been around since the dawn of MIDI as a solution to this problem. There is currently no good solution to this problem. People need to show interest if it's to ever be implemented in Bitwig.

The Problem:
Say you had two keyboards and you would like to use a couple of buttons to move each of the keyboards up one track or down and play on that track. Generally, the way you do this is change the midi channel of the instrument.

Currently, there is no way to use Midi Channels without extensive routing. When I asked support the solution was for:

The Current Solution:
using the api you can create a midi controller script, that receives on 16 different midi channels and gives you 16 dedicated inputs that lets you control 16 different tracks at the same time.
Midi out from Instrument tracks is realized via the hardware instrument device in Bitwig Studio, which has a midi channel setting, so you can set up every hardware instrument with its own midi channel
Basically what this means is that you:
* register an extra 16 outputs from one of your "master instruments"
* create a track for every instrument that routes back to it
* set each of your receiving tracks to one of the master instruments outputs
* then reroute to back to Bitwig

The biggest issues with this are:
* it requires setting up track inputs in your project over and over again
* it is limited in the number of tracks it supports by the number you choose in code
* it requires custom code from each user
* it doesn't play nice with other scripts
* it is inelegant. routes to Bitwig, back out, and then back again when it could just do one routing.

A Much Better Solution:

There is as simple solution, and it's been around since the dawn of MIDI: Track.setChannel(channel)

* Setting channels has been around for all of MIDI history, so this is not some crazy new feature.
* It shouldn't take long at all to make. Less than a day, it's a 16 number dropdown, a single variable, a few geters and setters, and a simple conditional
* It would allow for recording and switching around multiple instruments at the same time without having to select them as inputs for each track.
* It would also allow for some crazy fun stuff like switching the instrument randomly for every note you play. Not that it's necessary, just kind of fun.


So Let's Talk About It
There isn't really a whole lot to say on this subject, but unless the Developers see interest it's not likely to come around soon. Please, if this could ever help you, just leave a "bump" or something. This feature shouldn't take a single developer more than a few hours to make on the back end, so it's not like other things won't happen. It will just suddenly become much, much easier to set up multiple instruments at the same time and do a live performance where you change what track they play. If for no other reason, have it included so that you can have access to it later down the line.

Thanks for reading.

Post

Isn´t that kinda backwards? I´ve always worked by assigning channels to the instruments and then changing the channel the keyboard/controller sends out. In fact i´m not aware of a DAW that lets you change midi channel settings for tracks from a controller (ok reaper will do it i guess).
Maybe i´m misunderstanding.

The multi-channel script works fine for me, editing out unneeded channels is quite easy too. But I understand it won´t do for every use and users don´t want to get too technical with the scripts (though i like to encourage everyone to give it a shot, it´s very empowering).

Post

- The hardware instrument device has a channel selector for the Midi output. You can MIDI-learn that selector to a Hardware control.

- Or do you want to switch between different SOFTWARE instruments or tracks inside BwS from a MIDI keyboard? (So note input from that keyboard but also use buttons on that keyboard to select and record arm different tracks in BwS?)
Then you have to do it via controller scripting. Have a look into the API under the CursorTrack interface, more precisely: the Cursor interface. There you will find functions like selectNext(), selectPrevious(), selectFirst/Last().

- Also you're talking about two keyboards. How do you mean that?

Post

Oh. I'm calling instruments the things like drum pads and keyboards, and tracks the things which turn midi into sound.

And by two keyboards I mean I have one playing a bass sound, and another playing a melody sound. All tracks are armed, but only take certain inputs.

I can record both the bass and melody at the same time, and if I switch the channel of one or the other, I can record on the track associated with that channel.

But even better, if I made a controller script for it, I could just have each keyboard have it's own channel, only arm the tracks I'm recording on, and use a controller script to choose which channel that track accepts.

I've looked all through the API, and I have the ability to select tracks no problem. The issue arises when I have no way to differentiate between the midi instruments that are sending note events. There is only one way to send a note event to Bitwig and it Host.sendRawMidiEvent(). This leaves no room whatsoever for controlling where the midi goes on the fly. The only way to control it is to assign a midi instrument to a track manually, which won't work at all for live performance and generally kills the groove.

Post

Tearing Riots wrote:Isn´t that kinda backwards? I´ve always worked by assigning channels to the instruments and then changing the channel the keyboard/controller sends out. In fact i´m not aware of a DAW that lets you change midi channel settings for tracks from a controller (ok reaper will do it i guess).
Maybe i´m misunderstanding.

The multi-channel script works fine for me, editing out unneeded channels is quite easy too. But I understand it won´t do for every use and users don´t want to get too technical with the scripts (though i like to encourage everyone to give it a shot, it´s very empowering).
It's only kind of backwards if you're working from the mouse and keyboard being the only true inputs perspective. If you think of certain midi devices as being the more natural interface, it makes perfect sense they should be able to do everything a mouse and keyboard does.

And I agree on everyone giving scripting a shot. I just don't think it's good to teach people bad habits, and every coding style that even vaguely resembles this basic functionality is kludegy as hell. I've got ~5000 lines of code on my MDI (Multi Device Interface) and I can basically do everything but program synths from my Quneo. It's really, really impressive what I've gotten Controller Scripts to do. But I've been stuck at this point for over a year where I can't get multiple players using it at the same time because there is no way to differentiate instruments passed the Host.sendRawMidi() point without explicitly stopping playing, grabbing the mouse, and choosing your device for whatever track.

It's kind of a circular problem. Nobody can play like this because of this problem, so nobody tries, so nobody sees the problem. It's immediately obvious once you try though.

Post

The MDI being a bws script? Didn´t know that was possible but i think i understand know.

For clarification keyboard = midi keyboard, instrument = thing that makes sound.

Post

Perhaps it would be more appropriate to ask for the devs to expand on the SourceSelector class (accessible through Track.getSourceSelector())? It already provides access to the track source, but it doesn't do much right now.

Post

So the two midi keyboards are recognized as one MIDI input device but are sending notes on different midi channels?
And you want to seperate them via the controller script so that they can play different tracks with them, right?

Post

Track.geSourceSelector() must be rather new. That seems usable, though likely to lag.

@u-u-u : In terms of bitwig, the two MIDI inputs are recognized as being different but can only be filtered apart if you use the source selector. And while they are very easy to separate with controller script, they are are hard to separate in bitwig without using source selector.

But just in general, the whole reason channels exist is for the purpose of making one physical instrument control many synthesizers. There may be some hope in using Track.getSourceSelector(), but it's absurd to not just do it the way MIDI was designed to do it.

Post

Just checked Track.getSourceSelector().

It has two functions:
BooleanValue getHasNoteInputSelected ()
BooleanValue getHasAudioInputSelected ()

totally useless.

balls.

Post

Well, that's why I wrote it doesn't do much right now. Yet it's been there since version 1.

I do think that it would be a more elegant solution to build on it, because it would be in line with how the rest of the API is designed. To me, what you're asking for sounds awful lot like deprecating large chunks of the API design and even though you say it would only take a few hours for the developers to pull it off, it wouldn't make much sense to do that. In particular, as I understand it, it would affect the way pretty much every script creates note inputs with host.getMidiInPort().createNoteInput().

Instead, if the SourceSelector class would be expanded to provide an actual list of all possible sources, audio and MIDI, and a function to set the track's source, it could solve your problem and be in line with the rest of the API. Something like Track.getSourceSelector().setSource() would, in my opinion, be better than what you're asking for. And I wouldn't be surprised if it's already on the developers' long list of things to do, because they've provided the SourceSelector class since the first release.

Don't get me wrong, I do agree with the gist of your post -- that it should be possible to change the source of a track programmatically. I've come to the same conclusion as you that it's not possible right now (anyone correct me if I'm wrong here). I just disagree about the usefulness of having one more layer of a MIDI channel selector on top of everything that's already there.

Post

I think we're agreeing in different ways.

Perhaps Track.getSourceSelector().setSource() and Track.getSourceSelector().setChannel() would be a better way of doing this?

And setting channel really shouldn't be that hard. If the developers are able to do everything they've done so far, something along these lines (pun :party: ) can't be that bad:

Code: Select all

var myChannel = -1; //all channels

function setChannel(num) {
    myChannel = num;
}

function rightChannel(midibytes) {
    return myChannel == -1 || midibytes[0] >> 4 == myChannel;
}

// somewhere in the middle of a function like Track.recieveNote(note) 
if(rightChannel(midibytes) == false)
     return;  //don't use the note

The hardest part would be adding a GUI element because they'd probably have to bikeshed on where to put it and what it would look like. Or, worse yet, pass it by a designer.

Post

I still think defining a channel at that point is redundant. I mean, every time you create a note input which appears in the Track I/O drop-down (the source selector), you need to give it the mask which defines what data on which channel gets through. Typically you put the channel number in the name of the note input. If you'd first create a note input that passes data only on channel 3 and then later on would use that setChannel() function to make a track receive on channel 4 of that note input, what would it do? The mask is already filtering it. I would imagine it to only work with note inputs that pass through data on every channel. It complicates matters unnecessarily and would mean rethinking the note input creation procedure. You'd only need to know which source (note input) you want to have, instead of knowing both the source and the channel, because the note input is already set to work on a specific channel.

In short, you already define the MIDI channel when you create a note input, in my opinion making a separate setChannel() function unnecessary. Explicit is better than implicit, is it not?

Post

a note input which appears in the Track I/O drop-down (the source selector), you need to give it the mask which defines what data on which channel gets through. Typically you put the channel number in the name of the note input.
Image
http://imgur.com/a/nbFj1

I think I might be explaining this badly... If I connect two keyboards and put the first on channel 1, and the second on channel 2, then arm two tracks which accept "All Ins", how do I make it so each track only accepts one keyboard? Then if I switch the channel on my first keyboard to channel 2, will they both play the same synth (as they should)?

Another scenario: 1 keyboard, multiple synths. I want to be able to switch between synths in the way MIDI was designed so I make each synth accept only one channel and switch between channels on my keyboard. Obviously there are ways to do this with scripts, but why complicate something that was simple in the 80s?

I think we're thinking of two very different approaches. I definitely like the Track.sourceSelector().setNoteInput() style and would gladly use it to solve the problem just the same.

And either one will solve the problem of having neither, so whichever way this discussion goes, I'm content.

Post

If I connect two keyboards and put the first on channel 1, and the second on channel 2, then arm two tracks which accept "All Ins", how do I make it so each track only accepts one keyboard?
Well, sorry to say, but as far as I know, you don't do that. The "All ins" is Bitwig's own input that, as you would expect from the name, merges all inputs defined by all loaded scripts. It doesn't care about MIDI channels, it merges everything. If you put a MIDI monitor plugin as the first device, you'll notice that anything that goes into a track, comes on channel 1. (However, if a plugin requires receiving on a specific channel, you can do that by pointing a instrument track's output to that plugin; this then will show a number that allows you to set up MIDI channels. This is mainly useful for multitimbral plugins.)

Either you use the "All ins" and get this behaviour, or you create your own note inputs and set the track inputs accordingly. This really is how it's always been with MIDI, if you think about it. I still do agree that it would be nice to adjust the inputs programmatically.


You did mention creating some sort of "Multi Device Interface", I don't know what you meant with that, but if you somehow managed to control more than one port with your script, then you should be able to roll your own "All ins" just the same.

If you'd be satisfied with having just an "omni" input of a single device, then perhaps you could set up a filter in the MIDI callback to filter out stuff you don't want going to a specific track, ie. create your own setChannel() and if it matches with your track, let it go through. I don't know if it's possible to discard notes, but maybe it is.


Another scenario: 1 keyboard, multiple synths. I want to be able to switch between synths in the way MIDI was designed so I make each synth accept only one channel and switch between channels on my keyboard. Obviously there are ways to do this with scripts, but why complicate something that was simple in the 80s?
You do this by creating note inputs for each channel you wish to have (it's just one line of code for each), then set up the inputs on the tracks to match the channels coming from your keyboard, arm the tracks and you're done. This is what the support wrote to you and you quoted in the OP. I wouldn't call this exactly complicated, at least once you've created the inputs. While Bitwig insists on staying on channel 1 internally, no notes will come on the track if you set the mask of the note input properly.

And this isn't that much different from working with hardware synthesizers; creating the inputs is the same as setting up the transmitter channels, adjusting the inputs is the same as setting up the receiver channels and arming tracks is like pulling up the mixer fader to get some sound out.

I was born in the '80s so I can't speak for how simple it really was back then, but from my experience with hardware synthesizers, it's never been easy. Well maybe it's easy when each synthesizer has its own keyboard, but controlling synthesizers with other keyboards.. it always involves meticulous setting up, set the receiver channel on one side, set the transmitter channel on the other, probably hold down a number of buttons to do it or push them in a specific sequence or everyone's favourite, take a dive into a two line LCD screen with buttons for up, down and enter -- and most certainly, once you have it working on both ends, you don't mess with it again. Multitimbral synths and romplers may allow setting up the channels per patch and there's usually no easy way to change those settings on the fly. Then there are synths that have hardwired channels and there's nothing you can do about them (even something as recent as the Akai Rhythm Wolf & Tom Cat). Just search for the manuals of classic synthesizers from the period and you get the idea, it's a royal pain in the proverbial. The easiest way back then and even today is to just pull down the faders on the mixer -- no MIDI involved.

Post Reply

Return to “Controller Scripting”