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

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:

couldn't you use these cc identifiers with my custom module? something like:

if (host === 'midi' && port === 'DAWtoOSC' && address === '/control' && args[1].value === 117) {
    if (args[2].value = 12) {
    articulation = SPAO Woods High

assuming you have the articulations ready in the custom module.
this way you could leave track name as is. i don't know if this works. just a thought.

do you need to see the track name in OSC? if not we could edit the track name on the fly in custom module i think.
"Woods High [SPAO] [v] [m] [wh]" arrives in custom module and gets converted to "117 - 12"

and then:

if (trackname.includes(117 - 12)) {
    articulation = SPAO Woods High

No don’t think so - the cc value is the one that gets sent back from the transformer plugin using “the old method” to determine the map and therefore is object in the custom module - not the cc for the articulation itself.

I was going to use your custom module method with sysex to grab the track name, extract the tag from it as a variable so therefore use the tag to determine the map being used.

I don’t have too much trouble with the transformer plugin method for midi tracks but the benefit from your sysex method for me will be fixing a limitation on how many instrument tracks I can use the articulation mapping in OSC on - I’ve got a workaround to fix the lack of midi send function on instrument tracks but it is limited to 128 tracks and my template runs to 1000+

Hi everybody !

Are we still on christmas time ? :partying_face: Santa - @gcat - Claus, i'm trying to get the whole thing working... I understood how to have the trackname in a text widget, and that's super super cool, but now i'm stuck...


  • to simplify the whole process for me, i just let one instrument in the json :
var as_bass_upright = loadJSON('../Cubase Expression Maps/AS - Bass Upright.json');

var art_as_bass_upright = [as_bass_upright.InstrumentMap.member[0]?.list.obj[0]?.string[1].value,

var articulation = art_as_bass_upright;

  • i converted my expression map online (, having set the "encoding field" to uft-8.
  • in my O-S-C folder, i made a dedicated "Cubase Expression Map" folder, in which i put the converted json.
  • set all the 55 buttons :

And obviously, i'm missing something here... maybe in the props ?...

Thanks :wink:

Yes - this would work, but from what you're saying above the 18 character limitation would make this more difficult as I'd lose the tag - especially if I've got a number of similar tracks with a space at the same place.
Let me have a look at it and see.

i want to get to a point where the track is selected - the name is sent to OSC - OSC (on the fly as you say) extracts the tag from the name, OSC then reads the correct articulations for a map (using the tag) that has been populated into OSC dynamically from the xml of the expression map.

This would then avoid having to repopulate the custom module with articulations every time I edit or create a new map and I could use the sysex instead of plugins and therefore save time every time I add a new track.

Looking again at your original json file I think that there could be a way to slim that down to avoid a lot of the if statements - the really useful bit that you've created is the sysex filter. I'm going to have a real play with this over the next 24 hours and see what I can do.

Wish me luck...