MIDI Remote 1.3 — 594/1454 native commands don't bind via makeCommandBinding

Hi all,

I’ve built a full touch-screen controller for Cubase on top of the MIDI Remote API (custom WPF app, script-driven, ~4800 assignable slots across 20 pages plus a mixer console), now essentially complete. Along the way I needed a definitive answer to a question I couldn’t find documented anywhere: which of Cubase’s native commands can actually be bound through makeCommandBinding, and which can’t.

So I ran a full, systematic pass over the entire native command list exposed in the MIDI Remote Mapping Assistant — not a sample, all of it.

Method: commands were loaded in batches of 240 into the script, reloaded in Cubase, and checked one by one against the Mapping Assistant grid. Tested on Cubase, MIDI Remote API 1.3, clean/default project state.

One important clarification on what “Missing” means here: it’s purely the visual state shown by the Mapping Assistant itself — a bound slot whose command name Cubase’s binding layer doesn’t recognize is displayed differently from one that is. It’s Cubase’s own UI telling us the static match failed, not something I inferred by pressing the button and observing no effect. Whether that visual “Missing” state always corresponds to a genuine functional impossibility, or in some cases just an unmatched name while the action might still be reachable another way, is part of what I’d like feedback on.

Headline result: out of 1454 native commands tested, 594 (40.9%) do not bind via makeCommandBinding — leaving 860 usable directly through this mechanism. Macros, PLE (Project Logical Editor) presets and LE (Logical Editor) presets are not affected — those bind reliably at 100% and aren’t part of this count.

The solid part of the finding — entire categories that come back as 0% bindable regardless of any project configuration, session state, or selection (so this isn’t “needs a track selected” or “needs Control Room active,” it’s a flat wall for the whole category):

Category Missing / Total
Add Track 19 / 19
Inspector 21 / 21
Score Functions 105 / 105
Score Meter Scale 20 / 20
Score Symbol Editor 19 / 19
Score Symbol Palettes 16 / 16
Scores 13 / 13
Scores Statusbar 9 / 9
Score Align Elements 7 / 7
Set Insert Length 10 / 10
Track Versions 12 / 12
Render in Place 2 / 2

That’s 253 commands, all-or-nothing, across categories that together represent a large chunk of everyday editing workflow — track creation, the Inspector panel, and the entire Score Editor toolset in particular (which alone accounts for over a third of all Missing commands across the whole test).

Beyond this solid core, a good number of other categories (Control Room, Devices, Marker, Zoom, Windows, and a few more) also showed partial Missing results, but some of those may depend on project/session context that wasn’t active during this pass (Control Room enabled, a marker already placed, a specific selection, etc.) — those are still being re-verified in a properly configured session before I’d call them conclusive, so I’ve left them out of the table above on purpose.

Whether a systematic workaround exists for these — wrapping the same native action in a Macro or a PLE preset, both of which do bind reliably — is still an open question for me at this point; it’s untested at scale, so I wouldn’t call it a general solution yet. As far as I can tell, this exhaustive a breakdown had never been put together and published anywhere, and with more people building custom touch/hardware controllers on MIDI Remote, having an actual baseline of what’s structurally reachable versus not seems like useful groundwork — both for other developers, and potentially for prioritizing what a future MIDI Remote revision could extend (the Score Editor block above all stands out as the single biggest gap).

Is this a known/intentional scope limitation of the API (e.g., anything requiring an active editor context or a modal dialog is out of scope by design), or is it more of a gap that could be revisited? Happy to share the full per-command table (all 1454 rows) if that’s useful to anyone here or at Steinberg.

Looking forward to hearing your thoughts.

Where did you get this list from?

Please provide just ONE example of a failing command, let’s say from the AddTrack category, so I can have a look. Provide the command name and command category exactly as you insert into the makeCommandBinding.

@m.c

Good question — I actually tested exactly this on the Add Track category since it’s one of the cleanest 100% Missing blocks. For reference, here’s the full list of sub-commands tested under that category (all 19, all Missing):

json

"Add Track": [
  "Add Track...",
  "Arranger",
  "Audio",
  "Audio Mono",
  "Chord",
  "Effect",
  "Folder",
  "Group",
  "Instrument",
  "Marker",
  "MIDI",
  "Ruler",
  "Sampler",
  "Signature",
  "Tempo",
  "Transpose",
  "Using Track Preset...",
  "VCA",
  "Video"
]

Correction to an earlier draft of this reply: wrapping the native command in a Macro actually does work, just not silently. If you create a Macro whose single step is Add Track - Audio, the Macro binds fine in the Mapping Assistant (Macros always bind at 100%, as noted), and triggering it does produce an effect — it opens the standard “Add Track” dialog with the track type already pre-selected (Audio, in this case). It stops short of a fully silent one-tap creation though: you still have to manually set the configuration (routing, stereo/mono, name, count) and click the dialog’s own “Add Track” button to actually create the track. So for a touch-remote workflow specifically, it’s a partial win — it gets you to the right pre-filled dialog, but it doesn’t remove the need to interact with a modal window.

For reference, here’s the actual binding call from my script, generalized across pages and buttons:

js

var commandCategory = commandArray[0];
var commandName = commandArray[1];
pages[pageIndexInt].makeCommandBinding(
    boutonsCommandes[buttonIndexInt].mSurfaceValue,
    commandCategory,
    commandName
);

So for “Instrument” specifically, the live call is:

js

makeCommandBinding(button.mSurfaceValue, "Add Track", "Instrument")

Category and command strings match Cubase’s own display exactly — no formatting mismatch anywhere in the pipeline that I can find.

I haven’t tested a PLE-based equivalent for Add Track yet — PLE typically operates on existing objects (tracks, events, parts), so it’s not obvious there’s a “target” for a project logical editor preset to act on when the goal is creating a track that doesn’t exist yet, but given that my Macro assumption just turned out to be wrong, I’m not going to assert that one without testing it too.

I wouldn’t generalize the Macro result to all 594 Missing commands either — it’s entirely possible some categories open a pre-filled dialog like Add Track does, while others (anything that’s supposed to run silently in the background, for instance) behave differently. Add Track happening to need a dialog at all may be more about that specific command’s own design than about Macros in general. Still re-verifying across other categories before I’d call any of this conclusive.

So at this point: Macro-wrapping gets you a pre-filled dialog rather than a dead end, but not a fully silent one-tap trigger — at least not for Add Track. Curious whether others have seen the same “dialog pops pre-filled” pattern elsewhere, or found a way around the manual confirmation step.

Your list (json) is wrong. Not sure how you prepared it, but you should parse the KeyCommands.xml of Cubase and grab both command category and name from there.

For example, in the case of Add Instrument, the couple is “AddTrack”,“Instrument”. Notice that there is no space between Add and Track. This is why I asked you where you got the list from.

I’ll give you another example. There’s no “Using Track Preset…” in the KeyCommands.xml. What you see in the GUI as “Using Track Preset…” is not what you should use in the remote. In the remote, the correct command is “AddTrack”,“From Track Presets”.

Almost forgot: You can find the list of all available commands in Steinberg’s official page here:
Command Bindings | MIDI REMOTE API . You can even parse the source code of this page to get the proper command couples.

@M.C.

You were right, and it’s a bigger issue than I initially realized — thank you for pushing on this.

I went and checked against the actual KeyCommands.xml file (not just the Steinberg docs page, which turned out to still show the display-style names in its “Add Track” example — so that page didn’t catch this either). Once I parsed the real XML, the picture is very different from what my original test assumed.

Two concrete examples, exactly matching what you flagged:

  • The category is literally AddTrack (no space) in KeyCommands.xml, not Add Track as shown in the Mapping Assistant / Steinberg’s docs page.
  • The track-preset command is From Track Presets, not Using Track Preset... — again, exactly what you said.

But it goes further than just this one category. I ran the full comparison of all 594 commands my test reported as “Missing” against the real category/command names in KeyCommands.xml (70 categories, ~5176 commands total). The breakdown:

  • 189 (31.8%) are in categories that don’t exist under that name in KeyCommands.xml at all — this is almost entirely the seven “Score” categories from my table (Score Functions, Score Meter Scale, Score Symbol Editor, Score Symbol Palettes, Scores, Scores Statusbar, Score Align Elements). None of these exist as such in the real file.
  • 339 (57.1%) are in a category whose name IS correct, but with a command name that doesn’t match the internal string — e.g. my test used “Open/Close Fader Section” for what’s actually named “Toggle MIDI Fader Section” in the XML. The entire “Inspector” block (21/21) falls in this bucket, and it’s clearly a systematic naming-convention mismatch, not a binding failure.
  • Only 66 (11.1%) have both the correct category and the exact correct command string per the XML, and still showed as “Missing” — those are the only ones that might reflect an actual binding limitation, pending an actual retest.

So the honest conclusion is that my original methodology — pulling category/command names from what’s visually shown in the Mapping Assistant rather than from KeyCommands.xml — was flawed, and the 40.9% “don’t bind” figure in my original post is very likely a significant overstatement, possibly by close to an order of magnitude on the genuinely-unbindable count.

I’m redoing the full 1454-command test using KeyCommands.xml as the source of truth for category/command strings this time, and I’ll post a corrected breakdown once that’s done. Apologies for putting out a conclusion that wasn’t as solid as I presented it, and thanks again for catching this rather than letting it stand.

@M.C.

Retest complete — here are the corrected numbers, using KeyCommands.xml as the source of truth for category/command strings this time, exactly as I said I’d redo it.

Of the original 1454 commands:

  • 1043 confirmed bindable (71.7%) — verified by actually loading them in batches into the Mapping Assistant and reading the grid, not just cross-referencing strings on paper.
  • 7 confirmed still failing — real binding failures, not naming mismatches. I haven’t pinned down exactly which 7 yet (found via a visual batch scan, still need to isolate the precise category/command for each), will follow up with the exact list.
  • 403 set aside, not retested — these split into: 189 in categories that don’t exist under that name in KeyCommands.xml at all (mostly the Score categories: Score Functions, Score Meter Scale, Score Symbol Editor/Palettes, Scores, Scores Statusbar, Score Align Elements), 134 with no plausible command match in their real XML category, 46 with a string-similarity match that looked semantically different enough to need a human to check, and 34 fuzzy matches I originally trusted but demoted after finding they’d have collapsed multiple distinct old commands onto the same corrected name (ambiguous, not safe to assume).

So versus the original post’s headline number (594/1454, 40.9%, “don’t bind”): the real structurally-unbindable count looks to be somewhere well under 3% once the 403 are resolved, not 40%. Almost the entire original gap was the naming methodology issue you flagged, not an API limitation. Add Track (and the Inspector block, and Shuttle Play) remain the confirmed exceptions — those are genuine makeCommandBinding limitations, not casualties of the naming mismatch.

Next steps on my end: identify the exact 7 remaining failures, then go through the 403 set-aside ones by hand (the Score categories in particular are probably a real structural gap rather than a naming issue, since they don’t exist under any name in KeyCommands.xml). Will post again once that’s done.

Thanks again for pushing on this — the original 40.9% figure was just wrong, and I’d rather have the accurate number out there than let it stand.

I am getting back to you to point out that our mistake stemmed from trying to fully automate the process by relying on display names that—in some cases, at least—bear no relation to the actual command syntax.
We will therefore revisit the remaining commands to ensure we have the correct naming.
It is a real shame that there isn’t a file containing the correct, complete commands to prevent this type of error.

Hello everyone. To summarize: after numerous attempts and modifications—including successive renaming, discovering the actual “Score Editor” category (as opposed to the seven “fake” “Score” categories), and verifying the mapping batch by batch in the actual mapping assistant—we have reached a total of 1,337 assignable commands distributed across 60 categories. Of these, 15 cannot be bound, leaving 1,322 that are recognized and assignable.
In conclusion, with API 1.3, only 15 of the tested commands remain truly unrecognized by makeCommandBinding.

So, to sum up: the problem is solved—thanks to @m.c—pending a hypothetical future API update that would allow access to all Score Editor commands.

is this something you will share? or you keep this only for you? I have sherlock but since the windows changes, it’s a nightmare it doesn’t work anymore. with all kind of tests, so I was also looking to make one myself.. but if you have it and are willing to share.. why not testing what you have :wink: