Dear forum members,
whenever I try to activate a subpage by the press of a button I have to push it twice before the change takes place. I have tried different setups for that button like push / toggle / momentary and tap (editable in my controller) but I cannot make the change happen instantly with the first button press.
Any help is appreciated,
Emre
function makePageSelectedTrack() {
var page = makePageWithDefaults("SelectedTrack");
var console1SubPageArea = page.makeSubPageArea("Console1");
var console1EqSubPage = console1SubPageArea.makeSubPage("C1_Eq");
var console1DynSubPage = console1SubPageArea.makeSubPage("C1_Dyn");
page.makeActionBinding(
surfaceElements.touchButtonsL[0].mSurfaceValue,
console1EqSubPage.mAction.mActivate
);
page.makeActionBinding(
surfaceElements.touchButtonsL[1].mSurfaceValue,
console1DynSubPage.mAction.mActivate
);
numAssignableEncoders = 12;
var numParameters = numAssignableEncoders * 4;
var parameters = [];
var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel;
// Accessing object to Insert of selected track
var HostInsertViewer = selectedTrackChannel.mInsertAndStripEffects
.makeInsertEffectViewer("")
.excludeEmptySlots()
.followPluginWindowInFocus();
// Create Paramaters Array
for (var i = 0; i < numParameters; i++) {
var parameter = HostInsertViewer.mParameterBankZone.makeParameterValue();
parameters.push(parameter);
}
console1EqSubPage.mAction.mActivate;
console1EqSubPage.mOnActivate = function () {
// Bind knobs and buttons of encoders array to parameters
for (var i = 0; i < numAssignableEncoders; i++) {
page.makeValueBinding(
surfaceElements.encoders[i].mEncoderValue,
parameters[i]
);
page
.makeValueBinding(
surfaceElements.encoders[i].mPushValue,
parameters[i + numAssignableEncoders]
)
.setTypeToggle();
printEncoderDisplay(i);
}
};
console1DynSubPage.mOnActivate = function () {
for (var idx = 0; idx < numAssignableEncoders; ++idx) {
page.makeValueBinding(
surfaceElements.encoders[idx].mEncoderValue,
parameters[idx + numAssignableEncoders * 2]
);
page
.makeValueBinding(
surfaceElements.encoders[idx].mPushValue,
parameters[idx + numAssignableEncoders * 3]
)
.setTypeToggle();
printEncoderDisplay(idx);
}
};
return page;
}
This part of the code looks correct.
What you describe is most probably due to the touchButtonsL[0-1] being set to toggle mode.
You can inspect that for a start, by placing in your code this function:
surfaceElements.touchButtonsL[0].mSurfaceValue.mOnProcessValueChange=function(activeDevice,value,diff){
console.log("touchB0 value set to "+value+" diff="+diff)
}
Open your remote console, and press 2-3 times the touchButtonL[0] in order to trigger this function, and from there by posting a screenshot, we can work this out I hope.
OK, so the buttons are in gate mode. Then, you shouldn’t have any problem at all.
BUT now I see the real problem, it’s actually how you setup the subpages. You think that the assignments should be made inside the mOnActivate events, while this is not unfortunately true, though I can understand why you thought this way.
Let me quickly rewrite it for you:
function makePageSelectedTrack() {
var page = makePageWithDefaults("SelectedTrack");
var console1SubPageArea = page.makeSubPageArea("Console1");
var console1EqSubPage = console1SubPageArea.makeSubPage("C1_Eq");
var console1DynSubPage = console1SubPageArea.makeSubPage("C1_Dyn");
page.makeActionBinding(surfaceElements.touchButtonsL[0].mSurfaceValue,console1EqSubPage.mAction.mActivate);
page.makeActionBinding(surfaceElements.touchButtonsL[1].mSurfaceValue,console1DynSubPage.mAction.mActivate);
var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel;
// Accessing object to Insert of selected track
var HostInsertViewer = selectedTrackChannel.mInsertAndStripEffects
.makeInsertEffectViewer("")
.excludeEmptySlots()
.followPluginWindowInFocus();
// Create Paramaters Array
numAssignableEncoders = 12;
var numParameters = numAssignableEncoders * 4;
var parameters = [];
for (var i = 0; i < numParameters; i++) {
var parameter = HostInsertViewer.mParameterBankZone.makeParameterValue();
parameters.push(parameter);
}
// console1EqSubPage.mAction.mActivate;
for (var i = 0; i < numAssignableEncoders; i++) {
page.makeValueBinding(
surfaceElements.encoders[i].mEncoderValue,
parameters[i]
).setSubPage(console1EqSubPage);
page
.makeValueBinding(surfaceElements.encoders[i].mPushValue,parameters[i+numAssignableEncoders])
.setTypeToggle().setSubPage(console1EqSubPage);
printEncoderDisplay(i);
}
for (var idx = 0; idx < numAssignableEncoders; ++idx) {
page.makeValueBinding(surfaceElements.encoders[idx].mEncoderValue,parameters[idx+numAssignableEncoders*2]).setSubPage(console1DynSubPage);
page.makeValueBinding(surfaceElements.encoders[idx].mPushValue,parameters[idx+numAssignableEncoders*3]
).setTypeToggle().setSubPage(console1DynSubPage);
printEncoderDisplay(idx);
}
console1EqSubPage.mOnActivate = function () {
};
console1DynSubPage.mOnActivate = function () {
};
return page;
}
Please inspect the code in order to understand how the subPages concept really works.
By the way, what exactly is the sub printEncoderDisplay supposed to do?
Thanks a lot Minas, I am as always impressed by your knowledge and huge helpfulness!
You are right, I didn´t get the concept of subpages yet and I haven´t found a clear documentation in that regard. I wonder how others like you get into these concepts…
Anyway, your code works perfect and I am very happy!
My function printEncoderDisplay() is responsible for pushing the data to my mobile phones display. I use another software calles open stage control to make my phone act like a controller, all midi is merged with bome midi translator. If you want to know more details let me know…
// Print encoder display
function printEncoderDisplay(idx) {
var rows = [0x14, 0x15, 0x16];
rows.forEach(function(row) {
var valueType, trigger;
if (row == 0x14) {
valueType = 'mEncoderValue';
trigger = 'mOnTitleChange';
} else if (row == 0x15) {
valueType = 'mEncoderValue';
trigger = 'mOnDisplayValueChange';
} else if (row == 0x16) {
valueType = 'mPushValue';
trigger = 'mOnDisplayValueChange';
}
surfaceElements.encoders[idx][valueType][trigger] =
function (activeDevice, arg1, arg2) {
var print = row == 0x14 ? arg2 : arg1;
var startAt = 0x00;
var OscLcdIdx = 11 + this.idx;
var numColumns = 10;
var OscLcdIdxSysex = "0x" + OscLcdIdx.toString();
var dataDisplay = [0xf0, 0x00, 0x00, 0x66, row, OscLcdIdxSysex, startAt];
var printLength = print.length;
if (printLength < numColumns) {
while (printLength++ < numColumns) {
print = print + " ";
}
}
for (var i = 0; i < numColumns; ++i) {
dataDisplay.push(print.charCodeAt(i));
}
dataDisplay.push(0xf7);
midiOutput.sendMidi(activeDevice, dataDisplay);
}.bind({ idx });
});
}
I wish you and everybody else a merry Christmas and a wonderful time with your beloved ones!
Emre
After altering the code, you can keep this function just in the first for loop, since the contents as far as I can tell are identical, so in reality the second one is just a duplicate.