Skip to content

Instantly share code, notes, and snippets.

@stotes
Last active January 8, 2020 03:04
Show Gist options
  • Save stotes/e2a7f525a05afc0db00ef3f2c0294b0e to your computer and use it in GitHub Desktop.
Save stotes/e2a7f525a05afc0db00ef3f2c0294b0e to your computer and use it in GitHub Desktop.
KontrolX1MK2 HID Mapping
function KontrolX1MK2Controller() {
this.controller = new HIDController();
this.controller.softTakeoverAll();
this.mode = "default";
var selectTrackLastValue = 0;
// region CONTROLS
this.registerInputPackets = function() {
var packet = new HIDPacket("control", 0x1);
//Effects Knobs
for (var c = 1; c < 3; c++) {
var o = c * 10;
var cl = c == 1 ? o - 2 : o - 4;
packet.addControl("hid", c + "_filterHigh", cl - 2, "H");
packet.addControl("hid", c + "_filterMid", cl - 4, "H");
packet.addControl("hid", c + "_filterLow", cl - 6, "H");
}
//Effects Mix
//1-2
packet.addControl("hid", "1_mix", 2, "H");
packet.addControl("hid", "2_mix", 10, "H");
//Cue and Playback Buttons
for (var c = 1; c < 3; c++) {
packet.addControl("hid", c + "_play", 23 - c, "B", 0x1);
packet.addControl("hid", c + "_cue", 23 - c, "B", 0x2);
packet.addControl("hid", c + "_sync", 23 - c, "B", 0x4);
packet.addControl("hid", c + "_flux", 23 - c, "B", 0x8);
packet.addControl("hid", c + "_cue1", 23 - c, "B", 0x128);
packet.addControl("hid", c + "_cue2", 23 - c, "B", 0x64);
packet.addControl("hid", c + "_cue3", 23 - c, "B", 0x32);
packet.addControl("hid", c + "_cue4", 23 - c, "B", 0x16);
}
//TrackSelector
packet.addControl("hid", "1_loadTrack", 20, "B", 0x8);
packet.addControl("hid", "2_loadTrack", 20, "B", 0x2);
packet.addControl("hid", "selectButton", 23, "B", 0x10);
packet.addControl("hid", "selectTrack", 17, "H");
this.controller.registerInputPacket(packet);
};
this.registerCallbacks = function() {
HIDDebug("Registering HID callbacks");
var controller = this.controller;
controller.linkModifier("hid", "mode", "mode");
for (var channel = 1; channel < 3; channel++) {
// controller.setCallback("control", "hid", channel + "_headphone", function(button) {
// var ch = button.name.substr(0, 1);
// if (controller.modifiers.get("mode")) {
// engine.setParameter(
// "[Channel" + ch + "]",
// "cue_default",
// button.value === controller.buttonStates.pressed
// );
// } else {
// if (button.value === controller.buttonStates.pressed) {
// controller.toggle("[Channel" + ch + "]", "pfl");
// }
// }
// });
//PLAY
controller.setCallback("control", "hid", channel + "_play", function(button) {
var ch = button.name.substr(0, 1);
print("PLAY BUTTON Channel =" + ch);
if (button.value === controller.buttonStates.pressed) {
controller.toggle("[Channel" + ch + "]", "play");
}
});
//CUE
controller.setCallback("control", "hid", channel + "_cue", function(button) {
var ch = button.name.substr(0, 1);
print("CUE BUTTON Channel =" + ch);
if (button.value === controller.buttonStates.pressed) {
controller.toggle("[Channel" + ch + "]", "cue_default");
}
});
//SYNC
controller.setCallback("control", "hid", channel + "_sync", function(button) {
var ch = button.name.substr(0, 1);
print("SYNC Button Channel =" + ch);
if (button.value === controller.buttonStates.pressed) {
controller.toggle("[Channel" + ch + "]", "beatsync_phase");
}
});
//LOAD TRACK
controller.setCallback("control", "hid", channel + "_loadTrack", function(button) {
var ch = button.name.substr(0, 1);
print("Load Track Button Channel =" + ch);
if (button.value === controller.buttonStates.pressed) {
controller.toggle("[Channel" + ch + "]", "LoadSelectedTrack");
}
});
this.linkKnob("default", channel + "_mix", "[EffectRack1_EffectUnitN" + channel + "]", "mix");
this.linkKnob("default", channel + "_filterHigh", "[EffectRack1_EffectUnitN" + channel + "]", "parameter3");
this.linkKnob("default", channel + "_filterMid", "[EffectRack1_EffectUnitN" + channel + "]", "parameter2");
this.linkKnob("default", channel + "_filterLow", "[EffectRack1_EffectUnitN" + channel + "]", "parameter1");
controller.setCallback("control", "hid", channel + "_mix", this.knob);
controller.setCallback("control", "hid", channel + "_filterHigh", this.knob);
controller.setCallback("control", "hid", channel + "_filterMid", this.knob);
controller.setCallback("control", "hid", channel + "_filterLow", this.knob);
}
//SELECT TRACK
controller.setCallback("control", "hid", "selectTrack", function(knob) {
print("Select Track KNOB: " + knob.value);
print("Last Select Track Knob Value: " + controller.selectTrackLastValue);
engine.setValue(
"[Playlist]",
knob.value >= controller.selectTrackLastValue ? "SelectNextTrack" : "SelectPrevTrack",
1
);
controller.selectTrackLastValue = knob.value;
});
};
// endregion
// region LIGHTS
this.registerOutputPackets = function() {
var packet = new HIDPacket("lights", 0x80);
for (var c = 1; c < 3; c++) {
packet.addOutput("hid", c + "_play", 23 - c, "B");
packet.addOutput("hid", c + "_cue", 23 - c, "B");
packet.addOutput("hid", c + "_sync", 23 - c, "B");
// packet.addOutput("hid", c + "_button_fx_blue", 23 - c, "B");
}
packet.addOutput("hid", "mode", 19, "B");
this.controller.registerOutputPacket(packet);
};
this.sendLightsUpdate = function() {
this.controller.getLightsPacket().send();
};
this.brightness = 0x7f;
this.brightnessRange = 1.0 / 7;
// endregion
}
var KontrolX1MK2 = new KontrolX1MK2Controller();
KontrolX1MK2.init = function(id) {
KontrolX1MK2.id = id;
KontrolX1MK2.registerInputPackets();
KontrolX1MK2.registerOutputPackets();
KontrolX1MK2.registerCallbacks();
// for (var c = 1; c < 3; c++) {
// engine.makeConnection("[Channel" + c + "]", "VuMeter", KontrolX1MK2.refreshVolumeLights);
// KontrolX1MK2.controller.connectLight("[Channel" + c + "]", "pfl", function(value, packet, group, name) {
// var channel = group.substr(8, 1);
// packet.getField("hid", channel + "_headphone").value = value * 0x7f;
// });
// KontrolX1MK2.controller.connectLight("[QuickEffectRack1_[Channel" + c + "]_Effect1]", "enabled", function(
// value,
// packet,
// group,
// name
// ) {
// var channel = group.substr(26, 1);
// packet.getField("hid", channel + "_button_fx_red").value = value * 0x7f;
// packet.getField("hid", channel + "_button_fx_blue").value = value * 0x7f;
// });
// }
print("NI Traktor Kontrol X1MK2 " + KontrolX1MK2.id + " initialized!");
};
// region knobs
KontrolX1MK2.knobs = {};
KontrolX1MK2.linkKnob = function(mode, knob, group, name) {
if (!(mode in KontrolX1MK2.knobs)) KontrolX1MK2.knobs[mode] = {};
KontrolX1MK2.knobs[mode][knob] = {
mode: mode,
knob: knob,
group: group,
name: name
};
};
KontrolX1MK2.control = function(control, field) {
if (control.callback !== undefined) {
control.callback(control, field);
return;
}
engine.setParameter(control.group, control.name, field.value / 4096);
};
KontrolX1MK2.knob = function(field) {
var mode = KontrolX1MK2.knobs[KontrolX1MK2.mode];
if (mode === undefined) {
HIDDebug("Knob group not mapped in mode " + KontrolX1MK2.mode);
return;
}
var knob = mode[field.name];
if (knob === undefined) {
HIDDebug("Fader " + field.name + " not mapped in " + KontrolX1MK2.mode);
return;
}
return KontrolX1MK2.control(knob, field);
};
// endregion
KontrolX1MK2.shutdown = function() {
KontrolX1MK2.controller.getLightsPacket().clearControls();
print("NI Traktor Kontrol X1MK2 " + KontrolX1MK2.id + " shut down!");
};
KontrolX1MK2.incomingData = function(data, length) {
KontrolX1MK2.hidReadableDebug(data);
KontrolX1MK2.controller.parsePacket(data, length);
};
KontrolX1MK2.hidReadableDebug = function(data) {
var output = "Data: \n";
for (var property in data) {
output += "HID Byte Position: " + property + " Value: " + data[property] + "\n";
}
print(output);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment