diff --git a/res/controllers/Traktor-Kontrol-Z1-scripts.js b/res/controllers/Traktor-Kontrol-Z1-scripts.js index b5e32e58fd81..a83a7a34dfb0 100644 --- a/res/controllers/Traktor-Kontrol-Z1-scripts.js +++ b/res/controllers/Traktor-Kontrol-Z1-scripts.js @@ -5,6 +5,8 @@ // Author: djantti // +// eslint definitions +/* global controller, HIDController, HIDPacket */ class TraktorZ1Class { constructor() { this.controller = new HIDController(); @@ -16,11 +18,16 @@ class TraktorZ1Class { this.vuLeftConnection = {}; this.vuRightConnection = {}; this.vuMeterThresholds = {"vu-30": (1 / 7), "vu-15": (2 / 7), "vu-6": (3 / 7), "vu-3": (4 / 7), "vu0": (5 / 7), "vu3": (6 / 7), "vu6": (7 / 7)}; + + // Calibration data + this.rawCalibration = {}; + this.calibration = null; } init(_id) { this.id = _id; + this.calibrate(); this.registerInputPackets(); this.registerOutputPackets(); this.readCurrentPosition(); @@ -67,7 +74,7 @@ class TraktorZ1Class { this.registerInputScaler(InputReport0x01, "[Channel2]", "volume", 0x19, 0xFFFF, this.parameterHandler.bind(this)); // Crossfader - this.registerInputScaler(InputReport0x01, "[Master]", "crossfader", 0x1B, 0xFFFF, this.parameterHandler.bind(this)); + this.registerInputScaler(InputReport0x01, "[Master]", "crossfader", 0x1B, 0xFFFF, this.crossfaderHandler.bind(this)); this.controller.registerInputPacket(InputReport0x01); } @@ -116,6 +123,32 @@ class TraktorZ1Class { this.lightDeck(false); } + calibrate() { + this.rawCalibration.faders = new Uint8Array(0x20 * 3); + this.rawCalibration.faders.set(new Uint8Array(controller.getFeatureReport(0xD1)), 0x00); + this.rawCalibration.faders.set(new Uint8Array(controller.getFeatureReport(0xD2)), 0x20); + this.rawCalibration.faders.set(new Uint8Array(controller.getFeatureReport(0xD3)), 0x40); + this.calibration = this.parseRawCalibration(); + } + + parseRawCalibration() { + return { + crossfader: this.parseCrossfaderCalibration(0x3C), + }; + } + + parseCrossfaderCalibration(index) { + const data = this.rawCalibration.faders; + return { + min: this.parseUint16Le(data, index), + max: this.parseUint16Le(data, index+2), + }; + } + + parseUint16Le(data, index) { + return data[index] + (data[index+1]<<8); + } + readCurrentPosition() { // Sync on-screen controls with controller knob positions const report0x01 = new Uint8Array(controller.getInputReport(0x01)); @@ -209,6 +242,16 @@ class TraktorZ1Class { engine.setParameter(field.group, field.name, field.value / 4095); } + crossfaderHandler(field) { + // Crossfader value don't reach boundaries and need to use calibration values + // Also apply extra safe margins + const safeMargins = 5; + const min = this.calibration.crossfader.min; + const max = this.calibration.crossfader.max; + const value = script.absoluteLin(field.value, 0, 1, min + safeMargins, max - safeMargins); + engine.setParameter(field.group, field.name, value); + } + outputHandler(value, group, key) { let ledValue; if (value === 0 || value === false) {