Skip to content

Commit

Permalink
Controller: ION Discover DJ Pro
Browse files Browse the repository at this point in the history
An initial attempt to have support for the ION Discover DJ Pro. This file
was taken from https://mixxx.org/forums/viewtopic.php?f=7&t=3343 and modified
to make it work with a recent version of Mixxx.

Signed-off-by: meltedpianoman <meltedpianoman@gmail.com>
  • Loading branch information
ivosieben committed Jun 20, 2020
1 parent ff2abf0 commit 41ffad0
Show file tree
Hide file tree
Showing 2 changed files with 1,059 additions and 0 deletions.
262 changes: 262 additions & 0 deletions res/controllers/Ion-Discover-DJ-Pro-scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
// Ion Discover DJ pro Mapping Script Functions
// Joachim
var IonDiscoverDjPro = function() {};

IonDiscoverDjPro.init = function(id) { // called when the MIDI device is opened & set up
IonDiscoverDjPro.id = id; // Store the ID of this device for later use

IonDiscoverDjPro.directoryMode = false;

IonDiscoverDjPro.scratchMode = [false, false];
IonDiscoverDjPro.scratchTimer = [-1, -1];

IonDiscoverDjPro.manualLooping = [false, false];

IonDiscoverDjPro.leds = [
// Common
{ },
// Deck 1
{"rate": 0x70, "scratchMode": 0x48, "keylock": 0x51, "manualLoop": 0x61, "loopIn": 0x53, "loopOut": 0x54, "reLoop": 0x55},
// Deck 2
{"rate": 0x71, "scratchMode": 0x50, "keylock": 0x52, "manualLoop": 0x62, "loopIn": 0x56, "loopOut": 0x57, "reLoop": 0x58}
];
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[0]["file"], true);
};

IonDiscoverDjPro.shutdown = function() { // called when the MIDI device is closed
var lowestLED = 0x30;
var highestLED = 0x73;
for (var i=lowestLED; i<=highestLED; i++) {
IonDiscoverDjPro.setLED(i, false); // Turn off all the lights
}
};

IonDiscoverDjPro.groupToDeck = function(group) {
var matches = group.match(/^\[Channel(\d+)\]$/);
if (matches === null) {
return -1;
} else {
return matches[1];
}
};

IonDiscoverDjPro.setLED = function(value, status) {
if (status) {
status = 0x64;
} else {
status = 0x00;
}
midi.sendShortMsg(0x90, value, status);
};

IonDiscoverDjPro.samplesPerBeat = function(group) {
// FIXME: Get correct samplerate and channels for current deck
var sampleRate = 44100;
var channels = 2;
var bpm = engine.getValue(group, "file_bpm");
return channels * sampleRate * 60 / bpm;
};

IonDiscoverDjPro.selectKnob = function(channel, control, value, status, group) {
if (value > 63) {
value = value - 128;
}
if (IonDiscoverDjPro.directoryMode) {
var i;
if (value > 0) {
for (i = 0; i < value; i++) {
engine.setValue(group, "SelectNextPlaylist", 1);
}
} else {
for (i = 0; i < -value; i++) {
engine.setValue(group, "SelectPrevPlaylist", 1);
}
}
} else {
engine.setValue(group, "SelectTrackKnob", value);
}
};

IonDiscoverDjPro.loopIn = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
if (value) {
if (IonDiscoverDjPro.manualLooping[deck-1]) {
// Cut loop to Half
var start = engine.getValue(group, "loop_start_position");
var end = engine.getValue(group, "loop_end_position");
if ((start !== -1) && (end !== -1)) {
var len = (end - start) / 2;
engine.setValue(group, "loop_end_position", start + len);
}
} else {
if (engine.getValue(group, "loop_enabled")) {
engine.setValue(group, "reloop_exit", 1);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["reLoop"], false);
}
engine.setValue(group, "loop_in", 1);
engine.setValue(group, "loop_end_position", -1);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopIn"], true);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopOut"], false);
}
}
};

IonDiscoverDjPro.loopOut = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
if (value) {
var start = engine.getValue(group, "loop_start_position");
var end = engine.getValue(group, "loop_end_position");
if (IonDiscoverDjPro.manualLooping[deck-1]) {
// Set loop to current Bar (very approximative and would need to get fixed !!!)
var bar = IonDiscoverDjPro.samplesPerBeat(group);
engine.setValue(group, "loop_in", 1);
engine.setValue(group, "loop_end_position", start + bar);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopIn"], true);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopOut"], true);
} else {
if (start !== -1) {
if (end !== -1) {
// Loop In and Out set -> call Reloop/Exit
engine.setValue(group, "reloop_exit", 1);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopIn"], true);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopOut"], true);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["reLoop"], true);
} else {
// Loop In set -> call Loop Out
engine.setValue(group, "loop_out", 1);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["loopOut"], true);
}
}
}
}
};

IonDiscoverDjPro.reLoop = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
if (value) {
var start = engine.getValue(group, "loop_start_position");
var end = engine.getValue(group, "loop_end_position");

if (IonDiscoverDjPro.manualLooping[deck-1]) {
// Multiply Loop by Two
if ((start !== -1) && (end !== -1)) {
var len = (end - start) * 2;
engine.setValue(group, "loop_end_position", start + len);
}
} else {
if (engine.getValue(group, "loop_enabled")) {
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["reLoop"], false);
} else {
if ((start !== -1) && (end !== -1)) {
// Loop is set ! Light the led
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["reLoop"], true);
}
}
engine.setValue(group, "reloop_exit", 1);
}
}
};

IonDiscoverDjPro.playFromCue = function(channel, control, value, status, group) {
if (value) {
if (engine.getValue(group, "play")) {
engine.setValue(group, "play", 0);
engine.setValue(group, "cue_gotoandstop", 1);
} else {
engine.setValue(group, "cue_preview", 1);
}
} else {
engine.setValue(group, "cue_preview", 0);
}
};

IonDiscoverDjPro.jogWheel = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
var adjustedJog = parseFloat(value);
var posNeg = 1;
if (adjustedJog > 63) { // Counter-clockwise
posNeg = -1;
adjustedJog = value - 128;
}

if (IonDiscoverDjPro.scratchMode[deck-1]) {
if (IonDiscoverDjPro.scratchTimer[deck-1] === -1) {
engine.scratchEnable(deck, 128, 33+1/3, 1.0/8, (1.0/8)/32);
} else {
engine.stopTimer(IonDiscoverDjPro.scratchTimer[deck-1]);
}
engine.scratchTick(deck, adjustedJog);
IonDiscoverDjPro.scratchTimer[deck-1] = engine.beginTimer(20, "IonDiscoverDjPro.jogWheelStopScratch(" + deck + ")", true);
} else {
var gammaInputRange = 23; // Max jog speed
var maxOutFraction = 0.5; // Where on the curve it should peak; 0.5 is half-way
var sensitivity = 0.5; // Adjustment gamma
var gammaOutputRange = 3; // Max rate change
if (engine.getValue(group, "play")) {
adjustedJog = posNeg * gammaOutputRange * Math.pow(Math.abs(adjustedJog) / (gammaInputRange * maxOutFraction), sensitivity);
} else {
adjustedJog = gammaOutputRange * adjustedJog / (gammaInputRange * maxOutFraction);
}
engine.setValue(group, "jog", adjustedJog);
}
};

IonDiscoverDjPro.jogWheelStopScratch = function(deck) {
IonDiscoverDjPro.scratchTimer[deck-1] = -1;
engine.scratchDisable(deck);
};

IonDiscoverDjPro.WheelTouch = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
if (IonDiscoverDjPro.scratchMode[deck-1]) {
if (value) {
engine.scratchEnable(deck, 512, 33+1/3, 0.2, (0.2)/32);
IonDiscoverDjPro.scratching[deck-1] = true;
} else {
engine.scratchDisable(deck);
if (IonDiscoverDjPro.KeyIsLocked[deck-1]) {
engine.setValur(group, "keylock", 1);
}
IonDiscoverDjPro.scratching[deck-1] = false;
}
}
};

IonDiscoverDjPro.toggleDirectoryMode = function(channel, control, value) {
// Toggle setting and light
if (value) {
if (IonDiscoverDjPro.directoryMode) {
IonDiscoverDjPro.directoryMode = false;
} else {
IonDiscoverDjPro.directoryMode = true;
}
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[0]["directory"], IonDiscoverDjPro.directoryMode);
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[0]["file"], !IonDiscoverDjPro.directoryMode);
}
};

IonDiscoverDjPro.toggleScratchMode = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
// Toggle setting and light
if (value) {
if (IonDiscoverDjPro.scratchMode[deck-1]) {
IonDiscoverDjPro.scratchMode[deck-1] = false;
} else {
IonDiscoverDjPro.scratchMode[deck-1] = true;
}
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["scratchMode"], IonDiscoverDjPro.scratchMode[deck-1]);
}
};

IonDiscoverDjPro.toggleManualLooping = function(channel, control, value, status, group) {
var deck = IonDiscoverDjPro.groupToDeck(group);
// Toggle setting and light
if (value) {
if (IonDiscoverDjPro.manualLooping[deck-1]) {
IonDiscoverDjPro.manualLooping[deck-1] = false;
} else {
IonDiscoverDjPro.manualLooping[deck-1] = true;
}
IonDiscoverDjPro.setLED(IonDiscoverDjPro.leds[deck]["manualLoop"], IonDiscoverDjPro.manualLooping[deck-1]);
}
};
Loading

0 comments on commit 41ffad0

Please sign in to comment.