Device Page Controls limitation?

Post Reply New Topic
RELATED
PRODUCTS

Post

I've been investigating the controller script API for the past couple of nights and I'm looking to write a script for a hardware controller that has 32 rotary knobs. I'd like to assign controls from each page of the selected device to the 32 rotary knobs.

However, it appears that only the 8 controls on the device page currently showing can be observed at anyone time and thus sent to the hardware - is this correct? Switching pages then updates those 8 to that page's controls, so potentially only 8 rotaries can be live at a time here for a device?

Ideally I'd like to loop through 4 pages to get 8 controls from each to assign to 32 rotary encoders, but it doesn't seem like this approach is achievable unless I'm looking at this the wrong way?

Post

Haven't looked into 2.4 yet, but in 2.3.x you could simply acquire 4 instances of CursorRemoteControlsPage from a CursorDevice (not sure whether from the same or multiple ones), using the 3-parameter version of createCursorRemoteControlsPage(name, parameterCount, filterExpression) which doesn't auto-follow the GUI's parameter page selection. Use some unique name per instance, parameterCount 8 and filterExpression an empty string, and make sure you update each CursorRemoteControlsPage instance's selectedPageIndex to 0-3 respectively both after creation and whenever the CursorDevice indicates that the selected device changed (e.g. by observing the name).

Post

bassc wrote:I've been investigating the controller script API for the past couple of nights and I'm looking to write a script for a hardware controller that has 32 rotary knobs. I'd like to assign controls from each page of the selected device to the 32 rotary knobs.

However, it appears that only the 8 controls on the device page currently showing can be observed at anyone time and thus sent to the hardware - is this correct? Switching pages then updates those 8 to that page's controls, so potentially only 8 rotaries can be live at a time here for a device?

Ideally I'd like to loop through 4 pages to get 8 controls from each to assign to 32 rotary encoders, but it doesn't seem like this approach is achievable unless I'm looking at this the wrong way?
Yes, that's a bit of a problem. Even if you enlarge the page size of a parameter bank you only get maximum 9 parameters, which means a bank page can only address 1 mapping page (most contain 8 parameters but there are some with 9).
To solve your problem you would need to create 4 parameter banks with the size of 8 (8 * 4 = 32). After that you need to take care yourself to manage the offset between the 4 banks. But I have not tried that so far.

Post

Thanks for the replies guys, I'll give some of this a go and see how it pans out.

Post

BufoBufo - your advice has been helpful here.

Getting 4 instances of CursorRemoteControlsPage seemed like the way to go, but I found each instance's getParameter(p) lead back to just the displayed page. e.g. remotePages[x].getParameter(p), where x is 0 to 3, always returns parameter p on the current displayed page?

I also wondered if there was a good way to determine if the device had changed, since devices can have the same name? And the same name and position on different tracks?

Finally, the only way I can currently see how I might be able to work the pages onto the controller is:

- When I select a device, go through each page to update the controller (4 pages x 8 controllers onto 32 rotary knobs)
- On midi in, determine the page and switch the device's page on the fly so that the incoming CC is directed as intended

Is there a better way?

Post

bassc wrote: Getting 4 instances of CursorRemoteControlsPage seemed like the way to go, but I found each instance's getParameter(p) lead back to just the displayed page. e.g. remotePages[x].getParameter(p), where x is 0 to 3, always returns parameter p on the current displayed page?
Then you haven't set the page's index at the right time. I mistakenly said the cursordevice' name observer was a good place for that, but it should be the pageNames observer of each of your RC page instances individually. That observer also has the benefit of telling you whether or not the current device has enough RC pages for all your BCR's 4 encoder rows.
I also wondered if there was a good way to determine if the device had changed, since devices can have the same name? And the same name and position on different tracks?
AFAIK, the device name observer *always* fires, no matter if you switch between two devices with the same name.

Before continuing your BCR script, try experimenting more with the API to get a feeling of how everything behaves. Use println a lot. This little script may be helpful to start your Multi-RC experiments.. Good luck!

Code: Select all

loadAPI(6);

host.defineController('test', 'RC Pages Test', '1.0', '9877f0e1-1d18-43a1-a2c8-a9890395ad06', 'meme');
host.defineMidiPorts(0,0);

function init() {
    var TOTAL_RC_PAGES = 4,
        PARAMS_PER_RC_PAGE = 8,
        cursorTrack = host.createCursorTrack(0, 0),
        cursorDevice = cursorTrack.createCursorDevice(),
        rcPages;

    rcPages = initArray(null, TOTAL_RC_PAGES).map(function(foo, OWN_PAGE_INDEX) {
        var instanceName = 'MyRCPage' + OWN_PAGE_INDEX,
            rcPage = cursorDevice.createCursorRemoteControlsPage(instanceName, PARAMS_PER_RC_PAGE, ''),
            currentMaxPageIndex = 0,
            isPageAvailable = false,
            ownParams;

        rcPage.pageNames().addValueObserver(function(names) {
            currentMaxPageIndex = names.length - 1;

            isPageAvailable = OWN_PAGE_INDEX <= currentMaxPageIndex;

            if (isPageAvailable) {
                rcPage.selectedPageIndex().set(OWN_PAGE_INDEX);
                println(instanceName + ' is mapped to parameter page ' + (names[OWN_PAGE_INDEX] || '??'));
            } else {
                println(instanceName + ' currently unavailable');
                // this rcPage's parameter values "auto-fallback" to those of the device's last existing parameter page
            }
        });

        ownParams = initArray(null, PARAMS_PER_RC_PAGE).map(function(foo, PARAM_INDEX) {
            var param = rcPage.getParameter(PARAM_INDEX);

            param.value().addValueObserver(128, function(newVal) {
                println('Param ' + PARAM_INDEX + ' of ' + instanceName + ' changed to = ' + newVal);
                if (isPageAvailable) {
                    // add sync to midi device here
                }
            });

            return param;
        });

        return rcPage;
    });

    println('ready');
}

Post

Thanks BufoBufo, I will check through that script. Also have not tried that observer.

It's a Mackie Control C4 I'm implementing. Have made good progress and everything is done bar nailing this multi-page refreshing and getting a clean way of updating all encoders when required. Unlimited device pages will be implemented via bank switch buttons, with 4 x 8 shown at a time.

Post Reply

Return to “Controller Scripting”