Zoom and Project scroll using knobs

Hi!

Just started using remote scripts with a special idea in mind. I have a Monogram Creative Console with 3 knobs. Using Cubase it’s only possible to Zoom In our Out when assigning a command to a knob but not zoom out when knob is turned left and zoom in when knob is turned right. I also want to do this for project scrolling for one knob.

I imagine scripting should allow this one way or another but haven’t figured out exactly how. The knob needs to be relative and it needs to send a command for “Zoom in” when values are decreased and “zoom out” when values are increased.

Not sure exactly from the Api reference (that would need some further details btw) how this would be achieved :thinking:

Have a look here. If you can figure out how to make this work via script, please share!

2 Likes

Oh thanks! That looks really promising :tada:

Awesome, this work! Just need to change the knob to relative but got the zoom to work. Will post when I have a finished piece of code.

1 Like

Here’s some working code for setting one knob to zoom and one knob to nudge (move project cursor) if it helps anyone in the future:

//-----------------------------------------------------------------------------
// 2. SURFACE LAYOUT - create control elements and midi bindings
//-----------------------------------------------------------------------------

// create control element representing your hardware's surface
var knob = deviceDriver.mSurface.makeKnob(0, 0, 1, 3)
var knob2 = deviceDriver.mSurface.makeKnob(3, 0, 1, 3)

// bind midi ports to surface elements
knob.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 42).setTypeRelativeBinaryOffset();
knob2.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 44).setTypeRelativeBinaryOffset();

//-----------------------------------------------------------------------------
// 3. HOST MAPPING - create mapping pages and host bindings
//-----------------------------------------------------------------------------
var page = deviceDriver.mMapping.makePage('Default')

// Nudge Knob
var nudgeLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('NudgeLeft')
var nudgeRightVariable = deviceDriver.mSurface.makeCustomValueVariable('NudgeRight')

page.makeCommandBinding(nudgeLeftVariable, 'Transport', 'Nudge Cursor Left')
page.makeCommandBinding(nudgeRightVariable, 'Transport', 'Nudge Cursor Right')

createCommandKnob(knob, nudgeLeftVariable, nudgeRightVariable);

// Zoom knob
var zoomInVariable = deviceDriver.mSurface.makeCustomValueVariable('ZoomIn')
var zoomOutVariable = deviceDriver.mSurface.makeCustomValueVariable('ZoomOut')

page.makeCommandBinding(zoomInVariable, 'Zoom', 'Zoom In')
page.makeCommandBinding(zoomOutVariable, 'Zoom', 'Zoom Out')

createCommandKnob(knob2, zoomInVariable, zoomOutVariable);

/**
 * @param {MR_Knob} knob
 * @param {MR_SurfaceCustomValueVariable} commandIncrease
 * @param {MR_SurfaceCustomValueVariable} commandDecrease
 */

function createCommandKnob(knob, commandIncrease, commandDecrease) {
  knob.mSurfaceValue.mOnProcessValueChange = function(activeDevice, value) {
    if(value === 0 ) {
      commandIncrease.setProcessValue(activeDevice, 1)
    } else if (value === 1) {
      commandDecrease.setProcessValue(activeDevice, 1)
    }
  }
}
5 Likes

@pettor I’ve been attempting to use your technique above for nudging the cursor (thank you for sharing). It works in my case BUT the CC midi events are still sent to the selected track (and recorded!).

I can’t figure out how to stop the CC events from going to the track. Does this occur in your case? Is there a missing function call in the example code?

Try and remove your controller from “All MIDI” in Studio Setup.
Alternatively, on your MIDI/Instrument track, change the Input from All to the device you want to record.

Thanks for the suggestions. Those will of course filter it out but when other bindings done Midi remote absorbs the CC messages if the CC is assigned to some sort of Cubase Surface binding. In the case above, that doesn’t appear to occur. Whilst the customValueVariables are bound to commands, the Knob itself is not - and the Knob is thus passing information straight throughs till. That is at least what I think is going. Some how I need the knob to not send to Cubase.

1 Like

Is this true? I haven’t used the new MIDI Remote enough to tell, but the older Generic Remote passed any and all CC regardless of remote binding. I didn’t expect the new MIDI Remote to work any differently.

I haven’t had the chance to test this, but I strongly suspect it’s as @robw says. Since the commands end up assigned to the knob by proxy of the custom commands, the assignment of the main knob remains blank, and will probably continue to send to cubase whatever the knob is supposed to send from the device’s hardware side.

Yepp, sadly I have the same issue. I tried using channels to fix the issue but it still records the CC events. It feels like I should be able to tell Cubase to only record events on channel 1 and skip the others but not sure how.

Right now I try to use CC events that I know are unused from the list below (like 102-119). I also seldom use my knobs when recording since I mostly use them for zooming, panning etc.

Sorry for spending so much time on that issue, it’s dead simple. You have to set the “.setIsConsuming(true)” flag on the MIDI-binding.

please replace

with

// bind midi ports to surface elements
knob.mSurfaceValue.mMidiBinding.setInputPort(midiInput).setIsConsuming(true).bindToControlChange(0, 42).setTypeRelativeBinaryOffset();
knob2.mSurfaceValue.mMidiBinding.setInputPort(midiInput).setIsConsuming(true).bindToControlChange(0, 44).setTypeRelativeBinaryOffset();
1 Like

I tried transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) transport.jog_wheel.mEncoderValue.mMidiBinding .setInputPort(midiInput) .setIsConsuming(true) .bindToControlChange(0, 60) .setTypeAbsolute()

and it doesn’t stop the control Change 60 coming through if All Midi in is active on the input port.

I just retried it at our suggestion and it still fails to consume the value.

Code in full is here in case I’m doing it wrong: