I bought a Stream Deck Plus XL and I’m redoing the script I had made with midi remote api.
Everything works correctly except when I change banks in Cubase by pressing the bank change buttons on the created surface.
When I change banks by pressing the buttons everything is synchronized correctly except the names of the tracks, the colors, the panorama value and the fader position value.
In other words, every time I change banks by pressing the midi remote buttons, the names, colors, and numerical values of fader and panorama are always the values of the tracks in bank number 1.
That is, when I press the next bank and previous bank buttons, the sysex I receive are always from bank 1, while the rest of the information is correct.
On the other hand, if I select tracks directly in the cubase project with the mouse, the bank change is completely performed, everything is synchronized correctly.
What is wrong with my code? Why do the bank change buttons change the bank but not update the sysex messages?
var midiremote_api = require('midiremote_api_v1')
var deviceDriver = midiremote_api.makeDeviceDriver('elgato', 'Stream Deck Plus', 'JCT')
var midiInput = deviceDriver.mPorts.makeMidiInput()
var midiOutput = deviceDriver.mPorts.makeMidiOutput()
deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
.expectInputNameEquals('IAC_EverybodyToCubaseMidi')
.expectOutputNameEquals('IAC_CubaseMidiToEverybody')
var page = deviceDriver.mMapping.makePage('Default')
var bankSize = 6
var bankMidiChannel = 10 //channel 11
var bankSysexHeader = 0x01
var hostBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone('BankZone')
hostBankZone.excludeInputChannels()
hostBankZone.excludeOutputChannels()
hostBankZone.excludeWindowZoneLeftChannels()
hostBankZone.excludeWindowZoneRightChannels()
hostBankZone.setFollowVisibility(true)
var hostBankTrack = []
for (var i = 0; i < bankSize; i++) {
hostBankTrack[i] = hostBankZone.makeMixerBankChannel()
}
var surface = deviceDriver.mSurface
var surfaceRows_BankMutes = 1
var surfaceRows_BankSolos = 2
var surfaceRows_BankPans = 3
var surfaceRows_BankVols = 4
var surfaceRows_BankSelects = 8
// MUTE
var surfaceBankMuteButton = []
for (var i = 0; i < bankSize; i++) {
surfaceBankMuteButton[i] = surface.makeButton (i, surfaceRows_BankMutes, 1, 1)
surfaceBankMuteButton[i].mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(bankMidiChannel, 21 + i)
}
// SOLO
var surfaceBankSoloButton = []
for (var i = 0; i < bankSize; i++) {
surfaceBankSoloButton[i] = surface.makeButton (i, surfaceRows_BankSolos, 1, 1)
surfaceBankSoloButton[i].mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(bankMidiChannel, 31 + i)
}
// PAN
var surfaceBankPanoramaKnob = []
for (var i = 0; i < bankSize; i++) {
surfaceBankPanoramaKnob[i] = surface.makeKnob(i, surfaceRows_BankPans, 1, 1)
surfaceBankPanoramaKnob[i].mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(bankMidiChannel, 11 + i)
}
// VOLUME
var surfaceBankVolumeFader = []
for (var i = 0; i < bankSize; i++) {
surfaceBankVolumeFader[i] = surface.makeFader(i, surfaceRows_BankVols, 1, 3)
surfaceBankVolumeFader[i].mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(bankMidiChannel, 1 + i)
}
// SELECT
var surfaceBankSelectButton = []
for (var i = 0; i < bankSize; i++) {
surfaceBankSelectButton[i] = surface.makeButton (i, surfaceRows_BankSelects, 1, 1)
surfaceBankSelectButton[i].mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange(bankMidiChannel, 41 + i)
}
// BANK NAVIGATION
var surfaceBankButtonSwitchToPrevBank = surface.makeButton (0,10,0,0)
var surfaceBankButtonSwitchToNextBank = surface.makeButton (1,10,0,0)
var surfaceBankButtonShiftLeft = surface.makeButton (2,10,0,0)
var surfaceBankButtonShiftRight = surface.makeButton (3,10,0,0)
var surfaceBankButtonResetBank = surface.makeButton (4,10,0,0)
surfaceBankButtonSwitchToPrevBank.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange (bankMidiChannel, 126) // channel 11, cc 126
surfaceBankButtonSwitchToNextBank.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange (bankMidiChannel, 127) // channel 11, cc 127
surfaceBankButtonShiftLeft.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange (bankMidiChannel, 101) // channel 11, cc 101
surfaceBankButtonShiftRight.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange (bankMidiChannel, 102) // channel 11, cc 102
surfaceBankButtonResetBank.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.setOutputPort(midiOutput)
.bindToControlChange (bankMidiChannel, 103) // channel 11, cc 103
for (var i = 0; i < bankSize; i++) {
page.makeValueBinding(surfaceBankVolumeFader[i].mSurfaceValue, hostBankTrack[i].mValue.mVolume)
page.makeValueBinding(surfaceBankPanoramaKnob[i].mSurfaceValue, hostBankTrack[i].mValue.mPan)
page.makeValueBinding(surfaceBankMuteButton[i].mSurfaceValue, hostBankTrack[i].mValue.mMute)
page.makeValueBinding(surfaceBankSoloButton[i].mSurfaceValue, hostBankTrack[i].mValue.mSolo)
page.makeValueBinding(surfaceBankSelectButton[i].mSurfaceValue, hostBankTrack[i].mValue.mSelected)
}
page.makeActionBinding(surfaceBankButtonSwitchToPrevBank.mSurfaceValue, hostBankZone.mAction.mPrevBank)
page.makeActionBinding(surfaceBankButtonSwitchToNextBank.mSurfaceValue, hostBankZone.mAction.mNextBank)
page.makeActionBinding(surfaceBankButtonShiftLeft.mSurfaceValue, hostBankZone.mAction.mShiftLeft)
page.makeActionBinding(surfaceBankButtonShiftRight.mSurfaceValue, hostBankZone.mAction.mShiftRight)
page.makeActionBinding(surfaceBankButtonResetBank.mSurfaceValue, hostBankZone.mAction.mResetBank)
var bankTrackNames = []
var bankTrackNamesSysexHeader = 1
var bankTrackColors = []
var bankTrackColorsSysexHeader = 21
var bankTrackPanoramas = []
var bankTrackPanoramasSysexHeader = 41
var bankTrackFaderPositions = []
var bankTrackFaderPositionsSysexHeader = 61
var bankTrackTypes = []
var bankTrackTypesSysexHeader = 81
var daMixer = page.mHostAccess.makeDirectAccess(hostBankZone) //used for getting the track type in the "for" loop
for (var i = 0; i < bankSize; i++) {
// get name and get type of every track of bank
hostBankTrack[i].mOnTitleChange = (function(trackIndex) {
return function(activeDevice, activeMapping, title) {
var validString = title.length === 0 ? " " : title
bankTrackNames[trackIndex+1] = validString
var bankTrackNamesConsoleLogPrefix = "Bank, Track " + (trackIndex+1) + " - Name: "
sendSysexString(activeDevice, validString, bankSysexHeader, bankTrackNamesSysexHeader + trackIndex, bankTrackNamesConsoleLogPrefix)
var trackID = hostBankTrack[trackIndex].getRuntimeID(activeMapping)
var objectUniqueName = daMixer.getObjectUniqueName(activeMapping, trackID)
var trackType = objectUniqueName.replace(/\s?\d+$/, '')
bankTrackTypes[trackIndex + 1] = trackType
var bankTrackTypesConsoleLogPrefix = "Bank, Track " + (trackIndex+1) + " - Type: "
sendSysexString(activeDevice, trackType, bankSysexHeader, bankTrackTypesSysexHeader + trackIndex, bankTrackTypesConsoleLogPrefix)
}
})(i)
// get color of every track of bank
hostBankTrack[i].mOnColorChange = (function(trackIndex) {
return function(activeDevice,activeMapping,r,g,b,a){
var validColorCode = getColorCodeWithoutAlphaChannel (r,g,b,a)
bankTrackColors[trackIndex+1] = validColorCode
var bankTrackColorsConsoleLogPrefix = "Bank, Track " + (trackIndex+1) + " - Color: "
sendSysexString(activeDevice, validColorCode ,bankSysexHeader, bankTrackColorsSysexHeader + trackIndex, bankTrackColorsConsoleLogPrefix)
}
})(i)
// get pan value of every track of bank: setup custom vars to control the pan, in order for the mOnDisplayValueChange to refresh properly
var bankPanValues=surface.makeCustomValueVariable("bankPanValues" + i)
page.makeValueBinding(bankPanValues, hostBankTrack[i].mValue.mPan)
hostBankTrack[i].mValue.mPan.mOnDisplayValueChange = (function(trackIndex) {
return function(activeDevice, activeMapping, displayValue) {
var panValue = displayValue
if (panValue === "") {panValue = "X"}
bankTrackPanoramas[trackIndex+1] = panValue
var bankTrackPanoramasConsoleLogPrefix = "Bank, Track " + (trackIndex+1) + " - Pan: "
sendSysexString(activeDevice, panValue, bankSysexHeader, bankTrackPanoramasSysexHeader + trackIndex, bankTrackPanoramasConsoleLogPrefix)
}
})(i)
// get faderPosition value of every track of bank: setup custom vars to control the faderPosition, in order for the mOnDisplayValueChange to refresh properly
var bankFaderValues=surface.makeCustomValueVariable("bankFaderValues" + i)
page.makeValueBinding(bankFaderValues, hostBankTrack[i].mValue.mVolume)
hostBankTrack[i].mValue.mVolume.mOnDisplayValueChange = (function(trackIndex) {
return function(activeDevice, activeMapping, displayValue) {
var faderPosition = displayValue
bankTrackFaderPositions[trackIndex+1] = faderPosition
var bankTrackFaderPositionsConsoleLogPrefix = "Bank, Track " + (trackIndex+1) + " - FaderPosition: "
sendSysexString(activeDevice, faderPosition, bankSysexHeader, bankTrackFaderPositionsSysexHeader + trackIndex, bankTrackFaderPositionsConsoleLogPrefix)
}
})(i)
}
// GLOBAL FUNCTIONS
// convert r,g,b to hexadecimal color code "rrggbb"
function getColorCodeWithoutAlphaChannel(redCode,greenCode,blueCode,alphaChannel){
var r255=Math.round(255*redCode)
var g255=Math.round(255*greenCode)
var b255=Math.round(255*blueCode)
var a255=Math.round(255*alphaChannel)
var r255hex=r255.toString(16)
var g255hex=g255.toString(16)
var b255hex=b255.toString(16)
var a255hex=a255.toString(16)
if (r255hex==="0") {r255hex="00"}
if (g255hex==="0") {g255hex="00"}
if (b255hex==="0") {b255hex="00"}
if (a255hex==="0") {a255hex="00"}
var colorCodeWithoutAlphaChannel=r255hex+g255hex+b255hex
return colorCodeWithoutAlphaChannel
}
// send sysex and show log in console
function sendSysexString(activeDevice,receivedString,sysexHeader1,sysexHeader2,consolePrefix){
var sysexMessage=[0xF0,sysexHeader1,sysexHeader2].concat(receivedString.split('').map(function(c){return c.charCodeAt(0)})).concat([0xF7])
midiOutput.sendMidi(activeDevice,sysexMessage)
console.log(consolePrefix + receivedString)
}
…calling @m.c ![]()
By the way, I’m running Cubase 15.0.21 and macOS 15.7.7