Skip to content

Commit

Permalink
S4 Mk3: use scratch modes scratch2, scratchTick or scratch_position
Browse files Browse the repository at this point in the history
  • Loading branch information
ronso0 committed Dec 18, 2024
1 parent af4acaf commit 872328d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 26 deletions.
11 changes: 6 additions & 5 deletions res/controllers/Traktor Kontrol S4 MK3.hid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
<group label="TEST scratch modes">
<row orientation="vertical">
<option
variable="useEngineScratch"
type="boolean"
default="false"
label="Use 'engine.scratch..' functions">
<description>Use 'engine.scratchEnable()/disable()' and 'engine.scratchTick()' instead of engine.setValue(group, "scratch2..")</description>
variable="scratchMode"
type="enum"
label="Scratch mode">
<value label="scratch2">scratch2</value>
<value label="scratchTick">scratchTick</value>
<value label="wheelPos">wheelPos</value>
</option>
<option
variable="scratchSyncToWheelLED"
Expand Down
101 changes: 80 additions & 21 deletions res/controllers/Traktor-Kontrol-S4-MK3.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,20 @@ const BeatLoopRolls = [
// Default: 33 + 1/3
const BaseRevolutionsPerMinute = engine.getSetting("baseRevolutionsPerMinute") || 33 + 1/3;
const ScratchSyncToWheelLED = !!engine.getSetting("scratchSyncToWheelLED");
// For testing: switch between engine.scratch.. functions and engine.setValue(.., "scratch2..")
const UseEngineScratch = !!engine.getSetting("useEngineScratch");
// For testing: switch between
// * engine.scratch.. functions
// * engine.setValue(.., "scratch2..") and
// * new wheel_scratch_position controller

// The mode available, which the wheel can be used for.
const scratchModes = {
scratch2: 0,
scratchTick: 1,
wheelPos: 2,
wheelPosNew: 3,
};
const ScratchMode = scratchModes[engine.getSetting("scratchMode")] || scratchModes.scratch2;
// const UseEngineScratch = !!engine.getSetting("useEngineScratch");
// Parameters for engine.scratchEnable()
// alpha and beta are the recommended start values from
// https://github.com/mixxxdj/mixxx/wiki/midi%20scripting#scratching-and-jog-wheels
Expand Down Expand Up @@ -2432,17 +2444,19 @@ class S4Mk3Deck extends Deck {
this.wheelTouch = new Button({
touched: false,
deck: this,
wheelPos: 0,
speed: 0,
input: function(touched) {
this.touched = touched;
if (this.deck.wheelMode === wheelModes.vinyl || this.deck.wheelMode === wheelModes.motor) {
if (touched) {
this.toggleScratching(true);
} else { // release
if (UseEngineScratch) {
this.toggleScratching(false);
} else {
// if (ScratchMode === scratchModes.scratch2) {
this.stopScratchWhenOver();
}
// } else {
// this.toggleScratching(false);
// }
}
}
},
Expand All @@ -2451,18 +2465,36 @@ class S4Mk3Deck extends Deck {
return;
}

if (engine.getValue(this.group, "play") &&
engine.getValue(this.group, "scratch2") < 1.5 * baseRevolutionsPerSecond &&
engine.getValue(this.group, "scratch2") > 0) {
this.toggleScratching(false);
} else if (engine.getValue(this.group, "scratch2") === 0) {
this.toggleScratching(false);
} else {
engine.beginTimer(100, this.stopScratchWhenOver.bind(this), true);
// if (ScratchMode === scratchModes.scratchTick) {
// this.toggleScratching(false);
// }

switch (ScratchMode) {
case scratchModes.wheelPos:
if (Math.abs(this.speed) < 0.0000001) {
this.toggleScratching(false);
} else {
engine.beginTimer(100, this.stopScratchWhenOver.bind(this), true);
}
break;
case scratchModes.scratchTick:
case scratchModes.scratch2:
default:
if (engine.getValue(this.group, "play") &&
engine.getValue(this.group, "scratch2") < 1.5 * baseRevolutionsPerSecond &&
engine.getValue(this.group, "scratch2") > 0) {
this.toggleScratching(false);
} else if (engine.getValue(this.group, "scratch2") === 0) {
this.toggleScratching(false);
} else {
engine.beginTimer(100, this.stopScratchWhenOver.bind(this), true);
}
break;
}
},
toggleScratching: function(enable) {
if (UseEngineScratch) {
switch (ScratchMode) {
case scratchModes.scratchTick:
if (enable) {
engine.scratchEnable(this.deck.currentDeckNumber,
ScratchTicksPerRev,
Expand All @@ -2472,8 +2504,19 @@ class S4Mk3Deck extends Deck {
} else {
engine.scratchDisable(this.deck.currentDeckNumber);
}
} else {
break;
case scratchModes.wheelPos:
if (enable) {
engine.setValue(this.group, "scratch_position", this.wheelPos);
engine.setValue(this.group, "scratch_position_enable", 1);
} else {
engine.setValue(this.group, "scratch_position_enable", 0);
}
break;
case scratchModes.scratch2:
default:
engine.setValue(this.group, "scratch2_enable", enable);
break;
}
}
});
Expand All @@ -2493,7 +2536,8 @@ class S4Mk3Deck extends Deck {
this.oldValue = [value, timestamp, 0];
return;
}
let [oldValue, oldTimestamp, speed] = this.oldValue;
/* eslint prefer-const: "off" */
let [oldValue, oldTimestamp, speed, oldPos] = this.oldValue;

// Log value right-aligned
// const maxLength = wheelRelativeMax.toString().length;
Expand All @@ -2512,8 +2556,10 @@ class S4Mk3Deck extends Deck {
// It's not impossible a human made ~11 revs since the last call...
if (diff > wheelRelativeMax / 2) {
oldValue += wheelRelativeMax;
diff -= wheelRelativeMax;
} else if (diff < -wheelRelativeMax / 2) {
oldValue -= wheelRelativeMax;
diff += wheelRelativeMax;
}

const currentSpeed = (value - oldValue)/(timestamp - oldTimestamp);
Expand All @@ -2522,8 +2568,14 @@ class S4Mk3Deck extends Deck {
} else {
speed = currentSpeed;
}
this.oldValue = [value, timestamp, speed];
this.speed = wheelAbsoluteMax*speed*10*ScratchSpeedFactor;

this.speed = wheelAbsoluteMax * speed * 10 * ScratchSpeedFactor * 2.14;

const newPos = oldPos + diff * 55;
this.deck.wheelTouch.wheelPos = newPos;
this.deck.wheelTouch.speed = speed;

this.oldValue = [value, timestamp, speed, newPos];

const scratch2 = engine.getValue(this.group, "scratch2");
if (this.speed === 0 &&
Expand Down Expand Up @@ -2561,12 +2613,19 @@ class S4Mk3Deck extends Deck {
}
break;
case wheelModes.vinyl:
if (UseEngineScratch && engine.isScratching(this.deck.currentDeckNumber)) {
if (ScratchMode === scratchModes.scratchTick &&
engine.isScratching(this.deck.currentDeckNumber)) {
if (diff !== 0) {
engine.scratchTick(this.deck.currentDeckNumber, diff);
}
} else if (!UseEngineScratch && this.deck.wheelTouch.touched || scratch2 !== 0) {
} else if (ScratchMode === scratchModes.scratch2 &&
(this.deck.wheelTouch.touched || scratch2 !== 0)) {
engine.setValue(this.group, "scratch2", this.speed);
} else if (ScratchMode === scratchModes.wheelPos &&
// (this.deck.wheelTouch.touched || scratch2 !== 0)) {
(this.deck.wheelTouch.touched ||
engine.getValue(this.group, "scratch_position_enable") > 0)) {
engine.setValue(this.group, "scratch_position", newPos);
} else {
engine.setValue(this.group, "jog", this.speed);
}
Expand Down

0 comments on commit 872328d

Please sign in to comment.