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

i thought i have to share this.

i managed to get all dynamically. cubase track names (from HUI device in cubase), articulations (from json files) and the buttons for the articulations (thanks to Mihkel Zilmer).
no need of plugins and cc's and generic remote.
you can add tracks in cubase on the fly and the track name will show up immediately in OSC. no hard coding of track names any more. here's the link to my custom module:

i hope there's something for the cubase users. if you have questions feel free to ask. i'm giving my best to answer them.

have a good one



Is this the holy grail??!


How does it link the expression map to the track?

If I add a new track and then expression map in cubase, does OSC know what expression map is being used?

you have to convert your expression maps to json. this is the least dynamic part of it. you have OSC to say which json belongs to which expression maps. but the articulations are now pulled dynamically from the json files. in the custom module i say if this track is selected use this json to pull from.

i think it's amazing :crazy_face: :crazy_face: :crazy_face:

sorry i'm just really excited now.
if you have ideas and inputs for optimization i'm open.

If OSC can read the track name then we can work with that. Will have a look today.

This is potentially huge…

The json files could be loaded in a single operation by scanning the content of the folder. Extracting the articulation seems to always follow the same procedure, here is a blind attempt to get rid of 100s of lines of code (will need adjustments of course):

const fs = nativeRequire('fs')
const path = nativeRequire('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[0]>x.string[1].value)
        } catch(err) {
            console.error(`failed to extract articulations from ${inst}.json:`)

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


Edit: wrong function name fixed

Would you be able to skip a step and use xml instead of having to covert to json?

i realized only the first 18 chars are transmitted. i guess this is a hui limitation. if i have time i‘ll have a look into mackie.
but for now i‘m just happy the way it is now :ghost:

i'm gonna try that. thank you very much

i don't know if javascript can search in a xml file. i think @jean-emmanuel would be the man for this.

There may be a way to do it here. Away from my machine at the moment but will investigate shortly…

Access xml with JS

thanks @Sub3OneDay

i'll too

The way to go would be to install a node library such as this one in the custom module's directory (by running npm install xml2json in a terminal in that directory, this should create a folder called node_modules with the install modules inside it*), then you'll be able to use it like this

const fs = requireNative('fs');
const xml2json = requireNative('xml2json');

var xmlFile = fs.readFileSync( './data.xml', 'utf-8')
var json  = JSON.parse(xml2json.toJson(xmlFile))

*installing node is required to get the npm command: Download | Node.js

I assume you only need to install the node library once on a machine and you don’t need to get the custom module to do it each time you open the OSC panel and “load” the custom module?

18 character limitation not a massive problem as you can limit the track name length in cubase settings to 18 so that will make sure you don’t lose data into OSC but it does limit flexibility for me as I regularly use over 18 characters and tag my track names with a load of extra things at the end of the name to allow for searching etc in macros and logical editor in cubase - for example:


You only need to install it once in the folder, it's possible to install it globally though.

Ok thanks - looking into this shortly… I’m more of a musician than a coder so this is well outside my comfort zone but always up for a challenge!

@jean-emmanuel thank you for this. same as @Sub3OneDay here. :grimacing: more music than programming.

@Sub3OneDay what i also noticed regarding track names: if consecutive tracks have the same amount of chars from beginning to first space, the chars after the space get cut. as in your screen shot nearly all would get cut, but only if you select them in order. a workaround is to select a track with different chars amount and switch back to the desired track. i have no idea why this happens. maybe it's a cubase thing. i don't know. :roll_eyes:

@jean-emmanuel thank you for this. same as @Sub3OneDay here. :grimacing: more music than programming.

You may find it surprising, but me too, it's my real-life job :smiley:

1 Like

@gcat I currently have all my expression maps named with their cc designation for example:

and was going to tag each track name with the cc number at the end so would end up with a track name like this:


If I do this the data would be lost so would need to put the tag at the start of the track. Nnot ideal as this would also be reflected in the cubase mixer so you can't see the instrument names, just the tags.

Now we are in trouble...

big trouble i guess :scream: :sweat_smile: