I’m building a MIDI Remote script (Cubase Pro 15.0.21, macOS, API v1.3).
I have three square buttons that work as one-shot triggers: each one forces a transport state — Punch In, Pre-Roll, Post-Roll — to always ON (fixed value 1, never toggle), using DirectAccess on mTransport.
This follows the approach @m.c described here: Get Punch In/Out and Pre/Post-roll state with Midi Remote? - #12 by m.c
To get a valid activeMapping for the daTransport.setParameterProcessValue() call, I bind each button’s mSurfaceValue to a dummy HostValueVariable (page.mCustom.makeHostValueVariable(…)) and run the DirectAccess write inside mOnValueChange. Functionally it works perfectly.
The problem: in the surface editor (and in the hover tooltip) each of these buttons shows the text “undefined value (not defined)”. I assume this is because the bound HostValueVariable has no real host parameter/title behind it.
My questions:
Is there any way to set a custom title/text on the button (or on the HostValueVariable) so it shows something meaningful instead of “undefined value”?
Or is there a cleaner pattern to trigger a DirectAccess write from an incoming CC without binding the visible button to a dummy HostValueVariable that produces this label?
Minimal reproducible script below. Thanks in advance!
// Minimal reproducible script: three square buttons that force the transport's
// Punch In / Pre-Roll / Post-Roll to ON via DirectAccess. Each button shows
// "undefined value (not defined)" in the surface editor (the issue I'm asking about).
var midiremote_api = require('midiremote_api_v1')
var driver = midiremote_api.makeDeviceDriver('Repro', 'PunchRollRepro', 'jordikt')
var midiInput = driver.mPorts.makeMidiInput('Repro In')
var surface = driver.mSurface
var page = driver.mMapping.makePage('Main')
// DirectAccess on the transport
var daTransport = page.mHostAccess.makeDirectAccess(page.mHostAccess.mTransport)
// DirectAccess parameter tags
var DA_TAG_TRANSPORT_PUNCH_IN = 4020
var DA_TAG_TRANSPORT_PRE_ROLL = 4037
var DA_TAG_TRANSPORT_POST_ROLL = 4038
var CHANNEL_TRANSPORT = 0 // MIDI channel 1
// --- Three square buttons ---
var btnPunchInOn = surface.makeButton(0, 0, 1, 1)
var btnPreRollOn = surface.makeButton(0, 1, 1, 1)
var btnPostRollOn = surface.makeButton(0, 2, 1, 1)
// --- MIDI input bindings (CC 99 / 101 / 103, channel 1) ---
btnPunchInOn.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(CHANNEL_TRANSPORT, 99)
btnPreRollOn.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(CHANNEL_TRANSPORT, 101)
btnPostRollOn.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(CHANNEL_TRANSPORT, 103)
// --- Value bindings to dummy HostValueVariables ---
// This dummy binding is what makes the button display "undefined value (not defined)".
// It is needed only to obtain a valid activeMapping inside mOnValueChange, so the
// DirectAccess write below can run.
var hvvPunchInOn = page.mCustom.makeHostValueVariable('hvvPunchInOn')
var hvvPreRollOn = page.mCustom.makeHostValueVariable('hvvPreRollOn')
var hvvPostRollOn = page.mCustom.makeHostValueVariable('hvvPostRollOn')
page.makeValueBinding(btnPunchInOn.mSurfaceValue, hvvPunchInOn).mOnValueChange = function(activeDevice, activeMapping, value, diff) {
if (value == 1) {
btnPunchInOn.mSurfaceValue.setProcessValue(activeDevice, 0)
var id = daTransport.getBaseObjectID(activeMapping)
daTransport.setParameterProcessValue(activeMapping, id, DA_TAG_TRANSPORT_PUNCH_IN, 1)
}
}
page.makeValueBinding(btnPreRollOn.mSurfaceValue, hvvPreRollOn).mOnValueChange = function(activeDevice, activeMapping, value, diff) {
if (value == 1) {
btnPreRollOn.mSurfaceValue.setProcessValue(activeDevice, 0)
var id = daTransport.getBaseObjectID(activeMapping)
daTransport.setParameterProcessValue(activeMapping, id, DA_TAG_TRANSPORT_PRE_ROLL, 1)
}
}
page.makeValueBinding(btnPostRollOn.mSurfaceValue, hvvPostRollOn).mOnValueChange = function(activeDevice, activeMapping, value, diff) {
if (value == 1) {
btnPostRollOn.mSurfaceValue.setProcessValue(activeDevice, 0)
var id = daTransport.getBaseObjectID(activeMapping)
daTransport.setParameterProcessValue(activeMapping, id, DA_TAG_TRANSPORT_POST_ROLL, 1)
}
}
// DirectAccess lifecycle
page.mOnActivate = function(activeDevice, activeMapping) {
daTransport.activate(activeMapping)
}
page.mOnDeactivate = function(activeDevice, activeMapping) {
daTransport.deactivate(activeMapping)
}