Send Track Name and Color over SysEx

Tall order here. At least that’s how it feels after trying the same thing a dozen plus different ways, so not in humbly here and looking for some insight.

I’ve been building out a custom touch screen controller that lives on another machine (2024 MacMini - bare minimum specs for simplicity). It’s got its own simple iConnectivity MioXC single port USB/MIDI interface that goes into the main host machine’s (2019 MacPro - loaded) primary MIDI Interface (MOTU MIDI Express XT). Sending MIDI CC’s and Notes out of my application works beautifully. No issue there. Minimal reliance on MIDI Remote implementation. Not much more than mapping via a custom script.

What I’m trying to do is get the name of the currently selected track (any track type but ideally MIDI) out of Cubase and over SysEx to a text field in my application.

The wild part, is that with my current script, and application side code, I do get something when selecting any track that isn’t a MIDI track. That something is roughly 250 arbitrary, seemingly noise characters of MIDI data. None of it SysEx data (after debugging and filtering on both a programmatic and hardware level).

That said, I’ll attach the current script below as it is. Again - it’s certainly sending something when selecting anything but a MIDI track (sends nothing when selecting a MIDI track). I just don’t know what that something is. lol. So if anyone at all has any insight or can possibly spot any and all mistakes or oversights I’m likely making, I’d be forever grateful. Also open to any and all questions anyone may have. Cheers!

//-----------------------------------------------------------------------------
// 1. DRIVER SETUP - create driver object, midi ports, and detection information
//-----------------------------------------------------------------------------

var midiremote_api = require(‘midiremote_api_v1’);

var deviceDriver = midiremote_api.makeDeviceDriver(‘Aurora Soundworks’, ‘ControlONE’, ‘Brett St. James’);

var midiInput = deviceDriver.mPorts.makeMidiInput();
var midiOutput = deviceDriver.mPorts.makeMidiOutput();

deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
.expectInputNameEquals(‘MIDI Express XT Port 7’)
.expectOutputNameEquals(‘MIDI Express XT Port 7’);

//-----------------------------------------------------------------------------
// 2. SURFACE LAYOUT - create control elements and midi bindings
//-----------------------------------------------------------------------------

var page = deviceDriver.mMapping.makePage(‘ControlONE Custom Mapping’);
var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel;

function sendTrackNameAsSysEx(activeDevice, trackName) {
// Convert track name to an array of byte values
var nameBytes = trackName.split(‘’).map(function (char) {
return char.charCodeAt(0);
});

// Create SysEx message with the track name data
var sysExMessage = [0xF0, 0x7D, 0x00].concat(nameBytes).concat(0xF7); // Example Manufacturer ID 0x7D

// Send SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage);

}

// Function to send track color as raw bytes in SysEx message
function sendTrackColorAsSysEx(activeDevice, r, g, b, a) {
// Create a SysEx message with the RGBA color values
var sysExMessage = [0xF0, 0x7D, 0x01, r, g, b, a, 0xF7]; // Example Manufacturer ID 0x7D

// Send the SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage);

}

// Track Name Change Event
selectedTrackChannel.mOnTitleChange = function (activeDevice, activeMapping, objectTitle) {
sendTrackNameAsSysEx(activeDevice, objectTitle);
}

// Track Color Change Event
selectedTrackChannel.mOnColorChange = function (activeDevice, activeMapping, r, g, b, a, isActive) {
sendTrackColorAsSysEx(activeDevice, r, g, b, a);
}

//-----------------------------------------------------------------------------
// 3. BUTTON SETUP - create buttons and bind to MIDI messages
//-----------------------------------------------------------------------------

// Button 1
var button1 = deviceDriver.mSurface.makeButton(0, 0, 1, 2)
button1.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.bindToControlChange(10, 14)

[quote=“Brett_St_James, post:1, topic:927113, full:true”]
Tall order here. At least that’s how it feels after trying the same thing a dozen plus different ways, so not in humbly here and looking for some insight.

I’ve been building out a custom touch screen controller that lives on another machine (2024 MacMini - bare minimum specs for simplicity). It’s got its own simple iConnectivity MioXC single port USB/MIDI interface that goes into the main host machine’s (2019 MacPro - loaded) primary MIDI Interface (MOTU MIDI Express XT). Sending MIDI CC’s and Notes out of my application works beautifully. No issue there. Minimal reliance on MIDI Remote implementation. Not much more than mapping via a custom script.

What I’m trying to do is get the name of the currently selected track (any track type but ideally MIDI) out of Cubase and over SysEx to a text field in my application.

The wild part, is that with my current script, and application side code, I do get something when selecting any track that isn’t a MIDI track. That something is roughly 250 arbitrary, seemingly noise characters of MIDI data. None of it SysEx data (after debugging and filtering on both a programmatic and hardware level).

That said, I’ll attach the current script below as it is. Again - it’s certainly sending something when selecting anything but a MIDI track (sends nothing when selecting a MIDI track). I just don’t know what that something is. lol. So if anyone at all has any insight or can possibly spot any and all mistakes or oversights I’m likely making, I’d be forever grateful. Also open to any and all questions anyone may have. Cheers!

//-----------------------------------------------------------------------------
// 1. DRIVER SETUP - create driver object, midi ports, and detection information
//-----------------------------------------------------------------------------

var midiremote_api = require(‘midiremote_api_v1’);

var deviceDriver = midiremote_api.makeDeviceDriver(‘Aurora Soundworks’, ‘ControlONE’, ‘Brett St. James’);

var midiInput = deviceDriver.mPorts.makeMidiInput();
var midiOutput = deviceDriver.mPorts.makeMidiOutput();

deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
.expectInputNameEquals(‘MIDI Express XT Port 7’)
.expectOutputNameEquals(‘MIDI Express XT Port 7’);

//-----------------------------------------------------------------------------
// 2. SURFACE LAYOUT - create control elements and midi bindings
//-----------------------------------------------------------------------------

var page = deviceDriver.mMapping.makePage(‘ControlONE Custom Mapping’);
var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel;

function sendTrackNameAsSysEx(activeDevice, trackName) {
// Convert track name to an array of byte values
var nameBytes = trackName.split(‘’).map(function (char) {
return char.charCodeAt(0);
});

// Create SysEx message with the track name data
var sysExMessage = [0xF0, 0x7D, 0x00].concat(nameBytes).concat(0xF7); // Example Manufacturer ID 0x7D

// Send SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage);

}

// Function to send track color as raw bytes in SysEx message
function sendTrackColorAsSysEx(activeDevice, r, g, b, a) {
// Create a SysEx message with the RGBA color values
var sysExMessage = [0xF0, 0x7D, 0x01, r, g, b, a, 0xF7]; // Example Manufacturer ID 0x7D

// Send the SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage);

}

// Track Name Change Event
selectedTrackChannel.mOnTitleChange = function (activeDevice, activeMapping, objectTitle) {
sendTrackNameAsSysEx(activeDevice, objectTitle);
}

// Track Color Change Event
selectedTrackChannel.mOnColorChange = function (activeDevice, activeMapping, r, g, b, a, isActive) {
sendTrackColorAsSysEx(activeDevice, r, g, b, a);
}

//-----------------------------------------------------------------------------
// 3. BUTTON SETUP - create buttons and bind to MIDI messages
//-----------------------------------------------------------------------------

// Button 1
var button1 = deviceDriver.mSurface.makeButton(0, 0, 1, 2)
button1.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.bindToControlChange(10, 14)

Hi, you have this for the color sysex:

// Function to send track color as raw bytes in SysEx message
function sendTrackColorAsSysEx(activeDevice, r, g, b, a) {
// Create a SysEx message with the RGBA color values
var sysExMessage = [0xF0, 0x7D, 0x01, r, g, b, a, 0xF7]; // Example Manufacturer ID 0x7D

// Send the SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage);


The r,g,b values are in the range [0,1] thus we have to convert them to the [0,127] range for the sysex to be OK:

// Function to send track color as raw bytes in SysEx message
function sendTrackColorAsSysEx(activeDevice, r, g, b, a) {
// Create a SysEx message with the RGBA color values

var r127=Math.round(127*r)
var g127=Math.round(127*g)
var b127=Math.round(127*b)
var a127=Math.round(127*a)

var sysExMessage = [0xF0, 0x7D, 0x01, r127, g127, b127, a127, 0xF7]; // Example Manufacturer ID 0x7D

// Send the SysEx message using the active device
activeDevice.mMidiOutput.sendMidi(sysExMessage)

I didn’t spot something suspicious in the code for sending the track name. The thing is that when we have an mOnTitleChange, we have also the mOnColorChange so maybe once you correct the sysex for the color, things can work properly.

EDIT:
Well, once you have it working, perhaps you would want to block unicode chars with a code above 127 to be sent. This can break the sysex again.

var nameBytes = trackName.split('').map(function (char) {
var initCode=char.charCodeAt(0)
return initCode>127 ? 32 : initCode
})
2 Likes

Hey @m.c! Thanks so very much for the insight. It’s beyond appreciated. I haven’t yet been able to make this work, but considering how fantastic you are with the script side of this, I’m going to assume it’s something in my app-side code.

Hilariously, I get data on track change. Unfortunately, it’s loads of arbitrary numbers and zero pairs. One block that I am getting does in fact have the start of SysEx data. But that’s it. This all coming from print statements in my apps Xcode console.

I’ll figure it out one way or another. I’ll likely chime in if I get closer to avoid being a bother about it.

Thanks so much again, dude. Cheers!