MIDI remote API, Subpage creation when condition is fulfilled

Hi,

I’m fiddling around with the Cubase 12.0.40 demo and am currently checking the MIDI remote API.

Is there a way to activate a Subpage area when a condition is fulfilled ?

For example or better understanding : if i === 2 subpagearea x should get activated.

Thx!

yes :smiley:

1 Like
subpage.mAction.mActivate.trigger(activeDevice)
1 Like

@Jochen_Trappe

Jochen, thanks a lot for your reply.

My programming skills are pretty much not existent, last time I had to deal with javascript was about 20 years ago. With that being said, if I try the following within a function that gets called with activeDevice as an argument :

if (i === 2)
subpageEqHigh.mAction.mActivate.trigger(activeDevice) ;

The script stops and tells me that trigger expects type of MR_ActiveMapping as an argument.

If I try this:

if (i === 2)
subpageEqHigh.mAction.mActivate.trigger;

nothing happens, the condition has no consequence, subpage is not activated.

Do I have to use the subpage.mAction.mActivate.trigger thing in another context or does it simply need an argument of another kind (MR_ActiveMapping) ?

Hi @tannoy71, can you please post the full script here?

@Jochen_Trappe

Sure.

var panSurfacePage = surfacePageDefault;

pushencoders[11].mEncoderValue.mOnProcessValueChange = function (activeDevice, value){


    if (value > 0 && value < 1)
      panSurfacePage += 1;

    if (value === 1)
      panSurfacePage -= 1;

    if (panSurfacePage >= 2){
      panSurfacePage = 2;  
      subPageSurfaceShiftEqHighFreq.mAction.mActivate.trigger(activeDevice);
      }


    if (panSurfacePage <= 1)
      panSurfacePage = 1;   
   
  
        InitialPrintPageDisplay3(activeDevice, 'Page:0' + panSurfacePage.toString() + '/02');

        
 }

This is a snippet with the mentioned function. If I run it that way, the script messages ‘wrong type of native object’ when the value equals 2 and the subpage should be activated.

If I run it without an argument for ‘trigger’ (like “subPageSurfaceShiftEqHighFreq.mAction.mActivate.trigger;”) nothing happens despite the condition being true.

In the definition of the concerned classes in the midiremote_api_v1.js, ‘trigger’ is defined as to be used with an argument of type ‘MR_ActiveMapping’, if I understand it correctly. If I define a parameter on top of the function for ‘activeMapping’ being type of ‘MR_ActiveMapping’ and replace the relevant ‘activeDevice’ arguments with ‘activeMapping’ ones, I still get the ‘wrong type of native object’ message.

Hope this makes somewhat sense.

Thank you,

Marco.

Hi @tannoy71,

Now I understand. I gave a wrong hint, sorry for that.

Please have a look at the following example, it’ll show how to make subpage switching on a “higher level” (declaratively instead of imperatively).


var btnSwitchSubPages = deviceDriver.mSurface.makeButton(0, 0, 1, 1)
var knob = deviceDriver.mSurface.makeKnob(1, 0, 1, 1)

var subPageArea = page.makeSubPageArea('Sub Pages')
var subPage1 = subPageArea.makeSubPage('Sub Page 1')
var subPage2 = subPageArea.makeSubPage('Sub Page 2')
var subPage3 = subPageArea.makeSubPage('Sub Page 3')
var subPage4 = subPageArea.makeSubPage('Sub Page 4')

// ROUND ROBIN STYLE SUB PAGE SWITCHING
page.makeActionBinding(btnSwitchSubPages.mSurfaceValue, subPage2.mAction.mActivate).setSubPage(subPage1)
page.makeActionBinding(btnSwitchSubPages.mSurfaceValue, subPage3.mAction.mActivate).setSubPage(subPage2)
page.makeActionBinding(btnSwitchSubPages.mSurfaceValue, subPage4.mAction.mActivate).setSubPage(subPage3)
page.makeActionBinding(btnSwitchSubPages.mSurfaceValue, subPage1.mAction.mActivate).setSubPage(subPage4)

// VALUE BINDINGS FOR EACH SUB PAGE
page.makeValueBinding(knob.mSurfaceValue, page.mHostAccess.mTrackSelection.mMixerChannel.mValue.mVolume).setSubPage(subPage1)
page.makeValueBinding(knob.mSurfaceValue, page.mHostAccess.mTrackSelection.mMixerChannel.mValue.mPan).setSubPage(subPage2)
page.makeValueBinding(knob.mSurfaceValue, page.mHostAccess.mTrackSelection.mMixerChannel.mSends.getByIndex(0).mLevel).setSubPage(subPage3)
page.makeValueBinding(knob.mSurfaceValue, page.mHostAccess.mTrackSelection.mMixerChannel.mSends.getByIndex(1).mLevel).setSubPage(subPage4)
2 Likes

Hi @Jochen_Trappe ,

No worries, I just figured I gave you too less information - I’m sorry for that.

Thank you for your efforts. The example code you’ve been posting is exactly how I already have set it up now - I should have mentioned that.

Some background might be helpful: Since the Midi remote API doesn’t follow the concept of pages as the Mackie Control protocol does, I tried to find a way to at least indicate how many subpages are available and on which one the user is working right now via showing it on one of the control surface’s displays.

That would look like, if subpage 1 of 5 available subpages is activated it displays “Page:01/05”. On increasing the subpage number, the page number which is shown in the displays follows.

That works. I can implement that within a function that gets called with .mOnActivate.

That way, the page number which is displayed for the user is controlled by the subpage which is currently activated. I think this is what you referred to as declaratively ?

The downside to this is, that the user can only go up in pages and not up or down as she/he pleases to pick a specific pagenumber / subpage.

So I wanted to achieve it exactly the other way around (imperatively ?) - the page number which is displayed for the user should control which subpage is activated without the need for an action binding to a specific button.

That way I could assign a knob just for dialing through pages on the display / subpages on the script side.

Sorry for the confusion. I hope this sheds some more light on what I’m actually trying to achieve.

Hi @tannoy71,

what about this:


subPage1.mOnActivate = function(activeDevice, activeMapping) {
	InitialPrintPageDisplay3(activeDevice, 'Page:01/04');
}
subPage2.mOnActivate = function(activeDevice, activeMapping) {
	InitialPrintPageDisplay3(activeDevice, 'Page:02/04');
}
subPage3.mOnActivate = function(activeDevice, activeMapping) {
	InitialPrintPageDisplay3(activeDevice, 'Page:03/04');
}
subPage4.mOnActivate = function(activeDevice, activeMapping) {
	InitialPrintPageDisplay3(activeDevice, 'Page:04/04');
}

Hey @Jochen_Trappe,

thanks for that suggestion, but I assume you’ve overread (is that even a correct English term ?)
what I wrote about dealing with it that way, I’m gonna quote from my post above:

[…]That would look like, if subpage 1 of 5 available subpages is activated it displays “Page:01/05”. On increasing the subpage number, the page number which is shown in the displays follows.

That works. I can implement that within a function that gets called with .mOnActivate.

That way, the page number which is displayed for the user is controlled by the subpage which is currently activated. I think this is what you referred to as declaratively ?

The downside to this is, that the user can only go up in pages and not up or down as she/he pleases to pick a specific pagenumber / subpage.

So I wanted to achieve it exactly the other way around (imperatively ?) - the page number which is displayed for the user should control which subpage is activated without the need for an action binding to a specific button.

That way I could assign a knob just for dialing through pages on the display / subpages on the script side.

That means, it’s already implemented the way you are suggesting. But it has the mentioned drawbacks - therefore I was looking for a way to do it without the need of an action binding for activating a subpage.

The main concern is: Is it possible to activate a subpage other than by creating an action binding to a specific button/knob/younameit ?

Yes it is. I was just giving you a wrong hint in the first place.

For each sub page you create a “CustomValueVariable” and bind them together via “makeActionBinding”. Then in your encoder-callback you can trigger the according “CustomValueVariable” instead. That way you cannot accidently switch subpages that do not belong to the current mapping page. It has been quite a headache to deal with that problem. I know it’s not intuitive, but coding is never really intuitive, right? :wink:

So here is another example:

var btnGotoSubPage3 = deviceDriver.mSurface.makeButton(1, 0, 1, 1)
var knob = deviceDriver.mSurface.makeKnob(2, 0, 1, 1)

var valueActivateSubPage1 = deviceDriver.mSurface.makeCustomValueVariable('Activate SubPage 1')
var valueActivateSubPage2 = deviceDriver.mSurface.makeCustomValueVariable('Activate SubPage 2')
var valueActivateSubPage3 = deviceDriver.mSurface.makeCustomValueVariable('Activate SubPage 3')
var valueActivateSubPage4 = deviceDriver.mSurface.makeCustomValueVariable('Activate SubPage 4')

var subPageArea = page.makeSubPageArea('Sub Pages')
var subPage1 = subPageArea.makeSubPage('Sub Page 1')
var subPage2 = subPageArea.makeSubPage('Sub Page 2')
var subPage3 = subPageArea.makeSubPage('Sub Page 3')
var subPage4 = subPageArea.makeSubPage('Sub Page 4')

page.makeActionBinding(valueActivateSubPage1, subPage1.mAction.mActivate)
page.makeActionBinding(valueActivateSubPage2, subPage2.mAction.mActivate)
page.makeActionBinding(valueActivateSubPage3, subPage3.mAction.mActivate)
page.makeActionBinding(valueActivateSubPage4, subPage4.mAction.mActivate)

btnGotoSubPage3.mSurfaceValue.mOnProcessValueChange = function(activeDevice, value) {
	valueActivateSubPage3.setProcessValue(activeDevice, value)
}
1 Like

@Jochen_Trappe

Jochen,

I was fooling around somewhen a few days ago with the custom value variables to get this thing working.

I didn’t manage to get the setProcessValue part right and got stuck with exactly the problem you were describing: Subpages were switching which were not part of the current mapping page.

Your example works, that is the solution…awesome way to deal with it.

Thanks again for taking the time and helping me out, I appreciate it!

I owe you at least one beer (a very big one).

:beers:

Accepted! :crazy_face:

1 Like