Hi everyone,
I am using Nuendo 15 with a hybrid setup: an MCUPro (via Mackie Control protocol) and a Stream Deck (via the new MIDI Remote API).
I’ve noticed a significant inconsistency in how Nuendo handles transport feedback between these two protocols. While the MCUPro stays perfectly in sync for all functions, the MIDI Remote API falls short on several critical transport commands, specifically Punch In and Punch Out.
The issue:
In the MIDI Remote Mapping Assistant, Punch In/Out is currently only available as a Key Command. Because it is a command and not a “Value/Function,” Nuendo does not send a MIDI status update (handshake) back to the controller. This means the icons on my Stream Deck do not reflect the actual state of the transport, whereas the MCUPro (using the older Mackie protocol) works flawlessly.
I was able to fix similar issues for Monitoring by switching from a Key Command to a native API Function, but for Punch In/Out, these native functions simply seem to be missing from the browser in Nuendo 15.
Request to Steinberg:
Could the development team please expose Punch In and Punch Out as native API Functions/Values with bi-directional feedback, just as they are in the legacy Mackie Control implementation? For professional workflows using custom controllers, having reliable visual feedback for the transport state is essential.
Is anyone else experiencing this or found a workaround that doesn’t involve complex scripting?
Hi
You can access to the Punch In/Out value by using direct access on the transport :
var homePage = deviceDriver.mMapping.makePage('Home Page')
var hostObject = homePage.mHostAccess.mTransport
var da = homePage.mHostAccess.makeDirectAccess(hostObject)
homePage.mOnActivate = function(activeDevice, activeMapping) {
da.activate(activeMapping)
var transportID = da.getBaseObjectID(activeMapping)
var punchInProcessValue = da.getParameterProcessValue(activeMapping, transportID, 4020)
var punchInDisplayValue = da.getParameterDisplayValue(activeMapping, transportID, 4020)
console.log(punchInProcessValue.toString() + ' - ' + punchInDisplayValue)
}
You can also use the method setParameterProcessValue to change the value of the Punch In
Here are some other settings you might find interesting (I’m currently working on a way to display all the settings available with DirectAccess) :
| Tag | Title | Display Value | Display Units | Default Display Value | Process Value | Process Value Type | Default Process Value | Process Plain Value | Lock State | Automatable | Parameter Index | Comment |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4020 | punchIn | Off | 0 | discrete | -1 | 0 | FAUX | FAUX | 16 | Activate the Punch in | ||
| 4021 | punchOut | Off | 0 | discrete | -1 | 0 | FAUX | FAUX | 17 | |||
| 4028 | punchInTime | 1. 1. 1. 0 | 0 | discrete | -1 | 0 | FAUX | FAUX | 22 | Get/set the punch in time (use display value) | ||
| 4029 | punchOutTime | 1. 1. 1. 0 | 0 | discrete | -1 | 0 | FAUX | FAUX | 23 | |||
| 4132 | syncPunchToCycle | On | 1 | discrete | -1 | 1 | FAUX | FAUX | 74 | Lock Punch points to cycle locator or not |
I have no idea of what this is all about…
Brilliant find, Darko,
Using these now as part of a major script upgrade for a Tascam us2400. Please let’s know of any other cool finds. Also, is there a way to bind to these, so the DAW Controller will be notified of these changing in Cubase? Polling in the mOnIdle() seems so old-style! ![]()
I don’t have time to test it right now, but I think you should use the mOnParameterChange method.
mOnParameterChange : function (activeDevice : ActiveDevice, activeMapping : ActiveMapping, objectID : number, parameterTag : number)
Thanks Darko,
If you could get a few lines out that would be coll, but in the meantime, I found the punchIn and punchOut to be as above (4020 and 4021) while the syncPunch to LR is 4130:
var punchLockedToLR = daTransport.getParameterProcessValue(am, transID, 4130);
( Using Cubase Artist 13.0.55 )
Polling it in mOnIdle() on every 20th tick is working well but would really (!) appreciate more info on use of the mOnParameterChange.
Sorted!
daTransport.mOnParameterChange = function (ad, am, v1, v2) {
if (v1 === 360)
if (v2 === 4020 || v2 == 4021 || v2 === 4130) {
var transID = daTransport.getBaseObjectID(am);
setUpThePunchLights(ad, am);
}
}
...
function setUpThePunchLights(ad, amIn) {
if (amIn !== undefined) am = amIn;
var transID = daTransport.getBaseObjectID(am);
if (transID) {
var punchIn = daTransport.getParameterProcessValue(am, transID, 4020);
var punchOut = daTransport.getParameterProcessValue(am, transID, 4021);
var punchLockedToLR = daTransport.getParameterProcessValue(am, transID, 4130);
...
// punchIn, punchOut and punchLockedToLR have values 1 or 0 for true or false
//Tested on Cubase 13 Artist