Skip to content
Closed
Show file tree
Hide file tree
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
259 changes: 193 additions & 66 deletions res/controllers/Korg-KAOSS-DJ-scripts.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
// Korg KAOSS DJ controller mapping for Mixxx
// Seb Dooris, Fayaaz Ahmed, Lee Arromba
// Seb Dooris, Fayaaz Ahmed, Lee Arromba, Raphael Quast

var KAOSSDJ = {};
var ON = 0x7F,
OFF = 0x00,
UP = 0x01,
DOWN = 0x7F;
var ledChannel = {
'btnsL': 0x97,
'btnsR': 0x98,
'knobsL': 0xB7,
'knobsR': 0xB8,
'master': 0xB6
};
var led = {
'cue': 0x1E,
'sync': 0x1D,
'play': 0x1B,
'headphones': 0x19,
'fx': 0x18, // warning: led is owned by controller
'stripL': 0x15,
'stripM': 0x16,
'stripR': 0x17,
'loopStripL': 0x0F,
'loopStripM': 0x10,
'loopStripR': 0x11,
"btnsL": 0x97,
"btnsR": 0x98,
"knobsL": 0xB7,
"knobsR": 0xB8,
"master": 0xB6
};

// var led = {
// "cue": 0x1E,
// "sync": 0x1D,
// "play": 0x1B,
// "headphones": 0x19,
// "fx": 0x18, // warning: led is owned by controller
// "stripL": 0x15,
// "stripM": 0x16,
// "stripR": 0x17,
// "loopStripL": 0x0F,
// "loopStripM": 0x10,
// "loopStripR": 0x11,
// };

// shift button state variables
var shiftLeftPressed = false;
var shiftRightPressed = false;

// initialise decks
KAOSSDJ.deck = function(deckNumber) {
this.deckNumber = deckNumber;
Expand All @@ -42,13 +47,13 @@ for (var i = 0; i < 4; i++) { // TODO: currently only 2 decks supported. is 4 po

// ==== lifecycle ====

KAOSSDJ.init = function(id, debugging) {
KAOSSDJ.init = function(_id, _debugging) {
// turn on main led channels
var ledChannels = [
ledChannel['knobsL'],
ledChannel['knobsR'],
ledChannel['master']
]
ledChannel.knobsL,
ledChannel.knobsR,
ledChannel.master
];
for (var led = 0x00; led <= 0xFF; led++) {
for (var i = 0; i < ledChannels.length; i++) {
midi.sendShortMsg(ledChannels[i], led, ON);
Expand All @@ -61,10 +66,10 @@ KAOSSDJ.init = function(id, debugging) {
midi.sendSysexMsg(ControllerStatusSysex, ControllerStatusSysex.length);
};

KAOSSDJ.shutdown = function(id, debugging) {
KAOSSDJ.shutdown = function(_id, _debugging) {
// turn off all LEDs
for (var led = 0x00; led <= 0xFF; led++) {
for (key in ledChannel) {
for (var key in ledChannel) {
midi.sendShortMsg(ledChannel[key], led, OFF);
}
}
Expand All @@ -73,7 +78,7 @@ KAOSSDJ.shutdown = function(id, debugging) {
// ==== helper ====

KAOSSDJ.getDeckIndexFromChannel = function(channel) {
return channel - 7
return channel - 7;
};

KAOSSDJ.getDeckByChannel = function(channel) {
Expand All @@ -88,15 +93,15 @@ KAOSSDJ.updateDeckByChannel = function(channel, key, value) {

// ==== mapped functions ====

KAOSSDJ.wheelTouch = function(channel, control, value, status, group) {
KAOSSDJ.wheelTouch = function(channel, _control, value, _status, _group) {
var alpha = 1.0 / 8;
var beta = alpha / 32;
var deck = KAOSSDJ.getDeckByChannel(channel);
var deckNumber = deck.deckNumber;
var deck_playing = engine.getValue('[Channel' + deckNumber + ']', 'play_indicator');
var deckPlaying = engine.getValue("[Channel" + deckNumber + "]", "play_indicator");

// If in scratch mode or not playing enable vinyl-like control
if (deck.jogWheelsInScratchMode || !deck_playing ) {
if (deck.jogWheelsInScratchMode || !deckPlaying) {
if (value === ON) {
// Enable scratching on touch
engine.scratchEnable(deckNumber, 128, 33 + 1 / 3, alpha, beta);
Expand All @@ -107,7 +112,7 @@ KAOSSDJ.wheelTouch = function(channel, control, value, status, group) {
}
};

KAOSSDJ.wheelTurn = function(channel, control, value, status, group) {
KAOSSDJ.wheelTurn = function(channel, _control, value, _status, _group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
var deckNumber = deck.deckNumber;
var newValue = 0;
Expand All @@ -119,11 +124,11 @@ KAOSSDJ.wheelTurn = function(channel, control, value, status, group) {
if (engine.isScratching(deckNumber)) {
engine.scratchTick(deckNumber, newValue);
} else {
engine.setValue('[Channel' + deckNumber + ']', 'jog', newValue); // Pitch bend
engine.setValue("[Channel" + deckNumber + "]", "jog", newValue); // Pitch bend
}
};

KAOSSDJ.wheelTurnShift = function(channel, control, value, status, group) {
KAOSSDJ.wheelTurnShift = function(channel, _control, value, _status, _group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
if (deck.jogWheelsInScratchMode) {
// Fast scratch
Expand All @@ -137,68 +142,190 @@ KAOSSDJ.wheelTurnShift = function(channel, control, value, status, group) {
engine.scratchTick(deck.deckNumber, newValue);
} else {
// Move beatgrid
if(value === UP){
engine.setValue(deck.group, 'beats_translate_later', true);
} else if (value === DOWN){
engine.setValue(deck.group, 'beats_translate_earlier', true);
if (value === UP) {
engine.setValue(deck.group, "beats_translate_later", true);
} else if (value === DOWN) {
engine.setValue(deck.group, "beats_translate_earlier", true);
}
}
};

KAOSSDJ.scratchMode = function(channel, control, value, status, group) {
KAOSSDJ.scratchMode = function(channel, _control, value, _status, _group) {
if (value === ON) {
// Turn scratch mode on jogwheel (LED is red)
KAOSSDJ.updateDeckByChannel(channel, 'jogWheelsInScratchMode', true);
KAOSSDJ.updateDeckByChannel(channel, "jogWheelsInScratchMode", true);
} else if (value === OFF) {
// Turn scratch mode on jogwheel (LED is off)
KAOSSDJ.updateDeckByChannel(channel, 'jogWheelsInScratchMode', false);
KAOSSDJ.updateDeckByChannel(channel, "jogWheelsInScratchMode", false);
}
};

KAOSSDJ.browseKnob = function(channel, control, value, status, group) {
var nval = (value > 0x40 ? value - 0x80 : value);
engine.setValue(group, "SelectTrackKnob", nval);
};

KAOSSDJ.leftFxSwitch = function(channel, control, value, status, group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
if(value === ON) {
KAOSSDJ.updateDeckByChannel(channel, 'fx', true);
KAOSSDJ.leftFxSwitch = function(channel, _control, value, _status, _group) {
if (value === ON) {
KAOSSDJ.updateDeckByChannel(channel, "fx", true);
} else {
KAOSSDJ.updateDeckByChannel(channel, 'fx', false);
KAOSSDJ.updateDeckByChannel(channel, "fx", false);
}
};

KAOSSDJ.rightFxSwitch = function(channel, control, value, status, group) {
if(value === ON) {
KAOSSDJ.updateDeckByChannel(channel, 'fx', true);
KAOSSDJ.rightFxSwitch = function(channel, _control, value, _status, _group) {
if (value === ON) {
KAOSSDJ.updateDeckByChannel(channel, "fx", true);
} else {
KAOSSDJ.updateDeckByChannel(channel, 'fx', false);
KAOSSDJ.updateDeckByChannel(channel, "fx", false);
}
};

KAOSSDJ.controllerFxTouchMoveVertical = function(channel, control, value, status, group) {
KAOSSDJ.controllerFxTouchMoveVertical = function(_channel, _control, value, _status, _group) {
var decks = KAOSSDJ.decks;
for(key in decks) {
for (var key in decks) {
var deck = decks[key];
if(deck.fx) {
engine.setValue('[EffectRack1_EffectUnit'+deck.deckNumber +']', 'mix', value / 127);
if (deck.fx) {
engine.setValue("[EffectRack1_EffectUnit"+deck.deckNumber +"]", "mix", value / 127);
}
}
};

KAOSSDJ.controllerFxTouchMoveHorizontal = function(channel, control, value, status, group) {
KAOSSDJ.controllerFxTouchMoveHorizontal = function(_channel, _control, value, _status, _group) {
var decks = KAOSSDJ.decks;
for(key in decks) {
for (var key in decks) {
var deck = decks[key];
if(deck.fx) {
engine.setValue('[EffectRack1_EffectUnit'+deck.deckNumber +']', 'super1', value / 127);
if (deck.fx) {
engine.setValue("[EffectRack1_EffectUnit"+deck.deckNumber +"]", "super1", value / 127);
}
}
};

KAOSSDJ.controllerFxTouchUp = function(channel, _control, _value, _status, _group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
engine.setValue("[EffectRack1_EffectUnit"+deck.deckNumber +"]", "mix", 0);
engine.setValue("[EffectRack1_EffectUnit"+deck.deckNumber +"]", "super1", 0);
};

// use loop-button to deactivate an active loop or initialize a beatloop at the current playback position
KAOSSDJ.toggleLoop = function(channel, _control, value, _status, _group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
var loopEnabled = engine.getValue(deck.group, "loop_enabled");

if (value === ON) {
if (loopEnabled) {
engine.setValue(deck.group, "reloop_exit", true);
engine.setValue(deck.group, "beatloop_activate", false);
} else {
engine.setValue(deck.group, "beatloop_activate", true);
}
}
};

KAOSSDJ.controllerFxTouchUp = function(channel, control, value, status, group) {

// <LOAD A/B> : load track
// <SHIFT> + <LOAD A/B> : open/close folder in file-browser
KAOSSDJ.loadCallback = function(channel, _control, value, _status, _group) {
var deck = KAOSSDJ.getDeckByChannel(channel);
engine.setValue('[EffectRack1_EffectUnit'+deck.deckNumber +']', 'mix', 0);
engine.setValue('[EffectRack1_EffectUnit'+deck.deckNumber +']', 'super1', 0);
};
if (value === ON) {
if ((shiftLeftPressed) || (shiftRightPressed)) {
if (deck.deckNumber === 1) {
engine.setValue("[Library]", "MoveLeft", true);
} else {
engine.setValue("[Library]", "MoveRight", true);
}
} else {
engine.setValue(deck.group, "LoadSelectedTrack", true);
}
}
};

KAOSSDJ.shiftLeftCallback = function(_channel, _control, value, _status, _group) {
if (value === ON) {
// if (shiftRightPressed == true) {
// TODO add functionality if <RIGHT SHIFT> is active while <LEFT SHIFT> is pressed?
// }
shiftLeftPressed = true;
} else { shiftLeftPressed = false; }
};

KAOSSDJ.shiftRightCallback = function(_channel, _control, value, _status, _group) {
if (value === ON) {
// if (shiftLeftPressed == true) {
// TODO add functionality if <LEFT SHIFT> is active while <RIGHT SHIFT> is pressed?
// }
shiftRightPressed = true;
} else { shiftRightPressed = false; }
};

KAOSSDJ.changeFocus = function(_channel, _control, value, _status, _group) {
if (value === ON) {
// toggle focus between Playlist and File-Browser
engine.setValue("[Library]", "MoveFocusForward", true);
}
};

// <browseKnob> : browse library up & down
// <SHIFT> + <browseKnob> : toggle focus between Playlist and File-Browser
KAOSSDJ.browseKnob = function(_channel, _control, value, _status, _group) {
if (value > 0x40) {
if ((shiftLeftPressed) || (shiftRightPressed)) {
engine.setValue("[Library]", "MoveFocusForward", true);
} else {
engine.setValue("[Library]", "MoveUp", true);
}
} else {
if ((shiftLeftPressed) || (shiftRightPressed)) {
engine.setValue("[Library]", "MoveFocusBackward", true);
} else {
engine.setValue("[Library]", "MoveDown", true);
}
}
};

// <TAP> : open folder
// <TAP> + <TAP> : double-tap to close folder
// <SHIFT LEFT> + <TAP> : tap bpm of LEFT track
// <SHIFT RIGHT> + <TAP> : tap bpm of RIGHT track
var doubleTapTime;
KAOSSDJ.tapButtonCallback = function(_channel, _control, value, _status, _group) {
var now = new Date().getTime();
var timesince = now - doubleTapTime;

/* shift tab to move focus view */
if ((value === ON) && ((shiftLeftPressed))) {
// engine.setValue("[Library]", "MoveFocusForward", true);
engine.setValue("[Channel1]", "bpm_tap", true);
return;
}
if ((value === ON) && ((shiftRightPressed))) {
// engine.setValue("[Library]", "MoveFocusForward", true);
engine.setValue("[Channel2]", "bpm_tap", true);
return;
}

/* tap to open folder, double-tap to close folder (twice to undo first tap)*/
if (value === ON) {
if ((timesince < 600) && (timesince > 0)) {
engine.setValue("[Library]", "MoveLeft", true);
engine.setValue("[Library]", "MoveLeft", true);
} else {
engine.setValue("[Library]", "MoveRight", true);
}

doubleTapTime = new Date().getTime();
}
};

// <SHIFT> + <TOUCHPAD X> : control super knob of QuickEffectRack for deck 1
KAOSSDJ.controllerFxTouchMoveVerticalShift = function(_channel, _control, value, _status, _group) {
var deck = KAOSSDJ.decks[0];
if (deck.fx) {
var val = script.absoluteLin(value, 0, 1, 0, 127);
engine.setValue("[QuickEffectRack1_" + deck.group + "]", "super1", val);
}
};

// <SHIFT> + <TOUCHPAD Y> : control super knob of QuickEffectRack for deck 2
KAOSSDJ.controllerFxTouchMoveHorizontalShift = function(_channel, _control, value, _status, _group) {
var deck = KAOSSDJ.decks[1];
if (deck.fx) {
var val = script.absoluteLin(value, 0, 1, 0, 127);
engine.setValue("[QuickEffectRack1_" + deck.group + "]", "super1", val);
}
};
Loading