Simple Mackie Transport Control (for UFX1204/1604)

Post Reply New Topic
RELATED
PRODUCTS

Post

I wanted to start a thread for people who would like to do something with their controllers but are frustrated with their lack of knowledge but instead will just post a couple of findings while learning.

The first hurdle (the brick wall limiter of ignorance) has been overcome with help from Tom here:
http://blog.thomashelzle.de/2014/04/bit ... ntrollers/

So, I figured something straightforward would be a good starting point by creating a simple transport control script with button feedback for my UFX. Here's what I've discovered with some research and Midi OX:

MCU protocol sends notes for transport control.
Data 1 = the midi note number / controller number
Data 2 = the note velocity / controller value

Midi is 7bit and consists of 128 values represented as 0 - 127 in the scripts.
Notes are represented by values where C-1 to G 9 is equal to 0 to 127.
Note velocity is 0 to 127

That means that all that needs to be done is to connect:
REWIND (91 or G 6),
FF (92 or G# 6),
STOP (93 or A 6),
PLAY (94 or Bb 6),
and RECORD (95 or B 6),
to Bitwigs transport controls.

It turns out that Mackie Control is just basic midi. What a relief!
Bitwig will need to intercept (observe) this data and send it to the right place. Thankfully the Mackie script includes everything needed but the tricky bit is working out what can be thrown away. There are no shortcuts to learning this stuff it seems! :)

I hope this encourages others to get started and share their experiences. (no cats were harmed during this experience)

-originally some dodgy non-functional script was pasted here-
Last edited by fluxmachina on Wed Apr 15, 2015 8:08 pm, edited 5 times in total.

Post

like reading sanskrit to me. guess ill just not be able to use my max49 :)

Post

You're not the only one. This is all voodoo to me but after some reading it looks a lot less complicated than it did originally. I looked into python a while ago and they recommend starting off with pseudocode before messing with the sanscrit :). Pseudocode goes through each step of the script in plain English (or your language of choice).
It would look something like this:

Code: Select all

//////// This is an idea for how the script will work
//////// using plain language (a.k.a pseudocode).

Bitwig script start;

here's my controller ("UFX Transport");
it has these midi ports (1 midi in, 1 midi out);
autodetect it if there is a controller with these ports ("UFX1204 MIDI 1", "UFX1204 MIDI 1);

//////// The transport controls send and receive midi notes in
//////// Mackie mode.
//////// Notes are represented as decimal values
//////// (i.e 91 to 95 = G6 to Bb6).

it has these transport buttons:
rewind (note 91)
forward (note 92)
stop (note 93)
play (note 94)
record (note 95)

they will control bitwig.transport;

//////// Initialise the LEDS
send noteOFF for:
    91
    92
    94
    95
send noteON for:
    93

//////// Bitwig will receive transport control
//////// and send feedback to the controller.
//////// Here "isPressed" and "press" mean pressed and released
//////// not held.  "send.feedback" means Bitwig transmits.

bitwig is not playing but:
    if rewind isPressed
        press rewind on bitwig.transport
        until released send.feedback noteON for 91
    
    if forward isPressed
        press forward on bitwig.transport
        until released send.feedback noteON for 92
    
    if stop isPressed
        press stop on bitwig.transport 
    
    if play isPressed
        press play on bitwig.transport
    
    if record isPressed
        press record on bitwig.transport

//////// Bitwig also needs to send feedback to the controller
//////// when it's transport buttons are activated on screen.

    if bitwig.transport stop isPressed
        send noteON for 93
        send noteOFF for 94
        send noteOFF for 95

    if bitwig.transport play isPressed
        send noteON for 94
        send noteOFF 93
        while playing
            send noteON for 93
            send noteOFF for 94
            send noteOFF for 95 
        
    if bitwig.transport.record isPressed
        send noteON for 95
        while recording
            send noteOFF for 95

Bitwig script end;
That's a start I guess. This took ages to figure out so will try to forget that this is for 5 buttons. Hats off to the devs for being able to spit out code like it's a second language. With this open api you've pretty much given a lot of wannabe coders an excuse to start learning and brought a slice of the diy linux philosophy to other platforms.
Last edited by fluxmachina on Tue Apr 14, 2015 2:27 am, edited 1 time in total.

Post

mahhest wrote:guess ill just not be able to use my max49 :)
Give it a go if you have the time, it's quite satisfying. The trick is not caring that this is the coders equivalent playing Simon Says. Gotta start somewhere right?

Cracked the transport script! :tu:

MidiOX is a Godsend it's so helpful, picking up bits from the api docs helps a lot, "printMidi(status, data1, data2);" is your friend and "switch ()" is nice and tidy. A lot of this is still quite mysterious but it seems to work ok.

Code: Select all

loadAPI(1);

host.defineController("Behringer", "UFX Transport", "1.0", "4CCE0D60-DFE3-11E4-B571-0800200C9A66");
host.defineMidiPorts(1, 1);
// Autodetect Behringer UFX Mixer
host.addDeviceNameBasedDiscoveryPair(["UFX1204 MIDI 1"], ["UFX1204 MIDI 1"]);
host.addDeviceNameBasedDiscoveryPair(["UFX1604 MIDI 1"], ["UFX1604 MIDI 1"]);

// This prefixes "ufx." to each control to make them more readable.
var ufx =
{
	REW : 91,
	FF : 92,
	STOP : 93,
	PLAY : 94,
	REC : 95
};
//isPlay = false // Decided to comment.  What does it do?

// Tell bitwig what is going to be controlled and watch the transport controls on screen.
function init()
{
	host.getMidiInPort(0).setMidiCallback(onMidi);
	transport = host.createTransportSection();
	transport.addIsPlayingObserver(function(on) // Is Bitwig transport playing?
	{
		//isPlay = on; // Decided to comment out.  What does it do?
		sendNoteOn(0, ufx.PLAY, on ? 127 : 0); // Don't understand this yet.
		sendNoteOn(0, ufx.STOP, on ? 0 : 127);
	});
	transport.addIsRecordingObserver(function(on) // Is Bitwig transport record?
	//transport.addLauncherOverdubObserver(function(on) // Handy for overdubbing in clips.
	{
		sendNoteOn(0, ufx.REC, on ? 127 : 0);
	});
}

//
function onMidi(status, data1, data2)
{
	//printMidi(status, data1, data2); // This is really helpfull, similar to MidiOX as shows data.
	switch (data1)
	{
		case ufx.REW:
			if (data2 > 0) // Otherwise press and release will both cause rewind.
			{
				transport.rewind();
			}
			sendMidi(144, ufx.REW, data2); // Send(midi note, note value, note velocity)
			break;
		case ufx.FF:
			if (data2 > 0) // same as above.
			{
				transport.fastForward();
			}
			sendMidi(144, ufx.FF, data2);
			break;
		case ufx.STOP:
		if (data2 > 0)
			{
			transport.stop();
			}
			break;
		case ufx.PLAY:
			if (data2 > 0)
			{
			transport.play();
			}
			break;
		case ufx.REC:
		if (data2 > 0)
			{
			transport.record();
			//transport.toggleLauncherOverdub(); // Handy for overdubbing in clips.
			}
			break;		
	}
}

function exit()
{
}
Thank you everyone who has posted helpful tips.

Post Reply

Return to “Controller Scripting”