Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Traktor Kontrol S2MK3: Use FX select buttons to set quick effect presets #11702

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 86 additions & 6 deletions res/controllers/Traktor-Kontrol-S2-MK3-hid-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,19 +670,92 @@ TraktorS2MK3.wheelDeltas = function(deckNumber, value) {
};

TraktorS2MK3.fxHandler = function(field) {
/* We support 8 effects in total by having 2 effects per fx button. *
* First press of the button will load the preset at the index of the quick effect preset list *
* Second press will load the preset index + 4 *
* Arrange your quick effect preset list from 1 to 8 like this: 1/5, 2/6, 3/7, 4/8 */
if (field.value === 0) {
return;
}

const availableGroups = ["[Channel1]", "[Channel2]"];
const fxButtonCount = 4;
let targetGroups = [];
const fxNumber = parseInt(field.id[field.id.length - 1]);
const group = "[EffectRack1_EffectUnit" + fxNumber + "]";
let noShift = false;

// Toggle effect unit
TraktorS2MK3.fxButtonState[fxNumber] = !TraktorS2MK3.fxButtonState[fxNumber];
// Target decks whose shift button is pressed.
for (const group of availableGroups) {
if (TraktorS2MK3.shiftPressed[group]) { targetGroups.push(group); }
}

// If no shift button was pressed fall back to target all decks.
if (targetGroups.length === 0) {
targetGroups = availableGroups;
noShift = true;
}
Comment on lines +692 to +696
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to check here that the effect knob is in zero position (or close to it)? Otherwise we could reassign the effect chain preset, while it's audible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is up to the user to decide, and the learing curve should be pretty steep ;)
Related: #11198

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this works currently, but when I used the code from my old PR knobs would always reset when switching effect, whether that be to the center position or the zero position and the knob would only control it again when moved back to the initial point.


const fxToApply = {};
const activeFx = {};
// Detect which fx should be enabled
for (const group of targetGroups) {
activeFx[group] = engine.getValue(`[QuickEffectRack1_${group}]`, "loaded_chain_preset") - 1;
if (activeFx[group] === fxNumber) {
// Pressing again the fx button
fxToApply[group] = fxNumber + fxButtonCount;
} else if (activeFx[group] === fxNumber + fxButtonCount) {
// Already on secondary fx so resetting back to fxNumber
fxToApply[group] = fxNumber;
} else {
// First press of a different fx button
fxToApply[group] = fxNumber;
}
}

/* When we target both decks - No shift pressed - we want *
* to reset fx to same value for both */
if (targetGroups.length === 2 && noShift) {
const [deck1, deck2] = targetGroups;
const activeFxDeck1 = activeFx[deck1];
const activeFxDeck2 = activeFx[deck2];
const fxToApplyDeck1 = fxToApply[deck1];
const fxToApplyDeck2 = fxToApply[deck2];

// If any of deck has already fx enabled but different value to apply
if ((activeFxDeck1 === fxNumber || activeFxDeck2 === fxNumber) && fxToApplyDeck1 !== fxToApplyDeck2) {
// find lower value to reset both to the same one
const fxToApplyAll = Math.min(fxToApplyDeck1, fxToApplyDeck2);
fxToApply[deck1] = fxToApplyAll;
fxToApply[deck2] = fxToApplyAll;
}
}

engine.setValue(group, "group_[Channel1]_enable", TraktorS2MK3.fxButtonState[fxNumber]);
engine.setValue(group, "group_[Channel2]_enable", TraktorS2MK3.fxButtonState[fxNumber]);
TraktorS2MK3.outputHandler(TraktorS2MK3.fxButtonState[fxNumber], field.group, "fxButton" + fxNumber);
// Now apply the new fx value
for (const group of targetGroups) {
engine.setValue(`[QuickEffectRack1_${group}]`, "loaded_chain_preset", fxToApply[group] + 1);
}
};

TraktorS2MK3.fxOutputHandler = function() {
const fxButtonCount = 4;
const availableGroups = ["[Channel1]", "[Channel2]"];

const activeFx = {};
for (const group of availableGroups) {
activeFx[group] = engine.getValue(`[QuickEffectRack1_${group}]`, "loaded_chain_preset") - 1;
// We want to lit the proper fx button even when we have applied a higher fxNumber
if (activeFx[group] > fxButtonCount) { activeFx[group] = activeFx[group] - fxButtonCount; }
}

/* There is no way on the controller to indicate which deck the effect applies *
* to, but keeping both lit indicates that different effects are in use. */
for (let fxButton = 1; fxButton <= fxButtonCount; ++fxButton) {
let active = false;
for (const group of availableGroups) {
active = active || activeFx[group] === fxButton;
}
TraktorS2MK3.outputHandler(active, "[ChannelX]", "fxButton" + fxButton);
}
};

TraktorS2MK3.reverseHandler = function(field) {
Expand Down Expand Up @@ -836,6 +909,11 @@ TraktorS2MK3.registerOutputPackets = function() {
this.samplerCallbacks.push(engine.makeConnection("[Sampler" + i + "]", "play", this.samplesOutputHandler));
}

this.fxCallbacks = [];
for (const group of ["[Channel1]", "[Channel2]"]) {
this.fxCallbacks.push(engine.makeConnection(`[QuickEffectRack1_${group}]`, "loaded_chain_preset", this.fxOutputHandler));
}

TraktorS2MK3.lightDeck(false);
};

Expand Down Expand Up @@ -1015,6 +1093,8 @@ TraktorS2MK3.lightDeck = function(switchOff) {
TraktorS2MK3.controller.setOutput("[ChannelX]", "fxButton2", softLight, false);
TraktorS2MK3.controller.setOutput("[ChannelX]", "fxButton3", softLight, false);
TraktorS2MK3.controller.setOutput("[ChannelX]", "fxButton4", softLight, false);
// Set FX button LED state according to active quick effects on start-up
if (!switchOff) { TraktorS2MK3.fxOutputHandler(); }

TraktorS2MK3.controller.setOutput("[Channel1]", "reverse", softLight, false);
TraktorS2MK3.controller.setOutput("[Channel2]", "reverse", softLight, false);
Expand Down