What's new

Open Stage Control (Tutorial) - An alternative to Lemur and TouchOSC

tpoots

Member
I've started on a little utility that parses Cubase expression maps to extract information about the articulation, keyswitch, and UACC info. It's in python but you might find it helpful:


easiest way to run it is to just call it from the command line like:
>python expression-map-parser.py {path-to-directory-containing-expression-maps} --csv

(note the "--csv" flag at the end). This will parse every expression map contained in the directory and dump a CSV with all the articulation, keyswitch, and UACC details for each expression map. I've been using it to design the UI for my OSC articulation controller, like you I have found it very useful to get a list of all the articulations possible in a given library without having to manually type them all out.

The script does other stuff too if you don't add the "--csv" flag but that is fairly specific to my OSC configuration and requires a few more variables to be set up. I posted a quick and dirty blurb about how that works here https://vi-control.net/community/th...nd-cubase-expression-maps.114281/post-4912751 and I may eventually get around to cleaning the code up a bit and properly "releasing" the OSC controller plus associated utility scripts at some point.
 

Ibofobi

New Member
I just started to look into making an OSC controller as well. A generic articulation switcher would be my main goal. Did any of you find a generic way of identifying which track is selected in Cubase, without having to manually put some MIDI transformer or plugin sending specific identifier values on each and every track?
 

tpoots

Member
I just started to look into making an OSC controller as well. A generic articulation switcher would be my main goal. Did any of you find a generic way of identifying which track is selected in Cubase, without having to manually put some MIDI transformer or plugin sending specific identifier values on each and every track?
I have not found a way to do this. I have a poly pressure input transformer on each track. OSC is configured to send a PP 0 message whenever *any* track is selected (which is routed to the selected track automatically of course) and each track transforms PP0 into a different channel/value combo and sends it back to OSC. It's not as painful as it sounds if you make your OSC controller configuration driven. For example in mine, the channel identifies the "library" and the PP value identifies which instrument number within that library, so the incoming PP message is decoded and a single JS script is called that sets up the UI appropriately.
 

Ibofobi

New Member
I have not found a way to do this. I have a poly pressure input transformer on each track. OSC is configured to send a PP 0 message whenever *any* track is selected (which is routed to the selected track automatically of course) and each track transforms PP0 into a different channel/value combo and sends it back to OSC. It's not as painful as it sounds if you make your OSC controller configuration driven. For example in mine, the channel identifies the "library" and the PP value identifies which instrument number within that library, so the incoming PP message is decoded and a single JS script is called that sets up the UI appropriately.
Ok, I will probably have to consider such a solution. Thanks for your answer!
 

Drjay

Active Member
If you are looking for a quick and stable solution, I suggest to use the one mentioned above with the transformer, this way it only works with midi tracks though. In order to use it with instrument tracks, you‘ll have to use a plugin in the FX chain and get the values via the generic remote.
But there are other solutions as well, using e.g. the MCU protocol, or EUCON. Eucon is not feasible imo, since the protocol is not published. I am currently using MCU, but the solution it is a little bit fiddly; it takes some effort to make it run robust.
 

Ibofobi

New Member
If you are looking for a quick and stable solution, I suggest to use the one mentioned above with the transformer, this way it only works with midi tracks though. In order to use it with instrument tracks, you‘ll have to use a plugin in the FX chain and get the values via the generic remote.
But there are other solutions as well, using e.g. the MCU protocol, or EUCON. Eucon is not feasible imo, since the protocol is not published. I am currently using MCU, but the solution it is a little bit fiddly; it takes some effort to make it run robust.
Aha, I'll look into MCU and see how that could be utilized also then. Thanks!
 

RaztoR

Composer
I've started on a little utility that parses Cubase expression maps to extract information about the articulation, keyswitch, and UACC info. It's in python but you might find it helpful:


easiest way to run it is to just call it from the command line like:
>python expression-map-parser.py {path-to-directory-containing-expression-maps} --csv

(note the "--csv" flag at the end). This will parse every expression map contained in the directory and dump a CSV with all the articulation, keyswitch, and UACC details for each expression map. I've been using it to design the UI for my OSC articulation controller, like you I have found it very useful to get a list of all the articulations possible in a given library without having to manually type them all out.

The script does other stuff too if you don't add the "--csv" flag but that is fairly specific to my OSC configuration and requires a few more variables to be set up. I posted a quick and dirty blurb about how that works here https://vi-control.net/community/th...nd-cubase-expression-maps.114281/post-4912751 and I may eventually get around to cleaning the code up a bit and properly "releasing" the OSC controller plus associated utility scripts at some point.
That's a very convenient tool, thank you for sharing. Although for some reason it does not actually work as intended when executed. No CSV file is created and the command line simply prints: ExpressionMapName, Articulation, Keyswitch, UACC

I had re-installed python from the Windows Store just before trying it out, could critical dependencies be missing? Although no errors were thrown mentioning any missing dependencies.
The commands I tried in sequence, using the command line tool in Administrator mode:
1. D: 2. cd <locationContainingThePythonScript> 3. python expression-map-parser.py {D:\Example\Directory\For\ExpressionMaps} --csv
Removing the brackets for the directory causes the script to throw an AttributeError at line 376, so I assume they're meant to be there. I'll dive into python some more later if need be to better understand the language's semantics.
 

tpoots

Member
3. python expression-map-parser.py {D:\Example\Directory\For\ExpressionMaps} --csv[/ICODE]
Removing the brackets for the directory causes the script to throw an AttributeError at line 376, so I assume they're meant to be there. I'll dive into python some more later if need be to better understand the language's semantics.
I should clarify, the brackets aren't needed (they are just there to indicate that you have to fill in the argument yourself). You do have to put the path in quotes though. For example this is the exact invocation I used on Windows:

python expression-map-parser.py "E:\Audio\Cubase Projects\Expression Maps\Spitfire Audio\Olafur Arnalds Chamber Evolutions"
 

RaztoR

Composer
I should clarify, the brackets aren't needed (they are just there to indicate that you have to fill in the argument yourself). You do have to put the path in quotes though. For example this is the exact invocation I used on Windows:

python expression-map-parser.py "E:\Audio\Cubase Projects\Expression Maps\Spitfire Audio\Olafur Arnalds Chamber Evolutions"
That's what I assumed to be the case at first. But when I tried that it also resulted in the following error:
File "D:\locationContainingThePythonScript\expression-map-parser.py", line 376, in <module> articulation = articulationElement.find(".//*[@name='description']").get('value').strip() AttributeError: 'NoneType' object has no attribute 'get'

Seems to be related to a function call/assignment error. Any ideas? Faulty expression map description formatting on my end?
 
If you are looking for a quick and stable solution, I suggest to use the one mentioned above with the transformer, this way it only works with midi tracks though. In order to use it with instrument tracks, you‘ll have to use a plugin in the FX chain and get the values via the generic remote.
But there are other solutions as well, using e.g. the MCU protocol, or EUCON. Eucon is not feasible imo, since the protocol is not published. I am currently using MCU, but the solution it is a little bit fiddly; it takes some effort to make it run robust.

Yes agre e - very stable but as you say massive limitation is that it only works for midi tracks - simply because instrument temracks don’t have a midi send, only insert. It’s my number one on the list of things I wish cubase had!

You mention about a plug-in on the insert but I’m not aware of one? Are you?!
 

tpoots

Member
Seems to be related to a function call/assignment error. Any ideas? Faulty expression map description formatting on my end?
Your expression map is probably ok, it's likely my script doesn't account for all the possibilities of the way expression maps can be formatted since I've only tested it with the ones I use myself.

Do you want to send me an example of an expression map that isn't working? I can try it locally and see if I can figure out what's going on....
 

RaztoR

Composer
Your expression map is probably ok, it's likely my script doesn't account for all the possibilities of the way expression maps can be formatted since I've only tested it with the ones I use myself.

Do you want to send me an example of an expression map that isn't working? I can try it locally and see if I can figure out what's going on....
That's nice of you to do, thank you. I'll send it over PM in that case.
 

Drjay

Active Member
Yes agre e - very stable but as you say massive limitation is that it only works for midi tracks - simply because instrument temracks don’t have a midi send, only insert. It’s my number one on the list of things I wish cubase had!

You mention about a plug-in on the insert but I’m not aware of one? Are you?!
The idea is to insert any plugin (does not matter which one) in the insert FX chain of the instrument, must be in the same slot for every instrument you want to control. Pick any number of vst Parameters (e.g. compressor treshhold, attack time). These n parameters and their values serve the same purpose as the callback values in the midi track transformer, so set them a value according to your scheme (e.g. attack 123 = VSL Oboe)
Assign them in a generic remote. Pseudocode for generic remote: selectedTrack->Insert1->ParameterN.
Mute the Plugin (can't remember, whether the generic remote still gets updated if you disable the plugin, just try it). Every time you click on a new instrument track, or change the parameter in the plugin the values are send out via the generic remote.
I created a small vst plugin for this purpose, which provides me with other track parameters, which is great, but only works with instrument, audio, fx etc. tracks. So this another dead end, since in Cubase cannot use custom midi plugins :sad:
 
Last edited:
The idea is to insert any plugin (does not matter which one) in the insert FX chain of the instrument, must be in the same slot for every instrument you want to control. Pick any number of vst Parameters (e.g. compressor treshhold, attack time). These n parameters and their values serve the same purpose as the callback values in the midi track transformer, so set them a value according to your scheme (e.g. attack 123 = VSL Oboe)
Assign them in a generic remote. Pseudocode for generic remote: selectedTrack->Insert1->ParameterN.
Mute the Plugin (can't remember, whether the generic reote still gets updated if you disable the plugin, just try it). Every time you click on a new instrument track, or change the parameter in the plugin the values are send out via the generic remote.
I created a small vst plugin for this purpose, which provides me with other track parameters, which is great, but only works with instrument, audio, fx etc. tracks. So this another dead end, since in Cubase cannot use custom midi plugins :sad:
This sounds really promising - are you saying that if you assign the plug-in parameter on each instrument track to say 116, and then for tracks 1-50(say) you put 116-1, 116-2 etc, when selected the track, the generic remktw will fire out 116-1, or 116-2 etc.

I suppose one way that cc value hits OSC it doesn’t need to distinguish between instrument and midis track?…
 

Drjay

Active Member
This sounds really promising - are you saying that if you assign the plug-in parameter on each instrument track to say 116, and then for tracks 1-50(say) you put 116-1, 116-2 etc, when selected the track, the generic remktw will fire out 116-1, or 116-2 etc.

I suppose one way that cc value hits OSC it doesn’t need to distinguish between instrument and midis track?…
Yes, it doesn‘t need to distinguish (if you don‘t want to). But since you can use as many virtual midi ports as you like, you could do all kinds of routings.
 
Top Bottom