diff options
author | Antoine C <mixxx@acolombier.dev> | 2023-03-09 19:49:42 +0000 |
---|---|---|
committer | Antoine C <mixxx@acolombier.dev> | 2023-06-04 17:25:04 +0100 |
commit | b6cc0f73a88e6c92f542a1bb9c7d16127f2baa4b (patch) | |
tree | a86d0c1d6639045ee361874a2fe9e346f2d69136 | |
parent | 9df5a734363915659044f248ba6d35d1f8f03d0d (diff) |
Kontrol S4 Mk3: additionnal effect mappings and init fix
-rw-r--r-- | res/controllers/Traktor-Kontrol-S4-MK3.js | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/res/controllers/Traktor-Kontrol-S4-MK3.js b/res/controllers/Traktor-Kontrol-S4-MK3.js index 3721a2cbeb..15b8983a8e 100644 --- a/res/controllers/Traktor-Kontrol-S4-MK3.js +++ b/res/controllers/Traktor-Kontrol-S4-MK3.js @@ -203,7 +203,7 @@ class HIDInputPacket { this.fields = []; } - registerCallback(callback, byteOffset, bitOffset, bitLength, signed) { + registerCallback(callback, byteOffset, bitOffset, bitLength, defaultOldData) { if (typeof callback !== "function") { throw Error("callback must be a function"); } @@ -226,16 +226,12 @@ class HIDInputPacket { throw Error("bitLength must be an integer between 1 and 32"); } - if (signed === undefined) { - signed = false; - } - const field = { callback: callback, byteOffset: byteOffset, bitOffset: bitOffset, bitLength: bitLength, - oldData: 0 + oldData: defaultOldData }; this.fields.push(field); @@ -248,9 +244,10 @@ class HIDInputPacket { }; } - handleInput(byteArray) { + handleInput(byteArray, bufferHasNoReportID) { + const offset = bufferHasNoReportID ? -1 : 0; const view = new DataView(byteArray); - if (view.getUint8(0) !== this.reportId) { + if (!bufferHasNoReportID && view.getUint8(0) !== this.reportId) { return; } @@ -262,13 +259,13 @@ class HIDInputPacket { // The HID standard allows signed integers as well, but I am not aware // of any HID DJ controllers which use signed integers. if (numBytes === 1) { - data = view.getUint8(field.byteOffset); + data = view.getUint8(field.byteOffset + offset); } else if (numBytes === 2) { - data = view.getUint16(field.byteOffset, true); + data = view.getUint16(field.byteOffset + offset, true); } else if (numBytes === 3) { - data = view.getUint32(field.byteOffset, true) >>> 8; + data = view.getUint32(field.byteOffset + offset, true) >>> 8; } else if (numBytes === 4) { - data = view.getUint32(field.byteOffset, true); + data = view.getUint32(field.byteOffset + offset, true); } else { throw Error("field bitLength must be between 1 and 32"); } @@ -332,7 +329,7 @@ class Component { if (typeof callback === "function") { this.input = callback; } - this.inConnection = this.inPacket.registerCallback(this.input.bind(this), this.inByte, this.inBit, this.inBitLength); + this.inConnection = this.inPacket.registerCallback(this.input.bind(this), this.inByte, this.inBit, this.inBitLength, this.oldDataDefault); } inDisconnect() { if (this.inConnection !== undefined) { @@ -510,6 +507,8 @@ class Deck extends ComponentContainer { class Button extends Component { constructor(options) { + options.oldDataDefault = 0; + super(options); if (this.input === undefined) { @@ -930,6 +929,17 @@ class Pot extends Component { constructor(options) { super(options); this.hardwarePosition = null; + this.shiftedHardwarePosition = null; + } + setGroupKey(group, key) { + this.inKey = key; + if (key === this.outKey && group === this.group) { + return; + } + this.outDisconnect(); + this.group = group; + this.outKey = key; + this.outConnect(); } input(value) { const receivingFirstValue = this.hardwarePosition === null; @@ -944,6 +954,7 @@ class Pot extends Component { engine.softTakeover(this.group, this.inKey, true); } engine.softTakeoverIgnoreNextValue(this.group, this.inKey); + super.outDisconnect(); } } @@ -1472,6 +1483,12 @@ class S4Mk3EffectUnit extends ComponentContainer { this.buttons[index].outKey = this.buttons[index].inKey; this.knobs[index].group = this.buttons[index].group; this.knobs[index].inKey = this.focusedEffect === null ? "meta" : "parameter" + (index + 1); + this.knobs[index].shift = this.focusedEffect === null ? undefined : function() { + this.setGroupKey(unfocusGroup, "meta"); + }; + this.knobs[index].unshift = this.focusedEffect === null ? undefined : function() { + this.setGroupKey(effectGroup, "parameter" + (index + 1)); + }; this.buttons[index].outConnect(); } } @@ -1634,11 +1651,7 @@ class S4Mk3Deck extends Deck { wheelOutput[1] = wheelLEDmodes.ringFlash; wheelOutput[4] = this.color + Button.prototype.brightnessOn; - // hack around https://github.com/mixxxdj/mixxx/issues/10828 - // This isn't directly needed, but because we used this hack for - // the track progression, we must make sure we are in sync with it's - // delayed updated - engine.beginTimer(decks[0] * 35, () => { controller.send(wheelOutput, null, 50, true); }, true); + controller.send(wheelOutput, null, 50, true); this.indicator(true); } else if (this.previousWheelMode !== null) { @@ -1722,13 +1735,7 @@ class S4Mk3Deck extends Deck { wheelOutput[1] = wheelLEDmodes.ringFlash; wheelOutput[4] = this.color + Button.prototype.brightnessOn; - // hack around https://github.com/mixxxdj/mixxx/issues/10828 - // This isn't directly needed, but because we used this hack for - // the track progression, we must make sure we are in sync with it's - // delayed updated - engine.beginTimer(decks[0] * 35, () => { - controller.send(wheelOutput, null, 50, true); - }, true); + controller.send(wheelOutput, null, 50, true); this.indicator(true); } else if (this.previousWheelMode !== null) { @@ -2458,8 +2465,7 @@ class S4Mk3Deck extends Deck { wheelOutput[3] = LEDposition >> 8; wheelOutput[4] = this.color + Button.prototype.brightnessOn; - // FIXME glitch, likely related to https://github.com/mixxxdj/mixxx/issues/10828 - engine.beginTimer(decks[0] * 35, () => { controller.send(wheelOutput, null, 50, true); }, true); + controller.send(wheelOutput, null, 50, true); } }); @@ -2574,8 +2580,7 @@ class S4Mk3MixerColumn extends ComponentContainer { // FIXME: Why is output not working for these? this.saveGain = new PushButton({ - key: "update_replaygain_from_pregain", - group: group, + key: "update_replaygain_from_pregain" }); this.crossfaderSwitch = new Component({ @@ -2995,12 +3000,12 @@ class S4MK3 { motorData[9] = velocityRight >> 8; controller.send(motorData, null, 49, true); } - incomingData(data) { - const reportId = data[0]; + incomingData(data, _, forceReportId) { + const reportId = forceReportId || data[0]; if (reportId === 1) { - this.inPackets[1].handleInput(data.buffer); + this.inPackets[1].handleInput(data.buffer, !!forceReportId); } else if (reportId === 2) { - this.inPackets[2].handleInput(data.buffer); + this.inPackets[2].handleInput(data.buffer, !!forceReportId); // The master volume, booth volume, headphone mix, and headphone volume knobs // control the controller's audio interface in hardware, so they are not mapped. } else if (reportId === 3) { @@ -3020,6 +3025,8 @@ class S4MK3 { this.leftDeck.wheelRelative.input(view.getUint16(12, true)); this.rightDeck.wheelRelative.input(view.getUint16(40, true)); + } else { + console.warn("Unsupported HID repord with ID "+ reportId + ". Contains: "+data); } } init() { @@ -3027,17 +3034,17 @@ class S4MK3 { const wheelLEDinitPacket = Array(26).fill(0); wheelLEDinitPacket[1] = 1; wheelLEDinitPacket[2] = 3; - controller.send(wheelLEDinitPacket, null, 48); + controller.send(wheelLEDinitPacket, null, 48, true); wheelLEDinitPacket[0] = 1; - // hack around https://github.com/mixxxdj/mixxx/issues/10828 - engine.beginTimer(35, () => { controller.send(wheelLEDinitPacket, null, 48); }, true); + controller.send(wheelLEDinitPacket, null, 48); // Init wheel timer data wheelTimer = null; wheelTimerDelta = 0; // get state of knobs and faders - this.incomingData(new Uint8Array(controller.getInputReport(2))); + this.incomingData(new Uint8Array(controller.getInputReport(1)), null, 1); + this.incomingData(new Uint8Array(controller.getInputReport(2)), null, 2); } shutdown() { // button LEDs @@ -3048,12 +3055,10 @@ class S4MK3 { const wheelOutput = Array(40).fill(0); // left wheel LEDs - // FIXME this data gets ignored due to https://github.com/mixxxdj/mixxx/issues/10828 - // Unfortunately, because this is the teardown function, we cannot use a timer to delay the send - controller.send(wheelOutput, null, 50); + controller.send(wheelOutput, null, 50, true); // right wheel LEDs wheelOutput[0] = 1; - controller.send(wheelOutput, null, 50); + controller.send(wheelOutput, null, 50, true); } } |