THERE IT IS: the ultimate custom module for cubase users (at least for me)

This will probably not work with MCU. As far as I remember the maximum is 27 characters for the track name. In order to get this longer track name, you have to switch the MCU into ‚channel strip’ mode. I am not in front of my computer and I can‘t remember the button you have to press on the MCU in order to switch the mode.

For me the track name is not important per se. What’s important is the data that comes from cubase contains something that can ID the articulation map that has been linked to the track.

From all the good work so far it seems that you’re saying that this tag would need to sit in front of the cubase track name. This as I’ve said before is not ideal as it will make the mixer cures very difficult.

If you can dive that bit and remove the track name length limitation I think I’ll be able to solve the dynamic mapping of the xml so you don’t have to manually build a long custom module each time you edit or make a new map

My 2 cents: you could write your track names with the identifier at the end to keep visibility and extract it any way in the custom module as long as you respect the maximum length:

var name = 'Picc. Flute 0001'
var id = (name.match(/[0-9]{4}$/) || [])[0] // '0001'

The regular expression /[0-9]{4}$/ matches only 4-digits numbers located at the end of the string.

Yes - this is how I want to do it but we’re limited on the characters in track name length that actually comes in from cubase - and I have some quite long names so if I put the identifier at the end it will get truncated.

I think I will follow this path. With the 4 digits at the beginning, I can write what I want at the back.
Now I just have to find a way to dynamically write my query of the 4 digits and assignment of the instrument in an external module so that the main module stays lean.


bisch ou persönlich erreichbar oder machsches nur über d'komuniti, auso hie?

i'm getting this error:
Bildschirmfoto 2022-01-19 um 17.01.58

this the custom module:

const fs = requireNative('fs')
const path = requireNative('path')



const dir = __dirname + '/../json/cubase_expression_maps'

const maps = {}
const articulations = {}

// load json expression maps
fs.readdir(dir, (err, files) => {
    if (err) {throw err}
    files.forEach(file => {
        if (path.extname(file) === 'json') {
            maps[path.basename(file)] = loadJSON(file)
        }
    });

    // extract articulations
    for (var inst in maps) {

        try {
            articulations[inst] = maps[inst].InstrumentMap.member[1].list.obj[0].member[1].map(x=>x.string.value)
        } catch(err) {
            console.error(`failed to extract articulations from ${inst}.json:`)
            console.error(err)
        }
            
    }


    console.log('Extracted articulations:\n')
    console.log(articulations)

});

SOLVED:
it was the other way around

const fs = nativeRequire('fs')
const path = nativeRequire('path')

has anyone an idea what i'm missing?

thank you

i'm getting this error:

See Parsing xml using Node

1 Like

thanks for that...

Regarding track names in sysex data using mackie mcu have a look here…

Full track name in sysex

To get the full name in MCU mode, i use this code in a script widget (code found somewhere here):

locals.text = locals.text || Array(112).fill(" ") // persistent variable to store full text

if (value.includes("f0 00 00 66 14 12")) { // sysex header for mackie lcd text

var d = value.split(" ").slice(6).map(x=>parseInt(x, 16)), // hex to int
    pos = d[0], // first byte -> position
    text = d.slice(1).map(x=>String.fromCharCode(x)) // rest -> updated characters

text.pop() // drop sysex closing byte

// update characters
for (var i = 0; i < text.length; i++) {
  locals.text[i + pos] = text[i] // update 
}


// update text widget
set("lcd", locals.text.slice(72,82).join(""))}

I modified the last line to focus on track name.
The original last line is :


// update text widget
set("lcd", locals.text.slice(0,56).join("") + "\n" + locals.text.slice(56).join(""))

Then, i just have a button to send note 45 (strip mode).

Just to be clear - does this work as follows -

  • you select a track in cubase
  • cubase fires out sysex on an MCU remote channel
  • OSC custom module reads the full track name

??

How many characters from the track name can you get into OSC?

this is what we get. 29 chars:

if (host === 'midi' && port === 'MCUtoOSC' && address === '/sysex') {

			
			

			if (args[0].value.includes('f0 00 00 66 14 12')) {
			
			
			
			// CUBASE TRACKS HEX TO ASCII STRING
            // send('midi', 'OSCtoMCU', '/note', 1,44,1);   EDIT: is not needed
			var input = args[0].value.split(' ').splice(7 ,35);
			input.pop();			
			input = input.join('');
			var trackname = '';
			for (var n = 0; n < input.length; n += 2) {
			trackname += String.fromCharCode(parseInt(input.substr(n, 2), 16));
			}
        }
            console.log(trackname)

:slight_smile: was about to reply
Using a mackie port in cubase, we just isolate a part of the lcd screen.


mackie2

No custom module, just a script widget with this, and a text wigdet to get the text:

locals.text = locals.text || Array(112).fill(" ") // persistent variable to store full text

if (value.includes("f0 00 00 66 14 12")) { // sysex header for mackie lcd text

var d = value.split(" ").slice(6).map(x=>parseInt(x, 16)), // hex to int
    pos = d[0], // first byte -> position
    text = d.slice(1).map(x=>String.fromCharCode(x)) // rest -> updated characters

text.pop() // drop sysex closing byte

// update characters
for (var i = 0; i < text.length; i++) {
  locals.text[i + pos] = text[i] // update 
}


// update text widget
set("lcd", locals.text.slice(72,102).join(""))}

This is awesome - any chance you can post your session file?

Don't know if your asking me or gcat, so...

Here's my lcd :
Mackie lcd.json (14.4 KB)

Just have sysex "enabled" here :
sysex

1 Like

Sorry you're goiing to have to talk me through this one as I'm getting strange behaviour...

This is the code in my cm

oscInFilter:function(data){


        var { address, args, host, port } = data


        // MCU TEST AREA HERE

        if (host === 'midi' && port === 'MCU' && address === '/sysex') {

            if (args[0].value.includes('f0 00 00 66 14 12')) {



                // CUBASE TRACKS HEX TO ASCII STRING
                // send('midi', 'OSCtoMCU', '/note', 1,44,1);   EDIT: is not needed
                var input = args[0].value.split(' ').splice(7, 35);
                input.pop();
                input = input.join('');
                var trackname = '';
                for (var n = 0; n < input.length; n += 2) {
                    trackname += String.fromCharCode(parseInt(input.substr(n, 2), 16));
                }
            }
            console.log('MCU Track name ' + trackname)

        }
//END MCU TEST AREA
       
}

This is my set up in cubase:

This is the tracks selected:

image

I get a lot of sysex when I enable or apply the MIDI port in the studio step up but I don't get anything when changing tracks.

Have I missed a step?

Sorry @Sylvain I was going to try to implement in custom module but I guess I have some more fundamental issues...

The code looks good. i'm not sure try to comment out

and add:

return {address, args, host, port}

and what i saw your MCU input is disabled in cubase. just connect it to OSCtoMCU. and one last thing, be sure OSC runs before cubase. shut down cubase and try again.

and now i'm out. sorry

dealing with covid-19. i guess i'm off for a few days.

C U