Platform
Windows 10 pro 22H2 19045.3930
Cubase Pro 12.0.70
Only tested with JS scripts.
Issue
A MIDI device used in MIDI Remote can potentially lose its connection to MR if another MIDI device would for some reason disconnect.
At this point, the only remedy is to restart Cubase.
Details
Lets imagine the following setup on a Windows machine. 3 MIDI devices are connected to the PC, all via USB. The device used in MR is called “MyMRDevice”.
Windows adds all MIDI devices to a list as they become available to the system. In our case, the list of MIDI output ports looks like this when Cubase first starts.
Microsoft GS Wavetable Synth
MidiControler1
MyMRDevice
MidiController2
If “MidiController1” should disconnect (or be turned off), Windows list of MIDI output ports now looks as follows:
Microsoft GS Wavetable Synth
MyMRDevice
MidiController2
MIDI Remote has lost its connection to the “MyMRDevice”. Should you reconnect (or turn back on) the “MidiController1” device, Windows Output port list now looks like this:
Microsoft GS Wavetable Synth
MyMRDevice
MidiController2
MidiControler1
MIDI Remote will not be able to reconnect to MyMRDevice even if you reload the script.
The rest of Cubase appears unaffected. It is still possible to connect a MIDI Track to either of the ports in the above list at this point.
Hello, I confirm this behavior when we don’t have WinRT MIDI enabled. But once we do, I see no disconnection, and even when a port goes off and then back on after some time, the remote assigned to this port gets active again, while the other one never got disconnected.
Thank you for confirming and the added tip of using the WinRT MIDI.
Unfortunately for me, I can’t get my MR script to work when using WinRT. I noticed that the MIDI Port names changes when switching to WinRT, but I don’t know if that is the culprit. I did change my script to detect Input/Output ports using expectOutputNameContains rather than expectOutputNameEquals which I was using prior to testing WinRT.
The callback mOnActivate of the DeviceDriver never fires.
driver.mOnActivate = function (/** @type {MR_ActiveDevice} */ device) {
console.log("I'm activated") // <---- Never fires
}
My MIDI devices functions as normal using regular MIDI Tracks. Only the MIDI Remote gets stumped when I switch to WinRT.
Any thoughts or ideas would be greatly appreciated.
Ah, you have to have two detectionUnits so that you can cover both legacy and winRT cases.
Here’s an example from a script:
var midiInput = deviceDriver.mPorts.makeMidiInput("dawin")
var midiOutput = deviceDriver.mPorts.makeMidiOutput("dawout")
var detectWin=deviceDriver.makeDetectionUnit()
detectWin.detectPortPair(midiInput, midiOutput)
.expectInputNameContains('MIDIIN2')
.expectInputNameContains('Novation SL MkIII')
.expectOutputNameContains('MIDIOUT2')
.expectOutputNameContains('Novation SL MkIII')
.expectSysexIdentityResponse('002029','0101','0000')
// Windows RT
var detectWinRT=deviceDriver.makeDetectionUnit()
detectWinRT
.detectPortPair(midiInput, midiOutput)
.expectInputNameContains('SL MkIII')
.expectInputNameContains('Port 2')
.expectOutputNameContains('SL MkIII')
.expectOutputNameContains('Port 2')
.expectSysexIdentityResponse('002029','0101','0000')
//MacOS
var detectMac=deviceDriver.makeDetectionUnit()
detectMac
.detectPortPair(midiInput, midiOutput)
.expectInputNameEquals("Novation SL MkIII SL MkIII InControl")
.expectOutputNameEquals("Novation SL MkIII SL MkIII InControl")
As we can see, names are changed and so we need to cover this change. We can also see a sysexIdentityResponse, it can actually cover both cases without the need for filtering port names. At the moment I can’t remember why I have both port name filtering and sysexIdentity in this script, but it’s not important for our subject.
Thanks.
If I look at the bottom left of the MIDI Remote Script Console, I see two lists of MIDI Input port and Output ports respectively.
In my case, my port name changed from “Midi Fighter Twister” to “2 - Midi Fighter Twister [1]” with WinRT.
In my script I only made the following change (old lines commented out):
var midiInMF = driver.mPorts.makeMidiInput('MF')
var midiOutMF = driver.mPorts.makeMidiOutput('MF')
var detUnit = driver.makeDetectionUnit()
var detectPortPairMF = detUnit.detectPortPair(midiInMF, midiOutMF)
detectPortPairMF
// .expectInputNameEquals('Midi Fighter Twister')
.expectInputNameContains('Midi Fighter Twister')
// .expectOutputNameEquals('Midi Fighter Twister')
.expectOutputNameContains('Midi Fighter Twister')
I would expect this to work for both legacy and winRT.
I did notice other MIDI devices got renamed completely, but in this case, it was only an added prefix and a suffix.
The inputNameContains is “vicious”. If you look at my snippet, you’ll see two “contains” per port. This is actually acting as a logical “and”, not as an “or” as one would expect when seeing the logger window. If you take out any of these two, no recognition is taking place.
This is empirical, so I would suggest that you try adding a second “contains” to your detection unit.
Cool! So, you need to have different detection units for legacy and winRT, give this one a try, I’m setting the ports to winRT to equal, so adjust this to fit the names:
var driver = midiremote_api.makeDeviceDriver('DJ TECHTOOLS', 'Midi Fighter Twister Pro', 'Mama')
var midiInMF = driver.mPorts.makeMidiInput('MF')
var midiOutMF = driver.mPorts.makeMidiOutput('MF')
var midiInAHK = driver.mPorts.makeMidiInput('AHK')
var midiOutAHK = driver.mPorts.makeMidiOutput('AHK')
var detUnit = driver.makeDetectionUnit()
var detectPortPairMF = detUnit.detectPortPair(midiInMF, midiOutMF)
detectPortPairMF
.expectInputNameContains('Midi Fighter Twister') //Legacy name
.expectOutputNameContains('Midi Fighter Twister') //Legacy name
var detectPortPairAHK = detUnit.detectPortPair(midiInAHK, midiOutAHK)
detectPortPairAHK
.expectInputNameContains('AHK') //Legacy name
.expectOutputNameContains('AHK') //Legacy name
var detUnitRT = driver.makeDetectionUnit()
var detectPortPairMFRT = detUnitRT.detectPortPair(midiInMF, midiOutMF)
detectPortPairMFRT
.expectInputNameEquals('2 - Midi Fighter Twister [1]') //WinRT name
.expectOutputNameEquals('2 - Midi Fighter Twister [0]') //WinRT name
var detectPortPairAHKRT = detUnitRT.detectPortPair(midiInAHK, midiOutAHK)
detectPortPairAHKRT
.expectInputNameEquals('AHK [1]') //WinRT name
.expectOutputNameEquals('AHK [1]') //WinRT name
driver.mOnActivate = function (/** @type {MR_ActiveDevice} */ device) {
console.log("I'm activated") // <---- Never fires
}
I tried again, pasting in your change, but I still can’t get it to work, I’m afraid.
The port names in your snippet matches what I can see under “MIDI Input Ports”/“MIDI Output Ports” in the MIDI Remote Script Console.
As a test, I also tried “NameContains” for both detection variants.
As soon as I uncheck “Use Device ‘WinRT MIDI’” in Studio Setup my script starts working immediately.
Yes, this is because your detection unit for the legacy midi ports is working OK.
One thing that made my own script not working (for my Keylab) is that when in winRT mode, both my midi out ports are named identically, so the script can’t grab the correct one. Wondering if you’re facing something similar.