diff --git a/res/controllers/Pioneer-DDJ-400-script.js b/res/controllers/Pioneer-DDJ-400-script.js index cb4d05b1000..ec42310bf48 100644 --- a/res/controllers/Pioneer-DDJ-400-script.js +++ b/res/controllers/Pioneer-DDJ-400-script.js @@ -1,7 +1,7 @@ // Pioneer-DDJ-400-script.js // **************************************************************************** // * Mixxx mapping script file for the Pioneer DDJ-400. -// * Author: Warker, nschloe +// * Author: Warker, nschloe, dj3730 // * Forum: https://mixxx.org/forums/viewtopic.php?f=7&t=12113 // * Wiki: https://www.mixxx.org/wiki/doku.php/pioneer_ddj-400 // @@ -16,19 +16,20 @@ // * Beat Sync // * Beat Loop Mode // * Sampler Mode +// * BeatFX (controls Effect Unit 1. LEFT selects EFFECT1, RIGHT selects EFFECT2, FX_SELECT selects EFFECT3. +// ON/OFF toggles selected effect slot. SHIFT+ON/OFF disables all three effect slots. +// * Hot Cue Mode // // Partially: -// * Beatjump mode (no lighting, shift mode) +// * Beatjump mode (no lighting, shift mode(adjust jump size)) // * PAD FX (only slots A-H, Q-P) -// * Effect Section (without Beat FX left + Right - no equivalent function found) // * Output (lights) +// * Loop Section: Loop in / Out, Call, Double, Half +// (loop adjust not working, '4 beat loop' doesnt work correctly - see comments in PioneerDDJ400.loopin4beatPressedLong) // // Testing: // * Keyboard Mode (check pitch value) // * Keyshift Mode (check pitch value) -// * Hot Cue Mode (including loops) -// * Loop Section: Loop in / Out + Adjust, Call, Double, Half -// * Effect Section (Beat FX left + Right - select the Effect Slot (not Effect BPM)) // // Not working/implemented: // * Channel & Crossfader Start @@ -93,7 +94,7 @@ PioneerDDJ400.shiftState = [0, 0]; PioneerDDJ400.vinylMode = true; PioneerDDJ400.alpha = 1.0/8; PioneerDDJ400.beta = PioneerDDJ400.alpha/32; -PioneerDDJ400.highspeedScale = 2; +PioneerDDJ400.highspeedScale = 150; // multiplier for fast seek through track using SHIFT+JOGWHEEL PioneerDDJ400.bendScale = 0.5; PioneerDDJ400.pointJumpSpace = 0.005; // amount in percent of the Song we can jump back to previous Cue or loop point @@ -153,7 +154,7 @@ PioneerDDJ400.init = function() { // reset vumeter PioneerDDJ400.toggleLight(LightsPioneerDDJ400.deck1.vuMeter, false); PioneerDDJ400.toggleLight(LightsPioneerDDJ400.deck2.vuMeter, false); - + // DJ3730: added // enable soft takeover for rate controls engine.softTakeover("[Channel1]", "rate", true); @@ -166,10 +167,38 @@ PioneerDDJ400.init = function() { PioneerDDJ400.samplerCallbacks.push(engine.makeConnection("[Sampler" + i + "]", "play", PioneerDDJ400.samplerPlayOutputCallbackFunction)); } + // DJ3730: added + // trigger "track loaded" animations when a track is loaded + for (i=1; i<=2; i++) { + engine.connectControl("[Channel"+i+"]","track_loaded", "PioneerDDJ400.trackLoadedLED"+i); + engine.trigger("[Channel"+i+"]","track_loaded"); + } + + // DJ3730: added + // eye candy : play the "track loaded" animation on both decks at startup + midi.sendShortMsg(0x9F,0x00,0x7F); + midi.sendShortMsg(0x9F,0x01,0x7F); + // poll the controller for current control positions on startup midi.sendSysexMsg([0xF0,0x00,0x40,0x05,0x00,0x00,0x02,0x06,0x00,0x03,0x01,0xf7], 12); }; +PioneerDDJ400.trackLoadedLED1 = function (loaded) { + PioneerDDJ400.trackLoadedLED(1, loaded); +} +PioneerDDJ400.trackLoadedLED2 = function (loaded) { + PioneerDDJ400.trackLoadedLED(2, loaded); +} + +PioneerDDJ400.trackLoadedLED = function (channel, loaded) { + if (loaded) { + var value = 0x7F; + } else { + var value = 0x00; + } + midi.sendShortMsg(0x9F,0x00+(channel-1),value); +} + PioneerDDJ400.toggleLight = function(midiIn, active) { "use strict"; midi.sendShortMsg(midiIn.status, midiIn.data1, active ? 0x7F : 0); @@ -451,7 +480,6 @@ PioneerDDJ400.samplerModeShiftPadPressed = function(_channel, _control, value, _ } else { // load selected track engine.setValue(group, "LoadSelectedTrack", 1); } - // TODO: while playing a sample blink playing PAD? }; @@ -481,6 +509,9 @@ PioneerDDJ400.loopin4beatPressed = function(channel, _control, value, _status, g }; PioneerDDJ400.loopin4beatPressedLong = function(_channel, _control, value, _status, group) { + // problematic - loop gets set to the playback position where the 'long press' was recognized + // and not to the point at which the button was initially pressed + // as a result, the loop is not set where one would expect "use strict"; var loopEnabled = engine.getValue(group, "loop_enabled"); if (!loopEnabled && value > 0) { @@ -538,43 +569,46 @@ PioneerDDJ400.beatFxLevelDepthRotate = function(_channel, _control, value) { }; PioneerDDJ400.beatFxSelectPressed = ignoreRelease(function() { + // focus Effect Slot 3 in Effect Unit 1, or clear focus if it is currently focused "use strict"; - if (PioneerDDJ400.selectedFxSlot == 3) { - PioneerDDJ400.selectedFxSlot = 0; - } else { - PioneerDDJ400.selectedFxSlot = 3; - } + if (PioneerDDJ400.selectedFxSlot == 3) { + PioneerDDJ400.selectedFxSlot = 0; + } else { + PioneerDDJ400.selectedFxSlot = 3; + } }); PioneerDDJ400.beatFxSelectShiftPressed = function(_channel, _control, value) { "use strict"; //engine.setValue(PioneerDDJ400.selectedFxGroup, "prev_effect", value); - }; PioneerDDJ400.beatFxLeftPressed = ignoreRelease(function() { + // focus Effect Slot 1 in Effect Unit 1, or clear focus if it is currently focused "use strict"; - if (PioneerDDJ400.selectedFxSlot == 1) { - PioneerDDJ400.selectedFxSlot = 0; - } else { - PioneerDDJ400.selectedFxSlot = 1; - } + if (PioneerDDJ400.selectedFxSlot == 1) { + PioneerDDJ400.selectedFxSlot = 0; + } else { + PioneerDDJ400.selectedFxSlot = 1; + } }); PioneerDDJ400.beatFxRightPressed = ignoreRelease(function() { + // focus Effect Slot 2 in Effect Unit 1, or clear focus if it is currently focused "use strict"; - if (PioneerDDJ400.selectedFxSlot == 2) { - PioneerDDJ400.selectedFxSlot = 0; - } else { - PioneerDDJ400.selectedFxSlot = 2; - } + if (PioneerDDJ400.selectedFxSlot == 2) { + PioneerDDJ400.selectedFxSlot = 0; + } else { + PioneerDDJ400.selectedFxSlot = 2; + } }); PioneerDDJ400.beatFxOnOffPressed = ignoreRelease(function() { + // toggle the currently focused effect slot in Effect Unit 1 (if any) "use strict"; - var selectedSlot = PioneerDDJ400.selectedFxSlot; + var selectedSlot = PioneerDDJ400.selectedFxSlot; if (selectedSlot <= 0 || selectedSlot > PioneerDDJ400.numFxSlots) { - return; + return; } var isEnabled = !engine.getValue(PioneerDDJ400.selectedFxGroup, "enabled"); engine.setValue(PioneerDDJ400.selectedFxGroup, "enabled", isEnabled); @@ -582,9 +616,10 @@ PioneerDDJ400.beatFxOnOffPressed = ignoreRelease(function() { }); PioneerDDJ400.beatFxOnOffShiftPressed = ignoreRelease(function() { + // turn off all three effect slots in Effect Unit 1 "use strict"; for (var i = 1; i <= PioneerDDJ400.numFxSlots; i += 1) { - engine.setValue("[EffectRack1_EffectUnit3_Effect" + i + "]", "enabled", 0); + engine.setValue("[EffectRack1_EffectUnit1_Effect" + i + "]", "enabled", 0); } PioneerDDJ400.toggleLight(LightsPioneerDDJ400.beatFx, false); }); @@ -644,7 +679,7 @@ PioneerDDJ400.vuMeterUpdate = function(value, group) { // DJ3730: blink pad when sample playback starts PioneerDDJ400.samplerPlayOutputCallbackFunction = function (value, group, control) { if (value === 1) { - var curPad = group.match(script.samplerRegEx)[1]; + var curPad = group.match(/^\[Sampler(\d+)\]$/)[1]; // for some reason, using script.samplerRegEx here results in an error under Linux startSamplerBlink((0x97 + (curPad > 8 ? 2 : 0)), (0x30 + ((curPad > 8 ? curPad-8 : curPad)-1)), group); } }; @@ -724,16 +759,16 @@ PioneerDDJ400.shutdown = function() { // housekeeping // turn off all Sampler LEDs for (i = 0; i <= 7; ++i) { - midi.sendShortMsg(0x97, 0x30 + i, 0x00); // Deck 1 pads - midi.sendShortMsg(0x98, 0x30 + i, 0x00); // Deck 1 pads with SHIFT - midi.sendShortMsg(0x99, 0x30 + i, 0x00); // Deck 2 pads - midi.sendShortMsg(0x9A, 0x30 + i, 0x00); // Deck 2 pads with SHIFT + midi.sendShortMsg(0x97, 0x30 + i, 0x00); // Deck 1 pads + midi.sendShortMsg(0x98, 0x30 + i, 0x00); // Deck 1 pads with SHIFT + midi.sendShortMsg(0x99, 0x30 + i, 0x00); // Deck 2 pads + midi.sendShortMsg(0x9A, 0x30 + i, 0x00); // Deck 2 pads with SHIFT } // turn off all Hotcue LEDs for (i = 0; i <= 7; ++i) { - midi.sendShortMsg(0x97, 0x00 + i, 0x00); // Deck 1 pads - midi.sendShortMsg(0x98, 0x00 + i, 0x00); // Deck 1 pads with SHIFT - midi.sendShortMsg(0x99, 0x00 + i, 0x00); // Deck 2 pads - midi.sendShortMsg(0x9A, 0x00 + i, 0x00); // Deck 2 pads with SHIFT + midi.sendShortMsg(0x97, 0x00 + i, 0x00); // Deck 1 pads + midi.sendShortMsg(0x98, 0x00 + i, 0x00); // Deck 1 pads with SHIFT + midi.sendShortMsg(0x99, 0x00 + i, 0x00); // Deck 2 pads + midi.sendShortMsg(0x9A, 0x00 + i, 0x00); // Deck 2 pads with SHIFT } }; diff --git a/res/controllers/Pioneer-DDJ-400.midi.xml b/res/controllers/Pioneer-DDJ-400.midi.xml index 1ee35c62dbe..6d4a9ac74ba 100644 --- a/res/controllers/Pioneer-DDJ-400.midi.xml +++ b/res/controllers/Pioneer-DDJ-400.midi.xml @@ -121,9 +121,9 @@ - PLAY/PAUSE +SHIFT (DECK1) - press - Play/Pause + PLAY/PAUSE +SHIFT (DECK1) - press - Reverse playback in Slip Mode while held (Censor) [Channel1] - play + reverseroll 0x90 0x47 @@ -141,9 +141,9 @@ - PLAY/PAUSE +SHIFT (DECK2) - press - Play/Pause + PLAY/PAUSE +SHIFT (DECK2) - press - Reverse playback in Slip Mode while held (Censor) [Channel2] - play + reverseroll 0x91 0x47 @@ -4167,7 +4167,7 @@ - + [Sampler1] track_loaded @@ -4233,7 +4233,7 @@ 0.5 - + [Sampler9] track_loaded @@ -4298,10 +4298,10 @@ 0x7F 0.5 - + - - + + [Sampler1] track_loaded @@ -4366,10 +4366,10 @@ 0x7F 0.5 - + - - + + [Sampler9] track_loaded