From 6705606f8e09b0456a796fe6d8ca5343eef06e95 Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 19 Apr 2021 01:41:22 +0200 Subject: [PATCH 01/52] Numark Mixtrack Pro FX: added initial mapping --- .../Numark Mixtrack Pro FX.midi.xml | 1552 +++++++++++++++++ .../Numark-Mixtrack-Pro-FX-scripts.js | 854 +++++++++ 2 files changed, 2406 insertions(+) create mode 100644 res/controllers/Numark Mixtrack Pro FX.midi.xml create mode 100644 res/controllers/Numark-Mixtrack-Pro-FX-scripts.js diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml new file mode 100644 index 00000000000..d981e96fbbd --- /dev/null +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -0,0 +1,1552 @@ + + + + Numark Mixtrack Pro FX + bad1dea5, h67ma, photoenix + Mapping for the Numark Mixtrack Pro FX + https://mixxx.discourse.group/t/numark-mixtrack-pro-fx/19561 + + + + + + + + + + + [Master] + gain + 0xBE + 0x23 + + + + + + + [Master] + crossfader + 0xBF + 0x08 + + + + + + + [Master] + crossfader + 0xB1 + 0x08 + + + + + + + [Channel1] + MixtrackProFX.deck[0].gain.input + 0xB0 + 0x16 + + + + + + [Channel2] + MixtrackProFX.deck[1].gain.input + 0xB1 + 0x16 + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + MixtrackProFX.deck[0].treble.input + 0xB0 + 0x17 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + MixtrackProFX.deck[1].treble.input + 0xB1 + 0x17 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + MixtrackProFX.deck[0].mid.input + 0xB0 + 0x18 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + MixtrackProFX.deck[1].mid.input + 0xB1 + 0x18 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + MixtrackProFX.deck[0].bass.input + 0xB0 + 0x19 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + MixtrackProFX.deck[1].bass.input + 0xB1 + 0x19 + + + + + + + [QuickEffectRack1_[Channel1]] + MixtrackProFX.deck[0].filter.input + 0xB0 + 0x1A + + + + + + [QuickEffectRack1_[Channel2]] + MixtrackProFX.deck[1].filter.input + 0xB1 + 0x1A + + + + + + + [Channel1] + MixtrackProFX.deck[0].volume.input + 0xB0 + 0x1C + + + + + + [Channel2] + MixtrackProFX.deck[1].volume.input + 0xB1 + 0x1C + + + + + + + [Channel1] + MixtrackProFX.deck[0].pitch.inputMSB + 0xB0 + 0x09 + + + + + + [Channel2] + MixtrackProFX.deck[1].pitch.inputMSB + 0xB1 + 0x09 + + + + + + [Channel1] + MixtrackProFX.deck[0].pitch.inputLSB + 0xB0 + 0x29 + + + + + + [Channel2] + MixtrackProFX.deck[1].pitch.inputLSB + 0xB1 + 0x29 + + + + + + + [Channel1] + MixtrackProFX.deck[0].syncButton.input + 0x90 + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].syncButton.input + 0x91 + 0x02 + + + + + + + [Channel1] + MixtrackProFX.deck[0].cueButton.input + 0x90 + 0x01 + + + + + + [Channel2] + MixtrackProFX.deck[1].cueButton.input + 0x91 + 0x01 + + + + + + [Channel1] + MixtrackProFX.deck[0].cueButton.input + 0x80 + 0x01 + + + + + + [Channel2] + MixtrackProFX.deck[1].cueButton.input + 0x81 + 0x01 + + + + + + [Channel1] + MixtrackProFX.deck[0].cueButtonShift.input + 0x90 + 0x05 + + + + + + [Channel2] + MixtrackProFX.deck[1].cueButtonShift.input + 0x91 + 0x05 + + + + + + + [Channel1] + MixtrackProFX.deck[0].playButton.input + 0x90 + 0x00 + + + + + + [Channel2] + MixtrackProFX.deck[1].playButton.input + 0x91 + 0x00 + + + + + + + [Channel1] + MixtrackProFX.deck[0].playButtonStutter.input + 0x90 + 0x04 + + + + + + [Channel2] + MixtrackProFX.deck[1].playButtonStutter.input + 0x91 + 0x04 + + + + + + + [Channel1] + MixtrackProFX.deck[0].shiftButton.input + 0x90 + 0x20 + + + + + + [Channel1] + MixtrackProFX.deck[0].shiftButton.input + 0x80 + 0x20 + + + + + + [Channel2] + MixtrackProFX.deck[1].shiftButton.input + 0x91 + 0x20 + + + + + + [Channel2] + MixtrackProFX.deck[1].shiftButton.input + 0x81 + 0x20 + + + + + + + [Channel1] + MixtrackProFX.scratchToggle + 0x90 + 0x07 + + + + + + [Channel2] + MixtrackProFX.scratchToggle + 0x91 + 0x07 + + + + + + + [Channel1] + MixtrackProFX.deck[0].bleep.input + 0x90 + 0x08 + + + + + + [Channel1] + MixtrackProFX.deck[0].bleep.input + 0x80 + 0x08 + + + + + + [Channel2] + MixtrackProFX.deck[1].bleep.input + 0x91 + 0x08 + + + + + + [Channel2] + MixtrackProFX.deck[1].bleep.input + 0x81 + 0x08 + + + + + + + [Channel1] + MixtrackProFX.deck[0].modeHotcue.input + 0x94 + 0x00 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeHotcue.input + 0x95 + 0x00 + + + + + + [Channel1] + MixtrackProFX.deck[0].modeAutoloop.input + 0x94 + 0x0D + + + + + + [Channel2] + MixtrackProFX.deck[1].modeAutoloop.input + 0x95 + 0x0D + + + + + + [Channel1] + MixtrackProFX.deck[0].modeFadercuts.input + 0x94 + 0x07 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeFadercuts.input + 0x95 + 0x07 + + + + + + [Channel1] + MixtrackProFX.deck[0].modeSample.input + 0x94 + 0x0B + + + + + + [Channel2] + MixtrackProFX.deck[1].modeSample.input + 0x95 + 0x0B + + + + + + [Channel1] + MixtrackProFX.deck[0].modeSampleShift.input + 0x94 + 0x0F + + + + + + [Channel2] + MixtrackProFX.deck[1].modeSampleShift.input + 0x95 + 0x0F + + + + + + [Channel1] + MixtrackProFX.deck[0].modeBeatjump.input + 0x94 + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeBeatjump.input + 0x95 + 0x02 + + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[0].input + 0x94 + 0x14 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[0].input + 0x95 + 0x14 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[1].input + 0x94 + 0x15 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[1].input + 0x95 + 0x15 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[2].input + 0x94 + 0x16 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[2].input + 0x95 + 0x16 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[3].input + 0x94 + 0x17 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[3].input + 0x95 + 0x17 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[4].input + 0x94 + 0x18 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[4].input + 0x95 + 0x18 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[5].input + 0x94 + 0x19 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[5].input + 0x95 + 0x19 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[6].input + 0x94 + 0x1A + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[6].input + 0x95 + 0x1A + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[7].input + 0x94 + 0x1B + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[7].input + 0x95 + 0x1B + + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[0].input + 0x84 + 0x14 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[0].input + 0x85 + 0x14 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[1].input + 0x84 + 0x15 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[1].input + 0x85 + 0x15 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[2].input + 0x84 + 0x16 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[2].input + 0x85 + 0x16 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[3].input + 0x84 + 0x17 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[3].input + 0x85 + 0x17 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[4].input + 0x84 + 0x18 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[4].input + 0x85 + 0x18 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[5].input + 0x84 + 0x19 + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[5].input + 0x85 + 0x19 + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[6].input + 0x84 + 0x1A + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[6].input + 0x85 + 0x1A + + + + + + [Channel1] + MixtrackProFX.deck[0].pads[7].input + 0x84 + 0x1B + + + + + + [Channel2] + MixtrackProFX.deck[1].pads[7].input + 0x85 + 0x1B + + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[0].input + 0x94 + 0x1C + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[0].input + 0x95 + 0x1C + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[1].input + 0x94 + 0x1D + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[1].input + 0x95 + 0x1D + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[2].input + 0x94 + 0x1E + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[2].input + 0x95 + 0x1E + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[3].input + 0x94 + 0x1F + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[3].input + 0x95 + 0x1F + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[4].input + 0x94 + 0x20 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[4].input + 0x95 + 0x20 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[5].input + 0x94 + 0x21 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[5].input + 0x95 + 0x21 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[6].input + 0x94 + 0x22 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[6].input + 0x95 + 0x22 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[7].input + 0x94 + 0x23 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[7].input + 0x95 + 0x23 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loop.input + 0x94 + 0x40 + + + + + + [Channel2] + MixtrackProFX.deck[1].loop.input + 0x95 + 0x40 + + + + + + + [Channel1] + MixtrackProFX.deck[0].reloop.input + 0x94 + 0x41 + + + + + + [Channel2] + MixtrackProFX.deck[1].reloop.input + 0x95 + 0x41 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loopHalf.input + 0x94 + 0x34 + + + + + + [Channel1] + MixtrackProFX.deck[0].loopHalf.input + 0x84 + 0x34 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopHalf.input + 0x85 + 0x34 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopHalf.input + 0x95 + 0x34 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loopIn.input + 0x94 + 0x36 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopIn.input + 0x95 + 0x36 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loopDouble.input + 0x94 + 0x35 + + + + + + [Channel1] + MixtrackProFX.deck[0].loopDouble.input + 0x84 + 0x35 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopDouble.input + 0x95 + 0x35 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopDouble.input + 0x85 + 0x35 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loopOut.input + 0x94 + 0x37 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopOut.input + 0x95 + 0x37 + + + + + + + [Channel1] + MixtrackProFX.wheelTurn + 0xB0 + 0x06 + + + + + + [Channel2] + MixtrackProFX.wheelTurn + 0xB1 + 0x06 + + + + + + + [Channel1] + MixtrackProFX.wheelTouch + 0x90 + 0x06 + + + + + + [Channel2] + MixtrackProFX.wheelTouch + 0x91 + 0x06 + + + + + + + [Library] + MixtrackProFX.browse.knob.input + 0xBF + 0x00 + + + + + + + [Library] + MixtrackProFX.browse.knobShift.input + 0xBF + 0x01 + + + + + + + [Library] + MixtrackProFX.browse.knobButton.input + 0x9F + 0x07 + + + + + + + [Library] + MixtrackProFX.browse.buttonShift.input + 0x9F + 0x06 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loadButton.input + 0x9F + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].loadButton.input + 0x9F + 0x03 + + + + + + + [EffectRack1_EffectUnit1] + MixtrackProFX.effect[0].dryWetKnob.input + 0xB8 + 0x04 + + + + + + [EffectRack1_EffectUnit2] + MixtrackProFX.effect[1].dryWetKnob.input + 0xB8 + 0x04 + + + + + + + [EffectRack1_EffectUnit1] + MixtrackProFX.effect[0].effectParam.input + 0xB8 + 0x05 + + + + + + [EffectRack1_EffectUnit2] + MixtrackProFX.effect[1].effectParam.input + 0xB8 + 0x05 + + + + + + + [Channel1] + MixtrackProFX.effect[0].tap.input + 0x98 + 0x09 + + + + + + [Channel1] + MixtrackProFX.effect[0].tap.input + 0x88 + 0x09 + + + + + + [Channel2] + MixtrackProFX.effect[1].tap.input + 0x99 + 0x09 + + + + + + [Channel2] + MixtrackProFX.effect[1].tap.input + 0x89 + 0x09 + + + + + + + [EffectRack1_EffectUnit1_Effect1] + MixtrackProFX.deck[0].prevEffect.input + 0x98 + 0x00 + + + + + + [EffectRack1_EffectUnit1_Effect1] + MixtrackProFX.deck[0].prevEffect.input + 0x88 + 0x00 + + + + + + + [Library] + MixtrackProFX.browse.setBeatgrid.input + 0x98 + 0x01 + + + + + + [Library] + MixtrackProFX.browse.setBeatgrid.input + 0x88 + 0x01 + + + + + + + [EffectRack1_EffectUnit2_Effect1] + MixtrackProFX.deck[1].prevEffect.input + 0x98 + 0x02 + + + + + + [EffectRack1_EffectUnit2_Effect1] + MixtrackProFX.deck[1].prevEffect.input + 0x88 + 0x02 + + + + + + + [EffectRack1_EffectUnit1_Effect1] + MixtrackProFX.deck[0].nextEffect.input + 0x99 + 0x03 + + + + + + [EffectRack1_EffectUnit1_Effect1] + MixtrackProFX.deck[0].nextEffect.input + 0x89 + 0x03 + + + + + + + [Channel1] + MixtrackProFX.deck[0].beatsnap.input + 0x99 + 0x04 + + + + + + [Channel2] + MixtrackProFX.deck[1].beatsnap.input + 0x99 + 0x04 + + + + + + + [EffectRack1_EffectUnit2_Effect1] + MixtrackProFX.deck[1].nextEffect.input + 0x99 + 0x05 + + + + + + [EffectRack1_EffectUnit2_Effect1] + MixtrackProFX.deck[1].nextEffect.input + 0x89 + 0x05 + + + + + + + [EffectRack1_EffectUnit1_Effect1] + MixtrackProFX.effect[0].enableButton.input + 0xB8 + 0x03 + + + + + + [EffectRack1_EffectUnit2_Effect1] + MixtrackProFX.effect[1].enableButton.input + 0xB9 + 0x03 + + + + + + + [Channel1] + MixtrackProFX.deck[0].pflButton.input + 0x90 + 0x1B + + + + + + [Channel2] + MixtrackProFX.deck[1].pflButton.input + 0x91 + 0x1B + + + + + + + [Master] + MixtrackProFX.headGain.input + 0xBE + 0x2F + + + + + + + [Master] + headMix + 0xBE + 0x27 + + + + + + + [Channel1] + MixtrackProFX.deck[0].pitchBendDown.input + 0x90 + 0x0C + + + + + + [Channel1] + MixtrackProFX.deck[0].pitchBendDown.input + 0x80 + 0x0C + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchBendDown.input + 0x91 + 0x0C + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchBendDown.input + 0x81 + 0x0C + + + + + + + [Channel1] + MixtrackProFX.deck[0].pitchRange.input + 0x90 + 0x2C + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchRange.input + 0x91 + 0x2C + + + + + + + [Channel1] + MixtrackProFX.deck[0].pitchBendUp.input + 0x90 + 0x0B + + + + + + [Channel1] + MixtrackProFX.deck[0].pitchBendUp.input + 0x80 + 0x0B + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchBendUp.input + 0x91 + 0x0B + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchBendUp.input + 0x81 + 0x0B + + + + + + + [Channel1] + MixtrackProFX.deck[0].keylock.input + 0x90 + 0x2B + + + + + + [Channel2] + MixtrackProFX.deck[1].keylock.input + 0x91 + 0x2B + + + + + + + diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js new file mode 100644 index 00000000000..25e56bb6e5b --- /dev/null +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -0,0 +1,854 @@ +// controls annotated with "powerWindow workaround" would normally use +// powerWindow as type. There's a problem when pressing them and releasing +// quickly makes them act like toggles, which is quite confusing. +// the workaround fixes this issue. + +var MixtrackProFX = {}; + +// pitch ranges +// add/remove/modify steps to your liking +// default step must be set in Mixxx settings +// setting is stored per deck in pitchRange.currentRangeIdx +MixtrackProFX.pitchRanges = [0.08, 0.16, 1]; + +// jogwheel +MixtrackProFX.jogScratchSensitivity = 1024; +MixtrackProFX.jogScratchAlpha = 1; // do NOT set to 2 or higher +MixtrackProFX.jogScratchBeta = 1/32; +MixtrackProFX.jogPitchSensitivity = 10; +MixtrackProFX.jogSeekSensitivity = 10000; + +// state variables, don't touch +MixtrackProFX.shifted = false; +MixtrackProFX.scratchModeEnabled = [true, true]; + +MixtrackProFX.init = function() { + // effects for both decks + MixtrackProFX.effect = new components.ComponentContainer(); + MixtrackProFX.effect[0] = new MixtrackProFX.EffectUnit(1); + MixtrackProFX.effect[1] = new MixtrackProFX.EffectUnit(2); + + // decks + MixtrackProFX.deck = new components.ComponentContainer(); + MixtrackProFX.deck[0] = new MixtrackProFX.Deck(1); + MixtrackProFX.deck[1] = new MixtrackProFX.Deck(2); + + MixtrackProFX.browse = new MixtrackProFX.Browse(); + MixtrackProFX.headGain = new MixtrackProFX.HeadGain(); + + var exitDemoSysex = [0xF0, 0x7E, 0x00, 0x06, 0x01, 0xF7]; + midi.sendSysexMsg(exitDemoSysex, exitDemoSysex.length); + + var statusSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0x01, 0xF7]; + midi.sendSysexMsg(statusSysex, statusSysex.length); + + // enables 4 bottom pads fader cuts + var faderCutSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0xF7]; + midi.sendSysexMsg(faderCutSysex, faderCutSysex.length); + + // initialize leds for both decks + for (var i = 0; i < 2; i++) { + midi.sendShortMsg(0x90 + i, 0x00, 0x01); // play + midi.sendShortMsg(0x90 + i, 0x01, 0x01); // cue + midi.sendShortMsg(0x90 + i, 0x02, 0x01); // sync + midi.sendShortMsg(0x90 + i, 0x07, 0x7f); // scratch + midi.sendShortMsg(0x90 + i, 0x1B, 0x01); // pfl + + midi.sendShortMsg(0x94 + i, 0x00, 0x7F); // hotcue + midi.sendShortMsg(0x94 + i, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x94 + i, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x94 + i, 0x0B, 0x01); // sample + + midi.sendShortMsg(0x94 + i, 0x34, 0x01); // half + midi.sendShortMsg(0x94 + i, 0x35, 0x01); // double + midi.sendShortMsg(0x94 + i, 0x40, 0x01); // loop + + // initialize leds for shifted buttons + midi.sendShortMsg(0x90 + i, 0x04, 0x01); // play + midi.sendShortMsg(0x90 + i, 0x05, 0x01); // cue + midi.sendShortMsg(0x90 + i, 0x03, 0x01); // sync + midi.sendShortMsg(0x94 + i, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x94 + i, 0x02, 0x01); // beatjump + midi.sendShortMsg(0x90 + i, 0x08, 0x01); // bleep + midi.sendShortMsg(0x94 + i, 0x36, 0x01); // half + midi.sendShortMsg(0x94 + i, 0x37, 0x01); // double + midi.sendShortMsg(0x94 + i, 0x41, 0x01); // loop + + // pads + for (var j = 0; j < 8; j++) { + midi.sendShortMsg(0x94 + i, 0x14 + j, 0x01); + midi.sendShortMsg(0x94 + i, 0x1C + j, 0x01); // shifted + } + } + + midi.sendShortMsg(0x88, 0x09, 0x01); // tap led + + // check if quantize is enabled + var quantizeEnabled = engine.getValue("[Channel1]", "quantize"); + + // effect leds + midi.sendShortMsg(0x88, 0x00, 0x01); // hpf + midi.sendShortMsg(0x88, 0x01, 0x01); // lpf + midi.sendShortMsg(0x88, 0x02, 0x01); // flanger + midi.sendShortMsg(0x89, 0x03, 0x01); // echo + midi.sendShortMsg(0x89, 0x04, quantizeEnabled ? 0x7F : 0x01); // reverb + midi.sendShortMsg(0x89, 0x05, 0x01); // phaser + + // vumeters leds (off) + midi.sendShortMsg(0xB0, 0x1F, 0x00); + midi.sendShortMsg(0xB1, 0x1F, 0x00); + + engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); + engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); +}; + +MixtrackProFX.shutdown = function() { + var shutdownSysex = [0xF0, 0x00, 0x20, 0x7F, 0x02, 0xF7]; + midi.sendSysexMsg(shutdownSysex, shutdownSysex.length); +}; + +MixtrackProFX.EffectUnit = function(unitNumber) { + this.unitNumber = unitNumber; + this.group = "[EffectRack1_EffectUnit" + unitNumber + "]"; + + this.enableButton = new components.Button({ + input: function(channel, control, value, status, group) { + if (value === 2) { + value = 1; + } + engine.setValue(group, "enabled", value); + } + }); + + this.dryWetKnob = new components.Pot({ + group: this.group, + inKey: "mix" + }); + + this.tap = new components.Button({ + group: "[Channel" + this.unitNumber + "]", + key: "bpm_tap", + midi: [0x88, 0x09], + off: 0x01 + }); + + this.effectParam = new components.Encoder({ + group: "[EffectRack1_EffectUnit" + unitNumber + "_Effect1]", + inKey: "parameter1", + shift: function() { + this.inKey = "parameter2"; + }, + unshift: function() { + this.inKey = "parameter1"; + }, + input: function(channel, control, value) { + if (value === 0x01) { + this.inSetParameter(this.inGetParameter() + 0.05); + } else if (value === 0x7F) { + this.inSetParameter(this.inGetParameter() - 0.05); + } + } + }); +}; + +MixtrackProFX.EffectUnit.prototype = new components.ComponentContainer(); + +MixtrackProFX.Deck = function(number) { + var deck = this; + var channel = number - 1; + + components.Deck.call(this, number); + + this.playButton = new components.PlayButton({ + midi: [0x90 + channel, 0x00], + off: 0x01 + }); + + this.playButtonStutter = new components.Button({ + inKey: "play_stutter" + }); + + // powerWindow workaround + this.cueButton = new components.Button({ + midi: [0x90 + channel, 0x01], + off: 0x01, + outKey: "cue_indicator", + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + value = 1; + } + engine.setValue(group, "cue_default", value); + } + }); + + this.cueButtonShift = new components.Button({ + inKey: "start_stop" + }); + + this.syncButton = new components.SyncButton({ + midi: [0x90 + channel, 0x02], + off: 0x01 + }); + + this.pflButton = new components.Button({ + type: components.Button.prototype.types.toggle, + midi: [0x90 + channel, 0x1B], + off: 0x01, + key: "pfl" + }); + + this.loadButton = new components.Button({ + inKey: "LoadSelectedTrack", + shift: function() { + this.group = "[PreviewDeck1]"; + }, + unshift: function() { + this.group = "[Channel" + (channel + 1) + "]"; + } + }); + + this.volume = new components.Pot({ + group: this.currentDeck, + inKey: "volume" + }); + + this.treble = new components.Pot({ + group: "[EqualizerRack1_" + this.currentDeck + "_Effect1]", + inKey: "parameter3" + }); + + this.mid = new components.Pot({ + group: "[EqualizerRack1_" + this.currentDeck + "_Effect1]", + inKey: "parameter2" + }); + + this.bass = new components.Pot({ + group: "[EqualizerRack1_" + this.currentDeck + "_Effect1]", + inKey: "parameter1" + }); + + this.filter = new components.Pot({ + group: "[QuickEffectRack1_" + this.currentDeck + "]", + inKey: "super1" + }); + + this.gain = new components.Pot({ + inKey: "pregain" + }); + + this.pitch = new components.Pot({ + inKey: "rate", + invert: true + }); + + this.pads = new components.ComponentContainer(); + this.padsShift = new components.ComponentContainer(); + + for (var i = 0; i < 8; i++) { + this.pads[i] = new components.Button({ + group: this.currentDeck, + midi: [0x94 + channel, 0x14 + i], + inKey: "hotcue_" + (i + 1) + "_activate", + outKey: "hotcue_" + (i + 1) + "_enabled", + off: 0x01 + }); + + this.padsShift[i] = new components.Button({ + group: this.currentDeck, + inKey: "hotcue_" + (i + 1) + "_clear" + }); + } + + // switch pad mode to hotcue + this.modeHotcue = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x7F); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + + for (var i = 0; i < 8; i++) { + deck.pads[i].group = deck.currentDeck; + deck.pads[i].inKey = "hotcue_" + (i + 1) + "_activate"; + deck.pads[i].outKey = "hotcue_" + (i + 1) + "_enabled"; + + deck.padsShift[i].group = deck.currentDeck; + deck.padsShift[i].inKey = "hotcue_" + (i + 1) + "_clear"; + } + + deck.pads.reconnectComponents(); + } + }); + + // switch pad mode to auto loop + this.modeAutoloop = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x7F); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + + // this is just sad + deck.pads[0].inKey = "beatloop_0.0625_toggle"; + deck.pads[0].outKey = "beatloop_0.0625_enabled"; + deck.pads[1].inKey = "beatloop_0.125_toggle"; + deck.pads[1].outKey = "beatloop_0.125_enabled"; + deck.pads[2].inKey = "beatloop_0.25_toggle"; + deck.pads[2].outKey = "beatloop_0.25_enabled"; + deck.pads[3].inKey = "beatloop_0.5_toggle"; + deck.pads[3].outKey = "beatloop_0.5_enabled"; + deck.pads[4].inKey = "beatloop_1_toggle"; + deck.pads[4].outKey = "beatloop_1_enabled"; + deck.pads[5].inKey = "beatloop_2_toggle"; + deck.pads[5].outKey = "beatloop_2_enabled"; + deck.pads[6].inKey = "beatloop_4_toggle"; + deck.pads[6].outKey = "beatloop_4_enabled"; + deck.pads[7].inKey = "beatloop_8_toggle"; + deck.pads[7].outKey = "beatloop_8_enabled"; + + deck.padsShift[0].inKey = "beatlooproll_0.0625_activate"; + deck.padsShift[1].inKey = "beatlooproll_0.125_activate"; + deck.padsShift[2].inKey = "beatlooproll_0.25_activate"; + deck.padsShift[3].inKey = "beatlooproll_0.5_activate"; + deck.padsShift[4].inKey = "beatlooproll_1_activate"; + deck.padsShift[5].inKey = "beatlooproll_2_activate"; + deck.padsShift[6].inKey = "beatlooproll_4_activate"; + deck.padsShift[7].inKey = "beatlooproll_8_activate"; + + for (var i = 0; i < 8; i++) { + deck.pads[i].group = deck.currentDeck; + deck.padsShift[i].group = deck.currentDeck; + } + + deck.pads.reconnectComponents(); + } + }); + + // switch pad mode to fader cuts + this.modeFadercuts = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x09); // fader cuts (yes 0x09 works the best for some reason) + midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + + // the "fader cuts" function is somehow burned into hardware + + // need to set the pads to *something* to not trigger controls + // triggered previously by the pads and not display their status (e.g. hotcue set) + // nop would be really useful in this situation + // we can assume channel 4 is unused and therefore won't mess anything up + for (var i = 0; i < 8; i++) { + deck.pads[i].group = "[Channel4]"; + deck.padsShift[i].group = "[Channel4]"; + } + + deck.pads.reconnectComponents(); + } + }); + + // switch pad mode to sampler + this.modeSample = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x90 + channel, 0x0B, 0x7F); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + + for (var i = 0; i < 8; i++) { + deck.pads[i].group = "[Sampler" + (i + 1) + "]"; + deck.pads[i].inKey = "cue_gotoandplay"; + deck.pads[i].outKey = "play"; + + deck.padsShift[i].group = "[Sampler" + (i + 1) + "]"; + deck.padsShift[i].inKey = "start_stop"; + } + + deck.pads.reconnectComponents(); + } + }); + + // switch pad mode to shifted sampler + this.modeSampleShift = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x7F); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + + for (var i = 0; i < 8; i++) { + deck.pads[i].group = "[Sampler" + (i + 9) + "]"; + deck.pads[i].inKey = "cue_gotoandplay"; + deck.pads[i].outKey = "play"; + + deck.padsShift[i].group = "[Sampler" + (i + 9) + "]"; + deck.padsShift[i].inKey = "start_stop"; + } + + deck.pads.reconnectComponents(); + } + }); + + // switch pad mode to beatjump + this.modeBeatjump = new components.Button({ + input: function(channel) { + midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue + midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts + midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample + midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x90 + channel, 0x02, 0x7F); // beatjump + + deck.pads[0].inKey = "beatjump_0.0625_forward"; + deck.pads[0].outKey = "beatjump_0.0625_forward"; + deck.pads[1].inKey = "beatjump_0.125_forward"; + deck.pads[1].outKey = "beatjump_0.125_forward"; + deck.pads[2].inKey = "beatjump_0.25_forward"; + deck.pads[2].outKey = "beatjump_0.25_forward"; + deck.pads[3].inKey = "beatjump_0.5_forward"; + deck.pads[3].outKey = "beatjump_0.5_forward"; + deck.pads[4].inKey = "beatjump_1_forward"; + deck.pads[4].outKey = "beatjump_1_forward"; + deck.pads[5].inKey = "beatjump_2_forward"; + deck.pads[5].outKey = "beatjump_2_forward"; + deck.pads[6].inKey = "beatjump_forward"; // this button is adjustable, it uses the value set in the interface (4 by default) + deck.pads[6].outKey = "beatjump_forward"; + deck.pads[7].inKey = "beatjump_8_forward"; + deck.pads[7].outKey = "beatjump_8_forward"; + + deck.padsShift[0].inKey = "beatjump_0.0625_backward"; + deck.padsShift[1].inKey = "beatjump_0.125_backward"; + deck.padsShift[2].inKey = "beatjump_0.25_backward"; + deck.padsShift[3].inKey = "beatjump_0.5_backward"; + deck.padsShift[4].inKey = "beatjump_1_backward"; + deck.padsShift[5].inKey = "beatjump_2_backward"; + deck.padsShift[6].inKey = "beatjump_backward"; // this button is adjustable, it uses the value set in the interface (4 by default) + deck.padsShift[7].inKey = "beatjump_8_backward"; + + for (var i = 0; i < 8; i++) { + deck.pads[i].group = deck.currentDeck; + deck.padsShift[i].group = deck.currentDeck; + } + + deck.pads.reconnectComponents(); + } + }); + + this.shiftButton = new components.Button({ + input: function(channel, control, value) { + // each shift button shifts both decks + // more consistent with the logic burned into hardware + if (value === 0x7F) { + MixtrackProFX.shifted = true; + MixtrackProFX.deck[0].shift(); + MixtrackProFX.deck[1].shift(); + MixtrackProFX.browse.shift(); + MixtrackProFX.effect.shift(); + } else if (value === 0) { + MixtrackProFX.shifted = false; + MixtrackProFX.deck[0].unshift(); + MixtrackProFX.deck[1].unshift(); + MixtrackProFX.browse.unshift(); + MixtrackProFX.effect.unshift(); + } + } + }); + + this.loop = new components.Button({ + key: "loop_enabled", + midi: [0x94 + channel, 0x40], + off: 0x01, + input: function(channel, control, value, status, group) { + if (engine.getValue(group, "loop_enabled") === 0) { + script.triggerControl(group, "beatloop_activate"); + } else { + script.triggerControl(group, "beatlooproll_activate"); + } + } + }); + + this.reloop = new components.Button({ + inKey: "reloop_toggle" // or loop_in_goto to not enable loop + }); + + this.loopHalf = new components.Button({ + key: "loop_halve", + midi: [0x94 + channel, 0x34], + off: 0x01 + }); + + this.loopDouble = new components.Button({ + key: "loop_double", + midi: [0x94 + channel, 0x35], + off: 0x01 + }); + + this.loopIn = new components.Button({ + inKey: "loop_in" + }); + + this.loopOut = new components.Button({ + inKey: "loop_out" + }); + + // powerWindow workaround + this.bleep = new components.Button({ + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + value = 1; + } + engine.setValue(group, "reverseroll", value); + } + }); + + // powerWindow workaround + this.pitchBendUp = new components.Button({ + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + value = 1; + } + engine.setValue(group, "rate_temp_up", value); + } + }); + + // powerWindow workaround + this.pitchBendDown = new components.Button({ + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + value = 1; + } + engine.setValue(group, "rate_temp_down", value); + } + }); + + this.keylock = new components.Button({ + type: components.Button.prototype.types.toggle, + inKey: "keylock" + }); + + this.pitchRange = new components.Button({ + currentRangeIdx: 0, + input: function(channel, control, value, status, group) { + this.currentRangeIdx = (this.currentRangeIdx + 1) % MixtrackProFX.pitchRanges.length; + engine.setValue(group, "rateRange", MixtrackProFX.pitchRanges[this.currentRangeIdx]); + } + }); + + this.prevEffect = new components.Button({ + group: "[EffectRack1_EffectUnit" + number + "_Effect1]", + key: "prev_effect", + midi: [0x98, channel*2], + off: 0x01 + }); + + this.nextEffect = new components.Button({ + group: "[EffectRack1_EffectUnit" + number + "_Effect1]", + key: "next_effect", + midi: [0x99, 0x03 + channel*2], + off: 0x01 + }); + + this.beatsnap = new components.Button({ + type: components.Button.prototype.types.toggle, + key: "quantize", + midi: [0x89, 0x04], + off: 0x01 + }); + + this.reconnectComponents(function(component) { + if (component.group === undefined) { + component.group = this.currentDeck; + } + }); +}; + +MixtrackProFX.Deck.prototype = new components.Deck(); + +MixtrackProFX.Browse = function() { + this.knob = new components.Encoder({ + group: "[Library]", + inKey: "Move", + input: function(channel, control, value) { + if (value === 0x01) { + engine.setParameter(this.group, this.inKey + "Down", 1); + } else if (value === 0x7F) { + engine.setParameter(this.group, this.inKey + "Up", 1); + } + } + }); + + this.knobShift = new components.Encoder({ + group: "[Channel1]", // if it's stupid and works, then it's not stupid + input: function(channel, control, value) { + if (value === 0x01) { + engine.setParameter(this.group, "waveform_zoom_down", 1); + } else if (value === 0x7F) { + engine.setParameter(this.group, "waveform_zoom_up", 1); + } + } + }); + + this.knobButton = new components.Button({ + group: "[Library]", + inKey: "MoveFocusForward" + }); + + this.buttonShift = new components.Button({ + group: "[Library]", + inKey: "GoToItem" + }); + + this.setBeatgrid = new components.Button({ + group: "[Channel1]", + key: "beats_translate_curpos", + midi: [0x88, 0x01], + off: 0x01, + shift: function() { + this.group = "[Channel2]"; + }, + unshift: function() { + this.group = "[Channel1]"; + } + }); +}; + +MixtrackProFX.Browse.prototype = new components.ComponentContainer(); + +MixtrackProFX.HeadGain = function() { + components.Pot.call(this); +}; + +MixtrackProFX.HeadGain.prototype = new components.Pot({ + group: "[Master]", + inKey: "headGain" +}); + +MixtrackProFX.vuCallback = function(value, group) { + var level = value * 90; + + if (engine.getValue("[Channel1]", "pfl") || engine.getValue("[Channel2]", "pfl")) { + if (group === "[Channel1]") { + midi.sendShortMsg(0xB0, 0x1F, level); + } else if (group === "[Channel2]") { + midi.sendShortMsg(0xB1, 0x1F, level); + } + } else if (group === "[Channel1]") { + midi.sendShortMsg(0xB0, 0x1F, level); + } else if (group === "[Channel2]") { + midi.sendShortMsg(0xB1, 0x1F, level); + } +}; + +MixtrackProFX.scratchToggle = function(channel) { + MixtrackProFX.scratchModeEnabled[channel] = !MixtrackProFX.scratchModeEnabled[channel]; + midi.sendShortMsg(0x90 | channel, 0x07, MixtrackProFX.scratchModeEnabled[channel] ? 0x7F : 0x01); +}; + +// below: choose scratch A OR scratch B + +// ==== SCRATCH A START ==== // + +MixtrackProFX.wheelTouch = function(channel, control, value) { + var deckNumber = channel + 1; + + if (!MixtrackProFX.shifted && MixtrackProFX.scratchModeEnabled[channel] && value === 0x7F) { + // touch start + + engine.scratchEnable(deckNumber, MixtrackProFX.jogScratchSensitivity, 33+1/3, MixtrackProFX.jogScratchAlpha, MixtrackProFX.jogScratchBeta, true); + } else if (value === 0) { + // touch end + engine.scratchDisable(deckNumber, true); + } +}; + +MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { + var deckNumber = channel + 1; + + var newValue = value; + + if (value >= 64) { + // correct the value if going backwards + newValue -= 128; + } + + if (MixtrackProFX.shifted) { + // seek + var oldPos = engine.getValue(group, "playposition"); + + if (oldPos <= 0) { + oldPos = 0; + } + + if (oldPos >= 1) { + oldPos = 1; + } + + engine.setValue(group, "playposition", oldPos + newValue / MixtrackProFX.jogSeekSensitivity); + } else if (MixtrackProFX.scratchModeEnabled[channel] && engine.isScratching(deckNumber)) { + // scratch + engine.scratchTick(deckNumber, newValue); + } else { + // pitch bend + engine.setValue(group, "jog", newValue / MixtrackProFX.jogPitchSensitivity); + } +}; + +// ==== SCRATCH A END ==== // + +// ==== SCRATCH B START ==== // + +/*MixtrackProFX.scratchTimer = [null, null]; +MixtrackProFX.scratchTick = [null, null]; +MixtrackProFX.scratchDirection = [null, null]; +MixtrackProFX.scratchAccumulator = [0, 0]; +MixtrackProFX.lastScratchTick = [0, 0]; +MixtrackProFX.touching = [false, false]; +MixtrackProFX.searching = [false, false]; + +MixtrackProFX.startScratchTimer = function(channel) { + if (MixtrackProFX.scratchTimer[channel]) { + return; + } + + MixtrackProFX.scratchTick[channel] = 0; + MixtrackProFX.scratchTimer[channel] = engine.beginTimer(20, function() { + MixtrackProFX.scratchTimerCallback(channel); + }); +}; + +MixtrackProFX.stopScratchTimer = function(channel) { + if (MixtrackProFX.scratchTimer[channel]) { + engine.stopTimer(MixtrackProFX.scratchTimer[channel]); + } + + MixtrackProFX.scratchTimer[channel] = null; +}; + +MixtrackProFX.resetScratchTimer = function(channel, tick) { + if (!MixtrackProFX.scratchTimer[channel]) { + return; + } + + MixtrackProFX.scratchTick[channel] = tick; +}; + +MixtrackProFX.scratchTimerCallback = function(channel) { + if ((MixtrackProFX.scratchDirection[channel] && Math.abs(MixtrackProFX.scratchTick[channel]) > 2) + || (!MixtrackProFX.scratchDirection[channel] && Math.abs(MixtrackProFX.scratchTick[channel]) > 1)) { + MixtrackProFX.scratchTick[channel] = 0; + return; + } + + MixtrackProFX.scratchDisable(channel); +}; + +MixtrackProFX.scratchEnable = function(channel) { + engine.scratchEnable(channel + 1, MixtrackProFX.jogScratchSensitivity, 33+1/3, MixtrackProFX.jogScratchAlpha, MixtrackProFX.jogScratchBeta); + MixtrackProFX.stopScratchTimer(channel); +}; + +MixtrackProFX.scratchDisable = function(channel) { + MixtrackProFX.searching[channel] = false; + MixtrackProFX.stopScratchTimer(channel); + engine.scratchDisable(channel + 1, false); +}; + +MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { + var deckNumber = channel + 1; + var direction; + var newValue; + + if (value < 64) { + direction = true; + } else { + direction = false; + } + + var delta = Math.abs(MixtrackProFX.lastScratchTick[channel] - value); + if (MixtrackProFX.scratchDirection[channel] !== null && MixtrackProFX.scratchDirection[channel] != direction && delta < 64) { + direction = !direction; + } + + if (direction) { + newValue = value; + } else { + newValue = value - 128; + } + + if (MixtrackProFX.searching[channel]) { + var position = engine.getValue(group, "playposition"); + + if (position <= 0) { + position = 0; + } + + if (position >= 1) { + position = 1; + } + + engine.setValue(group, "playposition", position + newValue / MixtrackProFX.jogSeekSensitivity); + MixtrackProFX.resetScratchTimer(channel, newValue); + + return; + } + + if (MixtrackProFX.scratchDirection[channel] === null) { + MixtrackProFX.scratchDirection[channel] = direction; + } else if (MixtrackProFX.scratchDirection[channel] != direction) { + if (!MixtrackProFX.touching[channel]) { + MixtrackProFX.scratchDisable(channel); + } + + MixtrackProFX.scratchAccumulator[channel] = 0; + } + + MixtrackProFX.lastScratchTick[channel] = value; + MixtrackProFX.scratchDirection[channel] = direction; + MixtrackProFX.scratchAccumulator[channel] += Math.abs(newValue); + + if (engine.isScratching(deckNumber)) { + engine.scratchTick(deckNumber, newValue); + MixtrackProFX.resetScratchTimer(channel, newValue); + } else if (MixtrackProFX.shifted) { + if (MixtrackProFX.scratchAccumulator[channel] > 61) { + MixtrackProFX.scratchAccumulator[channel] -= 61; + if (direction) { + engine.setParameter(group, "beatjump_1_forward", 1); + } else { + engine.setParameter(group, "beatjump_1_backward", 1); + } + } + } else { + engine.setValue(group, "jog", newValue / MixtrackProFX.jogPitchSensitivity); + } +}; + +MixtrackProFX.wheelTouch = function(channel, control, value, status, group) { + if (!MixtrackProFX.shifted && !MixtrackProFX.searching[channel] && !MixtrackProFX.scratchModeEnabled[channel] && value != 0) { + return; + } + + MixtrackProFX.touching[channel] = 0x7F == value; + + if (value === 0x7F && !MixtrackProFX.shifted && !MixtrackProFX.searching[channel]) { + MixtrackProFX.scratchEnable(channel); + } else if (value === 0x7F && (MixtrackProFX.shifted || MixtrackProFX.searching[channel])) { + MixtrackProFX.scratchDisable(channel); + MixtrackProFX.searching[channel] = true; + MixtrackProFX.stopScratchTimer(channel); + } else { + MixtrackProFX.startScratchTimer(channel); + } +};*/ + +// ==== SCRATCH B END ==== // From 15e4d465ffe0a4312cfe8eb42352aa5e6338ab02 Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 19 Apr 2021 02:29:35 +0200 Subject: [PATCH 02/52] Numark Mixtrack Pro FX: added pad lights when shifted --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 25e56bb6e5b..3bdb5d78384 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -250,7 +250,14 @@ MixtrackProFX.Deck = function(number) { midi: [0x94 + channel, 0x14 + i], inKey: "hotcue_" + (i + 1) + "_activate", outKey: "hotcue_" + (i + 1) + "_enabled", - off: 0x01 + off: 0x01, + number: i, + shift: function() { + this.midi = [0x94 + channel, 0x1C + this.number]; + }, + unshift: function() { + this.midi = [0x94 + channel, 0x14 + this.number]; + } }); this.padsShift[i] = new components.Button({ @@ -461,6 +468,7 @@ MixtrackProFX.Deck = function(number) { MixtrackProFX.browse.unshift(); MixtrackProFX.effect.unshift(); } + MixtrackProFX.deck[channel].pads.reconnectComponents(); // for displaying pads lights when shifted } }); From 8de2c6fb527be3be39daa2be2ca83b78624add0e Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 17 May 2021 00:37:39 +0200 Subject: [PATCH 03/52] added blinking lights when alt pad function is selected --- .../Numark-Mixtrack-Pro-FX-scripts.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 3bdb5d78384..bc0823a5220 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -18,6 +18,10 @@ MixtrackProFX.jogScratchBeta = 1/32; MixtrackProFX.jogPitchSensitivity = 10; MixtrackProFX.jogSeekSensitivity = 10000; +// blink settings +MixtrackProFX.enableBlink = true; +MixtrackProFX.blinkDelay = 700; + // state variables, don't touch MixtrackProFX.shifted = false; MixtrackProFX.scratchModeEnabled = [true, true]; @@ -156,6 +160,8 @@ MixtrackProFX.EffectUnit.prototype = new components.ComponentContainer(); MixtrackProFX.Deck = function(number) { var deck = this; var channel = number - 1; + var blinkTimer = 0; + var blinkLedState = true; components.Deck.call(this, number); @@ -269,6 +275,7 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to hotcue this.modeHotcue = new components.Button({ input: function(channel) { + deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x7F); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts @@ -292,6 +299,7 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to auto loop this.modeAutoloop = new components.Button({ input: function(channel) { + deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x7F); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts @@ -338,6 +346,7 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to fader cuts this.modeFadercuts = new components.Button({ input: function(channel) { + deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x09); // fader cuts (yes 0x09 works the best for some reason) @@ -363,6 +372,7 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to sampler this.modeSample = new components.Button({ input: function(channel) { + deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts @@ -392,6 +402,7 @@ MixtrackProFX.Deck = function(number) { midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample midi.sendShortMsg(0x90 + channel, 0x0F, 0x7F); // sample shifted midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump + deck.blinkLedOn(0x90 + channel, 0x0B); // blink sample for (var i = 0; i < 8; i++) { deck.pads[i].group = "[Sampler" + (i + 9) + "]"; @@ -415,6 +426,7 @@ MixtrackProFX.Deck = function(number) { midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted midi.sendShortMsg(0x90 + channel, 0x02, 0x7F); // beatjump + deck.blinkLedOn(0x90 + channel, 0x00); // blink hotcue deck.pads[0].inKey = "beatjump_0.0625_forward"; deck.pads[0].outKey = "beatjump_0.0625_forward"; @@ -451,6 +463,30 @@ MixtrackProFX.Deck = function(number) { } }); + // start an infinite timer that toggles led state + this.blinkLedOn = function(midi1, midi2) { + if (!MixtrackProFX.enableBlink) { + return; + } + + deck.blinkLedOff(); + blinkLedState = true; + blinkTimer = engine.beginTimer(MixtrackProFX.blinkDelay, function() { + midi.sendShortMsg(midi1, midi2, blinkLedState ? 0x7F : 0x01); + blinkLedState = !blinkLedState; + }); + }; + + // stop the blink timer + this.blinkLedOff = function() { + if (!MixtrackProFX.enableBlink || blinkTimer === 0) { + return; + } + + engine.stopTimer(blinkTimer); + blinkTimer = 0; + }; + this.shiftButton = new components.Button({ input: function(channel, control, value) { // each shift button shifts both decks From 014e722d3821fd0277501c602438f0324724a785 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 22 Jul 2021 15:39:34 +0200 Subject: [PATCH 04/52] added bonus feature: key change --- .../Numark-Mixtrack-Pro-FX-scripts.js | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index bc0823a5220..8ee111633c5 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -592,14 +592,32 @@ MixtrackProFX.Deck = function(number) { group: "[EffectRack1_EffectUnit" + number + "_Effect1]", key: "prev_effect", midi: [0x98, channel*2], - off: 0x01 + off: 0x01, + shift: function() { + this.group = "[Channel" + number + "]"; + this.inKey = "pitch_up"; + this.outKey = "pitch_up"; + }, + unshift: function() { + this.group = "[EffectRack1_EffectUnit" + number + "_Effect1]"; + this.inKey = "prev_effect"; + this.outKey = "prev_effect"; + } }); this.nextEffect = new components.Button({ group: "[EffectRack1_EffectUnit" + number + "_Effect1]", key: "next_effect", midi: [0x99, 0x03 + channel*2], - off: 0x01 + off: 0x01, + shift: function() { + this.group = "[Channel" + number + "]"; + this.inKey = "pitch_down"; + }, + unshift: function() { + this.group = "[EffectRack1_EffectUnit" + number + "_Effect1]"; + this.inKey = "next_effect"; + } }); this.beatsnap = new components.Button({ From e2e4d4f438aa735d7b5cd036b9e1c00f7caced89 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 22 Jul 2021 15:50:28 +0200 Subject: [PATCH 05/52] fixed a bug with pad lights when pressing the other shift --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 8ee111633c5..99a65e4f819 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -504,7 +504,10 @@ MixtrackProFX.Deck = function(number) { MixtrackProFX.browse.unshift(); MixtrackProFX.effect.unshift(); } - MixtrackProFX.deck[channel].pads.reconnectComponents(); // for displaying pads lights when shifted + + // for displaying pads lights when shifted + MixtrackProFX.deck[0].pads.reconnectComponents(); + MixtrackProFX.deck[1].pads.reconnectComponents(); } }); From b295fc8e0d0e700e5500a5c6bb27a5aae137a36e Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 22 Jul 2021 16:20:23 +0200 Subject: [PATCH 06/52] fixed the sync button --- .../Numark Mixtrack Pro FX.midi.xml | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index d981e96fbbd..7fee429e5f8 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -192,7 +192,7 @@ - + [Channel1] MixtrackProFX.deck[0].syncButton.input @@ -211,6 +211,44 @@ + + + [Channel1] + MixtrackProFX.deck[0].syncButton.input + 0x80 + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].syncButton.input + 0x81 + 0x02 + + + + + + + [Channel1] + MixtrackProFX.deck[0].syncButton.input + 0x90 + 0x03 + + + + + + [Channel2] + MixtrackProFX.deck[1].syncButton.input + 0x91 + 0x03 + + + + [Channel1] From 7347d5f31ed54b2c93c8be7cbd4b332d5dd8035c Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 29 Jul 2021 18:25:14 +0200 Subject: [PATCH 07/52] fixed beatlooproll --- .../Numark Mixtrack Pro FX.midi.xml | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 7fee429e5f8..3b185f685de 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -979,6 +979,151 @@ + + + [Channel1] + MixtrackProFX.deck[0].padsShift[0].input + 0x84 + 0x1C + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[0].input + 0x85 + 0x1C + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[1].input + 0x84 + 0x1D + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[1].input + 0x85 + 0x1D + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[2].input + 0x84 + 0x1E + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[2].input + 0x85 + 0x1E + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[3].input + 0x84 + 0x1F + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[3].input + 0x85 + 0x1F + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[4].input + 0x84 + 0x20 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[4].input + 0x85 + 0x20 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[5].input + 0x84 + 0x21 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[5].input + 0x85 + 0x21 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[6].input + 0x84 + 0x22 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[6].input + 0x85 + 0x22 + + + + + + [Channel1] + MixtrackProFX.deck[0].padsShift[7].input + 0x84 + 0x23 + + + + + + [Channel2] + MixtrackProFX.deck[1].padsShift[7].input + 0x85 + 0x23 + + + + [Channel1] From a6d782f922c7e823cae813274933faf02db3b194 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 29 Jul 2021 19:24:26 +0200 Subject: [PATCH 08/52] fixed waveform zoom when waveform sync is disabled --- .../Numark-Mixtrack-Pro-FX-scripts.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 99a65e4f819..8506a6b28f6 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -11,6 +11,10 @@ var MixtrackProFX = {}; // setting is stored per deck in pitchRange.currentRangeIdx MixtrackProFX.pitchRanges = [0.08, 0.16, 1]; +// whether the corresponding Mixxx option is enabled +// (Settings -> Preferences -> Waveforms -> Synchronize zoom level across all waveforms) +MixtrackProFX.waveformsSynced = true; + // jogwheel MixtrackProFX.jogScratchSensitivity = 1024; MixtrackProFX.jogScratchAlpha = 1; // do NOT set to 2 or higher @@ -653,12 +657,23 @@ MixtrackProFX.Browse = function() { }); this.knobShift = new components.Encoder({ - group: "[Channel1]", // if it's stupid and works, then it's not stupid input: function(channel, control, value) { if (value === 0x01) { - engine.setParameter(this.group, "waveform_zoom_down", 1); + engine.setParameter("[Channel1]", "waveform_zoom_down", 1); + + // need to zoom both channels if waveform sync is disabled in Mixxx settings. + // and when it's enabled then no need to zoom 2nd channel, as it will cause + // the zoom to jump 2 levels at once + if (!MixtrackProFX.waveformsSynced) { + engine.setParameter("[Channel2]", "waveform_zoom_down", 1); + } } else if (value === 0x7F) { - engine.setParameter(this.group, "waveform_zoom_up", 1); + engine.setParameter("[Channel1]", "waveform_zoom_up", 1); + + // see above comment + if (!MixtrackProFX.waveformsSynced) { + engine.setParameter("[Channel2]", "waveform_zoom_up", 1); + } } } }); From 286c993930551aa0f53546903da5e5a1900b6a11 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 29 Jul 2021 22:35:54 +0200 Subject: [PATCH 09/52] use components.CueButton for cue button --- .../Numark-Mixtrack-Pro-FX-scripts.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 8506a6b28f6..f04c26af9e9 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -1,6 +1,6 @@ // controls annotated with "powerWindow workaround" would normally use -// powerWindow as type. There's a problem when pressing them and releasing -// quickly makes them act like toggles, which is quite confusing. +// powerWindow as type. There's a problem - when pressing them and releasing +// them *quickly* makes them act like toggles, which is quite confusing. // the workaround fixes this issue. var MixtrackProFX = {}; @@ -178,17 +178,9 @@ MixtrackProFX.Deck = function(number) { inKey: "play_stutter" }); - // powerWindow workaround - this.cueButton = new components.Button({ + this.cueButton = new components.CueButton({ midi: [0x90 + channel, 0x01], - off: 0x01, - outKey: "cue_indicator", - input: function(channel, control, value, status, group) { - if (value === 0x7F) { - value = 1; - } - engine.setValue(group, "cue_default", value); - } + off: 0x01 }); this.cueButtonShift = new components.Button({ From acbbdd8d7ecfa39aa7316fd8e1d320762356267f Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 29 Jul 2021 22:41:42 +0200 Subject: [PATCH 10/52] added documentation name to xml --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 3b185f685de..d3986b19ab9 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -5,6 +5,7 @@ bad1dea5, h67ma, photoenix Mapping for the Numark Mixtrack Pro FX https://mixxx.discourse.group/t/numark-mixtrack-pro-fx/19561 + numark_mixtrack_pro_fx From a720b28c70cdf1e62af4b0506873f75c58ac3152 Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 30 Jul 2021 13:44:25 +0200 Subject: [PATCH 11/52] removed snarky comments --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 6 +++--- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index d3986b19ab9..a7f056d82be 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -24,7 +24,7 @@ - + [Master] crossfader @@ -34,7 +34,7 @@ - + [Master] crossfader @@ -980,7 +980,7 @@ - + [Channel1] MixtrackProFX.deck[0].padsShift[0].input diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index f04c26af9e9..cdc0db2882b 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -345,7 +345,7 @@ MixtrackProFX.Deck = function(number) { deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x09); // fader cuts (yes 0x09 works the best for some reason) + midi.sendShortMsg(0x90 + channel, 0x07, 0x09); // fader cuts (0x09 works better than 0x7F for some reason) midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump From 0cca824005d47eade272c3cd76d8247d123da6c1 Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 30 Jul 2021 13:46:50 +0200 Subject: [PATCH 12/52] removed alternate scratch logic --- .../Numark-Mixtrack-Pro-FX-scripts.js | 154 ------------------ 1 file changed, 154 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index cdc0db2882b..ce60f6eab59 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -726,10 +726,6 @@ MixtrackProFX.scratchToggle = function(channel) { midi.sendShortMsg(0x90 | channel, 0x07, MixtrackProFX.scratchModeEnabled[channel] ? 0x7F : 0x01); }; -// below: choose scratch A OR scratch B - -// ==== SCRATCH A START ==== // - MixtrackProFX.wheelTouch = function(channel, control, value) { var deckNumber = channel + 1; @@ -774,153 +770,3 @@ MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { engine.setValue(group, "jog", newValue / MixtrackProFX.jogPitchSensitivity); } }; - -// ==== SCRATCH A END ==== // - -// ==== SCRATCH B START ==== // - -/*MixtrackProFX.scratchTimer = [null, null]; -MixtrackProFX.scratchTick = [null, null]; -MixtrackProFX.scratchDirection = [null, null]; -MixtrackProFX.scratchAccumulator = [0, 0]; -MixtrackProFX.lastScratchTick = [0, 0]; -MixtrackProFX.touching = [false, false]; -MixtrackProFX.searching = [false, false]; - -MixtrackProFX.startScratchTimer = function(channel) { - if (MixtrackProFX.scratchTimer[channel]) { - return; - } - - MixtrackProFX.scratchTick[channel] = 0; - MixtrackProFX.scratchTimer[channel] = engine.beginTimer(20, function() { - MixtrackProFX.scratchTimerCallback(channel); - }); -}; - -MixtrackProFX.stopScratchTimer = function(channel) { - if (MixtrackProFX.scratchTimer[channel]) { - engine.stopTimer(MixtrackProFX.scratchTimer[channel]); - } - - MixtrackProFX.scratchTimer[channel] = null; -}; - -MixtrackProFX.resetScratchTimer = function(channel, tick) { - if (!MixtrackProFX.scratchTimer[channel]) { - return; - } - - MixtrackProFX.scratchTick[channel] = tick; -}; - -MixtrackProFX.scratchTimerCallback = function(channel) { - if ((MixtrackProFX.scratchDirection[channel] && Math.abs(MixtrackProFX.scratchTick[channel]) > 2) - || (!MixtrackProFX.scratchDirection[channel] && Math.abs(MixtrackProFX.scratchTick[channel]) > 1)) { - MixtrackProFX.scratchTick[channel] = 0; - return; - } - - MixtrackProFX.scratchDisable(channel); -}; - -MixtrackProFX.scratchEnable = function(channel) { - engine.scratchEnable(channel + 1, MixtrackProFX.jogScratchSensitivity, 33+1/3, MixtrackProFX.jogScratchAlpha, MixtrackProFX.jogScratchBeta); - MixtrackProFX.stopScratchTimer(channel); -}; - -MixtrackProFX.scratchDisable = function(channel) { - MixtrackProFX.searching[channel] = false; - MixtrackProFX.stopScratchTimer(channel); - engine.scratchDisable(channel + 1, false); -}; - -MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { - var deckNumber = channel + 1; - var direction; - var newValue; - - if (value < 64) { - direction = true; - } else { - direction = false; - } - - var delta = Math.abs(MixtrackProFX.lastScratchTick[channel] - value); - if (MixtrackProFX.scratchDirection[channel] !== null && MixtrackProFX.scratchDirection[channel] != direction && delta < 64) { - direction = !direction; - } - - if (direction) { - newValue = value; - } else { - newValue = value - 128; - } - - if (MixtrackProFX.searching[channel]) { - var position = engine.getValue(group, "playposition"); - - if (position <= 0) { - position = 0; - } - - if (position >= 1) { - position = 1; - } - - engine.setValue(group, "playposition", position + newValue / MixtrackProFX.jogSeekSensitivity); - MixtrackProFX.resetScratchTimer(channel, newValue); - - return; - } - - if (MixtrackProFX.scratchDirection[channel] === null) { - MixtrackProFX.scratchDirection[channel] = direction; - } else if (MixtrackProFX.scratchDirection[channel] != direction) { - if (!MixtrackProFX.touching[channel]) { - MixtrackProFX.scratchDisable(channel); - } - - MixtrackProFX.scratchAccumulator[channel] = 0; - } - - MixtrackProFX.lastScratchTick[channel] = value; - MixtrackProFX.scratchDirection[channel] = direction; - MixtrackProFX.scratchAccumulator[channel] += Math.abs(newValue); - - if (engine.isScratching(deckNumber)) { - engine.scratchTick(deckNumber, newValue); - MixtrackProFX.resetScratchTimer(channel, newValue); - } else if (MixtrackProFX.shifted) { - if (MixtrackProFX.scratchAccumulator[channel] > 61) { - MixtrackProFX.scratchAccumulator[channel] -= 61; - if (direction) { - engine.setParameter(group, "beatjump_1_forward", 1); - } else { - engine.setParameter(group, "beatjump_1_backward", 1); - } - } - } else { - engine.setValue(group, "jog", newValue / MixtrackProFX.jogPitchSensitivity); - } -}; - -MixtrackProFX.wheelTouch = function(channel, control, value, status, group) { - if (!MixtrackProFX.shifted && !MixtrackProFX.searching[channel] && !MixtrackProFX.scratchModeEnabled[channel] && value != 0) { - return; - } - - MixtrackProFX.touching[channel] = 0x7F == value; - - if (value === 0x7F && !MixtrackProFX.shifted && !MixtrackProFX.searching[channel]) { - MixtrackProFX.scratchEnable(channel); - } else if (value === 0x7F && (MixtrackProFX.shifted || MixtrackProFX.searching[channel])) { - MixtrackProFX.scratchDisable(channel); - MixtrackProFX.searching[channel] = true; - MixtrackProFX.stopScratchTimer(channel); - } else { - MixtrackProFX.startScratchTimer(channel); - } -};*/ - -// ==== SCRATCH B END ==== // From d83704b78fea59250929953065e549044946ee4d Mon Sep 17 00:00:00 2001 From: Sancho Date: Sun, 1 Aug 2021 21:12:14 +0200 Subject: [PATCH 13/52] simplify library knob scroll Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index ce60f6eab59..be57f4bd2b8 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -638,13 +638,9 @@ MixtrackProFX.Deck.prototype = new components.Deck(); MixtrackProFX.Browse = function() { this.knob = new components.Encoder({ group: "[Library]", - inKey: "Move", - input: function(channel, control, value) { - if (value === 0x01) { - engine.setParameter(this.group, this.inKey + "Down", 1); - } else if (value === 0x7F) { - engine.setParameter(this.group, this.inKey + "Up", 1); - } + inKey: "MoveVertical", + inValueScale: function(value) { + return (value > 0x40) ? value - 0x80 : value; } }); From e62584551449946b78403f9904397264e80fec04 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 20:12:56 +0200 Subject: [PATCH 14/52] removed incorrect powerWindow notes, simplified push buttons --- .../Numark-Mixtrack-Pro-FX-scripts.js | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index be57f4bd2b8..651b3eb6506 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -1,8 +1,3 @@ -// controls annotated with "powerWindow workaround" would normally use -// powerWindow as type. There's a problem - when pressing them and releasing -// them *quickly* makes them act like toggles, which is quite confusing. -// the workaround fixes this issue. - var MixtrackProFX = {}; // pitch ranges @@ -544,34 +539,16 @@ MixtrackProFX.Deck = function(number) { inKey: "loop_out" }); - // powerWindow workaround this.bleep = new components.Button({ - input: function(channel, control, value, status, group) { - if (value === 0x7F) { - value = 1; - } - engine.setValue(group, "reverseroll", value); - } + inKey: "reverseroll" }); - // powerWindow workaround this.pitchBendUp = new components.Button({ - input: function(channel, control, value, status, group) { - if (value === 0x7F) { - value = 1; - } - engine.setValue(group, "rate_temp_up", value); - } + inKey: "rate_temp_up" }); - // powerWindow workaround this.pitchBendDown = new components.Button({ - input: function(channel, control, value, status, group) { - if (value === 0x7F) { - value = 1; - } - engine.setValue(group, "rate_temp_down", value); - } + inKey: "rate_temp_down" }); this.keylock = new components.Button({ From bef370aac326f742d05c7669a75e5f73e3985c92 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 20:35:09 +0200 Subject: [PATCH 15/52] globally send 0x01 to buttons when inactive --- .../Numark-Mixtrack-Pro-FX-scripts.js | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 651b3eb6506..04c1285a8fd 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -1,3 +1,6 @@ +// dim all lights when inactive instead of turning them off +components.Button.prototype.off = 0x01; + var MixtrackProFX = {}; // pitch ranges @@ -131,8 +134,7 @@ MixtrackProFX.EffectUnit = function(unitNumber) { this.tap = new components.Button({ group: "[Channel" + this.unitNumber + "]", key: "bpm_tap", - midi: [0x88, 0x09], - off: 0x01 + midi: [0x88, 0x09] }); this.effectParam = new components.Encoder({ @@ -165,8 +167,7 @@ MixtrackProFX.Deck = function(number) { components.Deck.call(this, number); this.playButton = new components.PlayButton({ - midi: [0x90 + channel, 0x00], - off: 0x01 + midi: [0x90 + channel, 0x00] }); this.playButtonStutter = new components.Button({ @@ -174,8 +175,7 @@ MixtrackProFX.Deck = function(number) { }); this.cueButton = new components.CueButton({ - midi: [0x90 + channel, 0x01], - off: 0x01 + midi: [0x90 + channel, 0x01] }); this.cueButtonShift = new components.Button({ @@ -183,14 +183,12 @@ MixtrackProFX.Deck = function(number) { }); this.syncButton = new components.SyncButton({ - midi: [0x90 + channel, 0x02], - off: 0x01 + midi: [0x90 + channel, 0x02] }); this.pflButton = new components.Button({ type: components.Button.prototype.types.toggle, midi: [0x90 + channel, 0x1B], - off: 0x01, key: "pfl" }); @@ -247,7 +245,6 @@ MixtrackProFX.Deck = function(number) { midi: [0x94 + channel, 0x14 + i], inKey: "hotcue_" + (i + 1) + "_activate", outKey: "hotcue_" + (i + 1) + "_enabled", - off: 0x01, number: i, shift: function() { this.midi = [0x94 + channel, 0x1C + this.number]; @@ -505,7 +502,6 @@ MixtrackProFX.Deck = function(number) { this.loop = new components.Button({ key: "loop_enabled", midi: [0x94 + channel, 0x40], - off: 0x01, input: function(channel, control, value, status, group) { if (engine.getValue(group, "loop_enabled") === 0) { script.triggerControl(group, "beatloop_activate"); @@ -522,13 +518,11 @@ MixtrackProFX.Deck = function(number) { this.loopHalf = new components.Button({ key: "loop_halve", midi: [0x94 + channel, 0x34], - off: 0x01 }); this.loopDouble = new components.Button({ key: "loop_double", midi: [0x94 + channel, 0x35], - off: 0x01 }); this.loopIn = new components.Button({ @@ -568,7 +562,6 @@ MixtrackProFX.Deck = function(number) { group: "[EffectRack1_EffectUnit" + number + "_Effect1]", key: "prev_effect", midi: [0x98, channel*2], - off: 0x01, shift: function() { this.group = "[Channel" + number + "]"; this.inKey = "pitch_up"; @@ -585,7 +578,6 @@ MixtrackProFX.Deck = function(number) { group: "[EffectRack1_EffectUnit" + number + "_Effect1]", key: "next_effect", midi: [0x99, 0x03 + channel*2], - off: 0x01, shift: function() { this.group = "[Channel" + number + "]"; this.inKey = "pitch_down"; @@ -599,8 +591,7 @@ MixtrackProFX.Deck = function(number) { this.beatsnap = new components.Button({ type: components.Button.prototype.types.toggle, key: "quantize", - midi: [0x89, 0x04], - off: 0x01 + midi: [0x89, 0x04] }); this.reconnectComponents(function(component) { @@ -657,7 +648,6 @@ MixtrackProFX.Browse = function() { group: "[Channel1]", key: "beats_translate_curpos", midi: [0x88, 0x01], - off: 0x01, shift: function() { this.group = "[Channel2]"; }, From 2fad4d3f9dbb51accb52c40196a99fe4f5411894 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 20:51:51 +0200 Subject: [PATCH 16/52] removed unnecessary value conversion in FX enable switch --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 04c1285a8fd..e5acf2ce97c 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -119,9 +119,7 @@ MixtrackProFX.EffectUnit = function(unitNumber) { this.enableButton = new components.Button({ input: function(channel, control, value, status, group) { - if (value === 2) { - value = 1; - } + // note: value is 2 when the switch is held down (1 when up) engine.setValue(group, "enabled", value); } }); From 39870aa73c4fc53e0506dbcf6d87c1051f67a9b8 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 20:59:57 +0200 Subject: [PATCH 17/52] removed shift+load (load to preview deck), not very useful in current state --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index e5acf2ce97c..850c9ca5391 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -191,13 +191,7 @@ MixtrackProFX.Deck = function(number) { }); this.loadButton = new components.Button({ - inKey: "LoadSelectedTrack", - shift: function() { - this.group = "[PreviewDeck1]"; - }, - unshift: function() { - this.group = "[Channel" + (channel + 1) + "]"; - } + inKey: "LoadSelectedTrack" }); this.volume = new components.Pot({ From 7e13ad7fa99cc5bd2465838992d503cc828edfe4 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 21:34:26 +0200 Subject: [PATCH 18/52] renamed unitNumber -> deckNumber & enableButton -> enableSwitch --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 4 ++-- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index a7f056d82be..1c1d063882d 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -1564,7 +1564,7 @@ [EffectRack1_EffectUnit1_Effect1] - MixtrackProFX.effect[0].enableButton.input + MixtrackProFX.effect[0].enableSwitch.input 0xB8 0x03 @@ -1573,7 +1573,7 @@ [EffectRack1_EffectUnit2_Effect1] - MixtrackProFX.effect[1].enableButton.input + MixtrackProFX.effect[1].enableSwitch.input 0xB9 0x03 diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 850c9ca5391..b1588631480 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -113,11 +113,11 @@ MixtrackProFX.shutdown = function() { midi.sendSysexMsg(shutdownSysex, shutdownSysex.length); }; -MixtrackProFX.EffectUnit = function(unitNumber) { - this.unitNumber = unitNumber; - this.group = "[EffectRack1_EffectUnit" + unitNumber + "]"; +MixtrackProFX.EffectUnit = function(deckNumber) { + this.deckNumber = deckNumber; + this.group = "[EffectRack1_EffectUnit" + deckNumber + "]"; - this.enableButton = new components.Button({ + this.enableSwitch = new components.Button({ input: function(channel, control, value, status, group) { // note: value is 2 when the switch is held down (1 when up) engine.setValue(group, "enabled", value); @@ -130,13 +130,13 @@ MixtrackProFX.EffectUnit = function(unitNumber) { }); this.tap = new components.Button({ - group: "[Channel" + this.unitNumber + "]", + group: "[Channel" + this.deckNumber + "]", key: "bpm_tap", midi: [0x88, 0x09] }); this.effectParam = new components.Encoder({ - group: "[EffectRack1_EffectUnit" + unitNumber + "_Effect1]", + group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", inKey: "parameter1", shift: function() { this.inKey = "parameter2"; From a5a6a02a7adf35d1a5573b7ece214d18963accbb Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 22:38:51 +0200 Subject: [PATCH 19/52] allow scrolling backwards before track start --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index b1588631480..0bfeca7e9f7 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -708,14 +708,6 @@ MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { // seek var oldPos = engine.getValue(group, "playposition"); - if (oldPos <= 0) { - oldPos = 0; - } - - if (oldPos >= 1) { - oldPos = 1; - } - engine.setValue(group, "playposition", oldPos + newValue / MixtrackProFX.jogSeekSensitivity); } else if (MixtrackProFX.scratchModeEnabled[channel] && engine.isScratching(deckNumber)) { // scratch From 82f9ca2cec8a4858ea3194dcad130e341fd554ca Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 1 Aug 2021 23:19:05 +0200 Subject: [PATCH 20/52] moved fx switch buttons to effect unit --- .../Numark Mixtrack Pro FX.midi.xml | 16 ++--- .../Numark-Mixtrack-Pro-FX-scripts.js | 67 ++++++++++--------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 1c1d063882d..f9f42641173 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -1450,7 +1450,7 @@ [EffectRack1_EffectUnit1_Effect1] - MixtrackProFX.deck[0].prevEffect.input + MixtrackProFX.effect[0].prevEffect.input 0x98 0x00 @@ -1459,7 +1459,7 @@ [EffectRack1_EffectUnit1_Effect1] - MixtrackProFX.deck[0].prevEffect.input + MixtrackProFX.effect[0].prevEffect.input 0x88 0x00 @@ -1488,7 +1488,7 @@ [EffectRack1_EffectUnit2_Effect1] - MixtrackProFX.deck[1].prevEffect.input + MixtrackProFX.effect[1].prevEffect.input 0x98 0x02 @@ -1497,7 +1497,7 @@ [EffectRack1_EffectUnit2_Effect1] - MixtrackProFX.deck[1].prevEffect.input + MixtrackProFX.effect[1].prevEffect.input 0x88 0x02 @@ -1507,7 +1507,7 @@ [EffectRack1_EffectUnit1_Effect1] - MixtrackProFX.deck[0].nextEffect.input + MixtrackProFX.effect[0].nextEffect.input 0x99 0x03 @@ -1516,7 +1516,7 @@ [EffectRack1_EffectUnit1_Effect1] - MixtrackProFX.deck[0].nextEffect.input + MixtrackProFX.effect[0].nextEffect.input 0x89 0x03 @@ -1545,7 +1545,7 @@ [EffectRack1_EffectUnit2_Effect1] - MixtrackProFX.deck[1].nextEffect.input + MixtrackProFX.effect[1].nextEffect.input 0x99 0x05 @@ -1554,7 +1554,7 @@ [EffectRack1_EffectUnit2_Effect1] - MixtrackProFX.deck[1].nextEffect.input + MixtrackProFX.effect[1].nextEffect.input 0x89 0x05 diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 0bfeca7e9f7..a0ec4efb4cb 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -114,9 +114,12 @@ MixtrackProFX.shutdown = function() { }; MixtrackProFX.EffectUnit = function(deckNumber) { - this.deckNumber = deckNumber; this.group = "[EffectRack1_EffectUnit" + deckNumber + "]"; + // switch values are: + // 0 - switch in the middle + // 1 - switch up + // 2 - switch down this.enableSwitch = new components.Button({ input: function(channel, control, value, status, group) { // note: value is 2 when the switch is held down (1 when up) @@ -130,7 +133,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { }); this.tap = new components.Button({ - group: "[Channel" + this.deckNumber + "]", + group: "[Channel" + deckNumber + "]", key: "bpm_tap", midi: [0x88, 0x09] }); @@ -152,6 +155,36 @@ MixtrackProFX.EffectUnit = function(deckNumber) { } } }); + + this.prevEffect = new components.Button({ + group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", + key: "prev_effect", + midi: [0x98, (deckNumber - 1) * 2], + shift: function() { + this.group = "[Channel" + deckNumber + "]"; + this.inKey = "pitch_up"; + this.outKey = "pitch_up"; + }, + unshift: function() { + this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; + this.inKey = "prev_effect"; + this.outKey = "prev_effect"; + } + }); + + this.nextEffect = new components.Button({ + group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", + key: "next_effect", + midi: [0x99, 0x03 + (deckNumber - 1) * 2], + shift: function() { + this.group = "[Channel" + deckNumber + "]"; + this.inKey = "pitch_down"; + }, + unshift: function() { + this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; + this.inKey = "next_effect"; + } + }); }; MixtrackProFX.EffectUnit.prototype = new components.ComponentContainer(); @@ -550,36 +583,6 @@ MixtrackProFX.Deck = function(number) { } }); - this.prevEffect = new components.Button({ - group: "[EffectRack1_EffectUnit" + number + "_Effect1]", - key: "prev_effect", - midi: [0x98, channel*2], - shift: function() { - this.group = "[Channel" + number + "]"; - this.inKey = "pitch_up"; - this.outKey = "pitch_up"; - }, - unshift: function() { - this.group = "[EffectRack1_EffectUnit" + number + "_Effect1]"; - this.inKey = "prev_effect"; - this.outKey = "prev_effect"; - } - }); - - this.nextEffect = new components.Button({ - group: "[EffectRack1_EffectUnit" + number + "_Effect1]", - key: "next_effect", - midi: [0x99, 0x03 + channel*2], - shift: function() { - this.group = "[Channel" + number + "]"; - this.inKey = "pitch_down"; - }, - unshift: function() { - this.group = "[EffectRack1_EffectUnit" + number + "_Effect1]"; - this.inKey = "next_effect"; - } - }); - this.beatsnap = new components.Button({ type: components.Button.prototype.types.toggle, key: "quantize", From efb387ffb5521d621174eb57cda6fbee85aac334 Mon Sep 17 00:00:00 2001 From: Sancho Date: Mon, 2 Aug 2021 22:28:25 +0200 Subject: [PATCH 21/52] simplify vuCallback Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index a0ec4efb4cb..75d6408ee31 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -665,18 +665,8 @@ MixtrackProFX.HeadGain.prototype = new components.Pot({ MixtrackProFX.vuCallback = function(value, group) { var level = value * 90; - - if (engine.getValue("[Channel1]", "pfl") || engine.getValue("[Channel2]", "pfl")) { - if (group === "[Channel1]") { - midi.sendShortMsg(0xB0, 0x1F, level); - } else if (group === "[Channel2]") { - midi.sendShortMsg(0xB1, 0x1F, level); - } - } else if (group === "[Channel1]") { - midi.sendShortMsg(0xB0, 0x1F, level); - } else if (group === "[Channel2]") { - midi.sendShortMsg(0xB1, 0x1F, level); - } + var deckOffset = script.deckFromGroup(group) - 1; + midi.sendShortMsg(0xB0 + deckOffset, 0x1F, level); }; MixtrackProFX.scratchToggle = function(channel) { From 5b44a56525dd696c61121c6111362d01de57b1bf Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 2 Aug 2021 22:18:02 +0200 Subject: [PATCH 22/52] added comments explaining fader cuts feature --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 6 ++++-- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index f9f42641173..1e0f2905155 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -24,7 +24,8 @@ - + + [Master] crossfader @@ -34,7 +35,8 @@ - + + [Master] crossfader diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 75d6408ee31..891cc234293 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -356,7 +356,11 @@ MixtrackProFX.Deck = function(number) { } }); - // switch pad mode to fader cuts + // switch pad mode to "fader cuts" + // when pads are in "fader cuts" mode, they rapidly move the crossfader + // the feature is implemented in hardware or firmware + // holding a pad activates a "fader cut", releasing it causes the GUI crossfader + // to return to the position of physical crossfader this.modeFadercuts = new components.Button({ input: function(channel) { deck.blinkLedOff(); @@ -367,8 +371,6 @@ MixtrackProFX.Deck = function(number) { midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - // the "fader cuts" function is somehow burned into hardware - // need to set the pads to *something* to not trigger controls // triggered previously by the pads and not display their status (e.g. hotcue set) // nop would be really useful in this situation From afe1fa9524f190b75a980cb81402216b79f09101 Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 3 Aug 2021 02:03:51 +0200 Subject: [PATCH 23/52] added note-offs for all buttons --- .../Numark Mixtrack Pro FX.midi.xml | 533 ++++++++++++++++-- .../Numark-Mixtrack-Pro-FX-scripts.js | 45 +- 2 files changed, 508 insertions(+), 70 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 1e0f2905155..6ba5b6100a6 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -233,7 +233,7 @@ - + [Channel1] MixtrackProFX.deck[0].syncButton.input @@ -252,7 +252,26 @@ - + + + [Channel1] + MixtrackProFX.deck[0].syncButton.input + 0x80 + 0x03 + + + + + + [Channel2] + MixtrackProFX.deck[1].syncButton.input + 0x81 + 0x03 + + + + + [Channel1] MixtrackProFX.deck[0].cueButton.input @@ -271,6 +290,7 @@ + [Channel1] MixtrackProFX.deck[0].cueButton.input @@ -289,6 +309,7 @@ + [Channel1] MixtrackProFX.deck[0].cueButtonShift.input @@ -307,7 +328,26 @@ - + + + [Channel1] + MixtrackProFX.deck[0].cueButtonShift.input + 0x80 + 0x05 + + + + + + [Channel2] + MixtrackProFX.deck[1].cueButtonShift.input + 0x81 + 0x05 + + + + + [Channel1] MixtrackProFX.deck[0].playButton.input @@ -326,6 +366,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].playButton.input + 0x80 + 0x00 + + + + + + [Channel2] + MixtrackProFX.deck[1].playButton.input + 0x81 + 0x00 + + + + [Channel1] @@ -345,20 +404,30 @@ - + [Channel1] - MixtrackProFX.deck[0].shiftButton.input - 0x90 - 0x20 + MixtrackProFX.deck[0].playButtonStutter.input + 0x80 + 0x04 + + + + + + [Channel2] + MixtrackProFX.deck[1].playButtonStutter.input + 0x81 + 0x04 + [Channel1] MixtrackProFX.deck[0].shiftButton.input - 0x80 + 0x90 0x20 @@ -373,6 +442,16 @@ + + + [Channel1] + MixtrackProFX.deck[0].shiftButton.input + 0x80 + 0x20 + + + + [Channel2] MixtrackProFX.deck[1].shiftButton.input @@ -382,7 +461,7 @@ - + [Channel1] MixtrackProFX.scratchToggle @@ -401,20 +480,30 @@ - + [Channel1] - MixtrackProFX.deck[0].bleep.input - 0x90 - 0x08 + MixtrackProFX.scratchToggle + 0x80 + 0x07 + + + + + + [Channel2] + MixtrackProFX.scratchToggle + 0x81 + 0x07 + [Channel1] MixtrackProFX.deck[0].bleep.input - 0x80 + 0x90 0x08 @@ -429,6 +518,16 @@ + + + [Channel1] + MixtrackProFX.deck[0].bleep.input + 0x80 + 0x08 + + + + [Channel2] MixtrackProFX.deck[1].bleep.input @@ -438,7 +537,7 @@ - + [Channel1] MixtrackProFX.deck[0].modeHotcue.input @@ -511,6 +610,80 @@ + + + [Channel1] + MixtrackProFX.deck[0].modeHotcue.input + 0x84 + 0x00 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeHotcue.input + 0x85 + 0x00 + + + + + + [Channel1] + MixtrackProFX.deck[0].modeAutoloop.input + 0x84 + 0x0D + + + + + + [Channel2] + MixtrackProFX.deck[1].modeAutoloop.input + 0x85 + 0x0D + + + + + + [Channel1] + MixtrackProFX.deck[0].modeFadercuts.input + 0x84 + 0x07 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeFadercuts.input + 0x85 + 0x07 + + + + + + [Channel1] + MixtrackProFX.deck[0].modeSample.input + 0x84 + 0x0B + + + + + + [Channel2] + MixtrackProFX.deck[1].modeSample.input + 0x85 + 0x0B + + + + + [Channel1] MixtrackProFX.deck[0].modeSampleShift.input @@ -529,7 +702,7 @@ - + [Channel1] MixtrackProFX.deck[0].modeBeatjump.input 0x94 @@ -547,6 +720,43 @@ + + + [Channel1] + MixtrackProFX.deck[0].modeSampleShift.input + 0x84 + 0x0F + + + + + + [Channel2] + MixtrackProFX.deck[1].modeSampleShift.input + 0x85 + 0x0F + + + + + + [Channel1] + MixtrackProFX.deck[0].modeBeatjump.input + 0x84 + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].modeBeatjump.input + 0x85 + 0x02 + + + + [Channel1] @@ -1127,7 +1337,7 @@ - + [Channel1] MixtrackProFX.deck[0].loop.input @@ -1146,6 +1356,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].loop.input + 0x84 + 0x40 + + + + + + [Channel2] + MixtrackProFX.deck[1].loop.input + 0x85 + 0x40 + + + + [Channel1] @@ -1165,20 +1394,30 @@ - + [Channel1] - MixtrackProFX.deck[0].loopHalf.input - 0x94 - 0x34 + MixtrackProFX.deck[0].reloop.input + 0x84 + 0x41 + + + + + + [Channel2] + MixtrackProFX.deck[1].reloop.input + 0x85 + 0x41 + [Channel1] MixtrackProFX.deck[0].loopHalf.input - 0x84 + 0x94 0x34 @@ -1187,7 +1426,17 @@ [Channel2] MixtrackProFX.deck[1].loopHalf.input - 0x85 + 0x95 + 0x34 + + + + + + + [Channel1] + MixtrackProFX.deck[0].loopHalf.input + 0x84 0x34 @@ -1196,7 +1445,7 @@ [Channel2] MixtrackProFX.deck[1].loopHalf.input - 0x95 + 0x85 0x34 @@ -1221,20 +1470,30 @@ - + [Channel1] - MixtrackProFX.deck[0].loopDouble.input - 0x94 - 0x35 + MixtrackProFX.deck[0].loopIn.input + 0x84 + 0x36 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopIn.input + 0x85 + 0x36 + [Channel1] MixtrackProFX.deck[0].loopDouble.input - 0x84 + 0x94 0x35 @@ -1249,6 +1508,16 @@ + + + [Channel1] + MixtrackProFX.deck[0].loopDouble.input + 0x84 + 0x35 + + + + [Channel2] MixtrackProFX.deck[1].loopDouble.input @@ -1277,6 +1546,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].loopOut.input + 0x84 + 0x37 + + + + + + [Channel2] + MixtrackProFX.deck[1].loopOut.input + 0x85 + 0x37 + + + + [Channel1] @@ -1315,7 +1603,7 @@ - + [Library] MixtrackProFX.browse.knob.input @@ -1325,7 +1613,7 @@ - + [Library] MixtrackProFX.browse.knobShift.input @@ -1335,7 +1623,7 @@ - + [Library] MixtrackProFX.browse.knobButton.input @@ -1345,7 +1633,17 @@ - + + + [Library] + MixtrackProFX.browse.knobButton.input + 0x8F + 0x07 + + + + + [Library] MixtrackProFX.browse.buttonShift.input @@ -1355,7 +1653,17 @@ - + + + [Library] + MixtrackProFX.browse.buttonShift.input + 0x8F + 0x06 + + + + + [Channel1] MixtrackProFX.deck[0].loadButton.input @@ -1374,6 +1682,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].loadButton.input + 0x8F + 0x02 + + + + + + [Channel2] + MixtrackProFX.deck[1].loadButton.input + 0x8F + 0x03 + + + + [EffectRack1_EffectUnit1] @@ -1412,7 +1739,7 @@ - + [Channel1] MixtrackProFX.effect[0].tap.input @@ -1423,18 +1750,19 @@ - [Channel1] - MixtrackProFX.effect[0].tap.input - 0x88 + [Channel2] + MixtrackProFX.effect[1].tap.input + 0x99 0x09 + - [Channel2] - MixtrackProFX.effect[1].tap.input - 0x99 + [Channel1] + MixtrackProFX.effect[0].tap.input + 0x88 0x09 @@ -1449,7 +1777,7 @@ - + [EffectRack1_EffectUnit1_Effect1] MixtrackProFX.effect[0].prevEffect.input @@ -1459,6 +1787,7 @@ + [EffectRack1_EffectUnit1_Effect1] MixtrackProFX.effect[0].prevEffect.input @@ -1468,7 +1797,7 @@ - + [Library] MixtrackProFX.browse.setBeatgrid.input @@ -1478,6 +1807,7 @@ + [Library] MixtrackProFX.browse.setBeatgrid.input @@ -1487,7 +1817,7 @@ - + [EffectRack1_EffectUnit2_Effect1] MixtrackProFX.effect[1].prevEffect.input @@ -1497,6 +1827,7 @@ + [EffectRack1_EffectUnit2_Effect1] MixtrackProFX.effect[1].prevEffect.input @@ -1506,7 +1837,7 @@ - + [EffectRack1_EffectUnit1_Effect1] MixtrackProFX.effect[0].nextEffect.input @@ -1516,6 +1847,7 @@ + [EffectRack1_EffectUnit1_Effect1] MixtrackProFX.effect[0].nextEffect.input @@ -1525,7 +1857,7 @@ - + [Channel1] MixtrackProFX.deck[0].beatsnap.input @@ -1544,7 +1876,26 @@ - + + + [Channel1] + MixtrackProFX.deck[0].beatsnap.input + 0x89 + 0x04 + + + + + + [Channel2] + MixtrackProFX.deck[1].beatsnap.input + 0x89 + 0x04 + + + + + [EffectRack1_EffectUnit2_Effect1] MixtrackProFX.effect[1].nextEffect.input @@ -1554,6 +1905,7 @@ + [EffectRack1_EffectUnit2_Effect1] MixtrackProFX.effect[1].nextEffect.input @@ -1563,7 +1915,7 @@ - + [EffectRack1_EffectUnit1_Effect1] MixtrackProFX.effect[0].enableSwitch.input @@ -1582,7 +1934,7 @@ - + [Channel1] MixtrackProFX.deck[0].pflButton.input @@ -1601,6 +1953,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].pflButton.input + 0x80 + 0x1B + + + + + + [Channel2] + MixtrackProFX.deck[1].pflButton.input + 0x81 + 0x1B + + + + [Master] @@ -1621,7 +1992,7 @@ - + [Channel1] MixtrackProFX.deck[0].pitchBendDown.input @@ -1632,18 +2003,19 @@ - [Channel1] - MixtrackProFX.deck[0].pitchBendDown.input - 0x80 + [Channel2] + MixtrackProFX.deck[1].pitchBendDown.input + 0x91 0x0C + - [Channel2] - MixtrackProFX.deck[1].pitchBendDown.input - 0x91 + [Channel1] + MixtrackProFX.deck[0].pitchBendDown.input + 0x80 0x0C @@ -1677,20 +2049,30 @@ - + [Channel1] - MixtrackProFX.deck[0].pitchBendUp.input - 0x90 - 0x0B + MixtrackProFX.deck[0].pitchRange.input + 0x80 + 0x2C + + + + + + [Channel2] + MixtrackProFX.deck[1].pitchRange.input + 0x81 + 0x2C + [Channel1] MixtrackProFX.deck[0].pitchBendUp.input - 0x80 + 0x90 0x0B @@ -1705,6 +2087,16 @@ + + + [Channel1] + MixtrackProFX.deck[0].pitchBendUp.input + 0x80 + 0x0B + + + + [Channel2] MixtrackProFX.deck[1].pitchBendUp.input @@ -1733,6 +2125,25 @@ + + + [Channel1] + MixtrackProFX.deck[0].keylock.input + 0x80 + 0x2B + + + + + + [Channel2] + MixtrackProFX.deck[1].keylock.input + 0x81 + 0x2B + + + + diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 891cc234293..368d66d212b 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -287,7 +287,10 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to hotcue this.modeHotcue = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x7F); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop @@ -311,7 +314,10 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to auto loop this.modeAutoloop = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x7F); // auto loop @@ -362,7 +368,10 @@ MixtrackProFX.Deck = function(number) { // holding a pad activates a "fader cut", releasing it causes the GUI crossfader // to return to the position of physical crossfader this.modeFadercuts = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop @@ -386,7 +395,10 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to sampler this.modeSample = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } deck.blinkLedOff(); midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop @@ -410,7 +422,10 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to shifted sampler this.modeSampleShift = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts @@ -434,7 +449,10 @@ MixtrackProFX.Deck = function(number) { // switch pad mode to beatjump this.modeBeatjump = new components.Button({ - input: function(channel) { + input: function(channel, control, value) { + if (value !== 0x7F) { + return; + } midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts @@ -530,6 +548,9 @@ MixtrackProFX.Deck = function(number) { key: "loop_enabled", midi: [0x94 + channel, 0x40], input: function(channel, control, value, status, group) { + if (value !== 0x7F) { + return; + } if (engine.getValue(group, "loop_enabled") === 0) { script.triggerControl(group, "beatloop_activate"); } else { @@ -544,12 +565,12 @@ MixtrackProFX.Deck = function(number) { this.loopHalf = new components.Button({ key: "loop_halve", - midi: [0x94 + channel, 0x34], + midi: [0x94 + channel, 0x34] }); this.loopDouble = new components.Button({ key: "loop_double", - midi: [0x94 + channel, 0x35], + midi: [0x94 + channel, 0x35] }); this.loopIn = new components.Button({ @@ -580,6 +601,9 @@ MixtrackProFX.Deck = function(number) { this.pitchRange = new components.Button({ currentRangeIdx: 0, input: function(channel, control, value, status, group) { + if (value !== 0x7F) { + return; + } this.currentRangeIdx = (this.currentRangeIdx + 1) % MixtrackProFX.pitchRanges.length; engine.setValue(group, "rateRange", MixtrackProFX.pitchRanges[this.currentRangeIdx]); } @@ -671,7 +695,10 @@ MixtrackProFX.vuCallback = function(value, group) { midi.sendShortMsg(0xB0 + deckOffset, 0x1F, level); }; -MixtrackProFX.scratchToggle = function(channel) { +MixtrackProFX.scratchToggle = function(channel, control, value) { + if (value !== 0x7F) { + return; + } MixtrackProFX.scratchModeEnabled[channel] = !MixtrackProFX.scratchModeEnabled[channel]; midi.sendShortMsg(0x90 | channel, 0x07, MixtrackProFX.scratchModeEnabled[channel] ? 0x7F : 0x01); }; From 59ff1ffb94e2c61bfdeeea33f0e1fe30f66295a3 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 5 Aug 2021 11:44:42 +0200 Subject: [PATCH 24/52] added TODO to change FX selection in future version of Mixxx --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 368d66d212b..4b7482f7b1f 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -113,6 +113,9 @@ MixtrackProFX.shutdown = function() { midi.sendSysexMsg(shutdownSysex, shutdownSysex.length); }; +// TODO in 2.3 it is not possible to "properly" map the FX selection buttons. +// this should be done with load_preset and QuickEffects instead (when effect +// chain preset saving/loading is available in Mixxx) MixtrackProFX.EffectUnit = function(deckNumber) { this.group = "[EffectRack1_EffectUnit" + deckNumber + "]"; From 2cf356074cd5c65d50db21ef5139cb33641c625e Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 6 Aug 2021 00:34:09 +0200 Subject: [PATCH 25/52] redesigned pad section using switching componentContainers --- .../Numark Mixtrack Pro FX.midi.xml | 208 +++---- .../Numark-Mixtrack-Pro-FX-scripts.js | 553 +++++++++--------- 2 files changed, 398 insertions(+), 363 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 6ba5b6100a6..3b81f3098f5 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -538,9 +538,10 @@ + [Channel1] - MixtrackProFX.deck[0].modeHotcue.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 0x00 @@ -549,16 +550,17 @@ [Channel2] - MixtrackProFX.deck[1].modeHotcue.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 0x00 + [Channel1] - MixtrackProFX.deck[0].modeAutoloop.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 0x0D @@ -567,16 +569,17 @@ [Channel2] - MixtrackProFX.deck[1].modeAutoloop.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 0x0D + [Channel1] - MixtrackProFX.deck[0].modeFadercuts.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 0x07 @@ -585,16 +588,17 @@ [Channel2] - MixtrackProFX.deck[1].modeFadercuts.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 0x07 + [Channel1] - MixtrackProFX.deck[0].modeSample.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 0x0B @@ -603,7 +607,7 @@ [Channel2] - MixtrackProFX.deck[1].modeSample.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 0x0B @@ -611,9 +615,10 @@ + [Channel1] - MixtrackProFX.deck[0].modeHotcue.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 0x00 @@ -622,16 +627,17 @@ [Channel2] - MixtrackProFX.deck[1].modeHotcue.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 0x00 + [Channel1] - MixtrackProFX.deck[0].modeAutoloop.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 0x0D @@ -640,16 +646,17 @@ [Channel2] - MixtrackProFX.deck[1].modeAutoloop.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 0x0D + [Channel1] - MixtrackProFX.deck[0].modeFadercuts.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 0x07 @@ -658,16 +665,17 @@ [Channel2] - MixtrackProFX.deck[1].modeFadercuts.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 0x07 + [Channel1] - MixtrackProFX.deck[0].modeSample.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 0x0B @@ -676,7 +684,7 @@ [Channel2] - MixtrackProFX.deck[1].modeSample.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 0x0B @@ -684,75 +692,79 @@ + [Channel1] - MixtrackProFX.deck[0].modeSampleShift.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 - 0x0F + 0x02 [Channel2] - MixtrackProFX.deck[1].modeSampleShift.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 - 0x0F + 0x02 - + + [Channel1] - MixtrackProFX.deck[0].modeBeatjump.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x94 - 0x02 + 0x0F [Channel2] - MixtrackProFX.deck[1].modeBeatjump.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x95 - 0x02 + 0x0F + [Channel1] - MixtrackProFX.deck[0].modeSampleShift.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 - 0x0F + 0x02 [Channel2] - MixtrackProFX.deck[1].modeSampleShift.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 - 0x0F + 0x02 - + + [Channel1] - MixtrackProFX.deck[0].modeBeatjump.input + MixtrackProFX.deck[0].padSection.modeButtonPress 0x84 - 0x02 + 0x0F [Channel2] - MixtrackProFX.deck[1].modeBeatjump.input + MixtrackProFX.deck[1].padSection.modeButtonPress 0x85 - 0x02 + 0x0F @@ -760,7 +772,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[0].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x14 @@ -769,7 +781,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[0].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x14 @@ -778,7 +790,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[1].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x15 @@ -787,7 +799,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[1].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x15 @@ -796,7 +808,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[2].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x16 @@ -805,7 +817,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[2].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x16 @@ -814,7 +826,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[3].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x17 @@ -823,7 +835,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[3].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x17 @@ -832,7 +844,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[4].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x18 @@ -841,7 +853,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[4].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x18 @@ -850,7 +862,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[5].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x19 @@ -859,7 +871,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[5].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x19 @@ -868,7 +880,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[6].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1A @@ -877,7 +889,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[6].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1A @@ -886,7 +898,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[7].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1B @@ -895,7 +907,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[7].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1B @@ -905,7 +917,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[0].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x14 @@ -914,7 +926,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[0].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x14 @@ -923,7 +935,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[1].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x15 @@ -932,7 +944,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[1].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x15 @@ -941,7 +953,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[2].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x16 @@ -950,7 +962,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[2].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x16 @@ -959,7 +971,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[3].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x17 @@ -968,7 +980,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[3].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x17 @@ -977,7 +989,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[4].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x18 @@ -986,7 +998,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[4].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x18 @@ -995,7 +1007,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[5].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x19 @@ -1004,7 +1016,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[5].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x19 @@ -1013,7 +1025,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[6].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1A @@ -1022,7 +1034,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[6].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1A @@ -1031,7 +1043,7 @@ [Channel1] - MixtrackProFX.deck[0].pads[7].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1B @@ -1040,7 +1052,7 @@ [Channel2] - MixtrackProFX.deck[1].pads[7].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1B @@ -1050,7 +1062,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[0].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1C @@ -1059,7 +1071,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[0].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1C @@ -1068,7 +1080,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[1].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1D @@ -1077,7 +1089,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[1].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1D @@ -1086,7 +1098,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[2].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1E @@ -1095,7 +1107,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[2].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1E @@ -1104,7 +1116,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[3].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x1F @@ -1113,7 +1125,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[3].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x1F @@ -1122,7 +1134,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[4].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x20 @@ -1131,7 +1143,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[4].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x20 @@ -1140,7 +1152,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[5].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x21 @@ -1149,7 +1161,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[5].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x21 @@ -1158,7 +1170,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[6].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x22 @@ -1167,7 +1179,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[6].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x22 @@ -1176,7 +1188,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[7].input + MixtrackProFX.deck[0].padSection.padPress 0x94 0x23 @@ -1185,7 +1197,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[7].input + MixtrackProFX.deck[1].padSection.padPress 0x95 0x23 @@ -1195,7 +1207,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[0].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1C @@ -1204,7 +1216,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[0].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1C @@ -1213,7 +1225,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[1].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1D @@ -1222,7 +1234,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[1].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1D @@ -1231,7 +1243,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[2].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1E @@ -1240,7 +1252,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[2].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1E @@ -1249,7 +1261,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[3].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x1F @@ -1258,7 +1270,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[3].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x1F @@ -1267,7 +1279,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[4].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x20 @@ -1276,7 +1288,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[4].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x20 @@ -1285,7 +1297,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[5].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x21 @@ -1294,7 +1306,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[5].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x21 @@ -1303,7 +1315,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[6].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x22 @@ -1312,7 +1324,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[6].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x22 @@ -1321,7 +1333,7 @@ [Channel1] - MixtrackProFX.deck[0].padsShift[7].input + MixtrackProFX.deck[0].padSection.padPress 0x84 0x23 @@ -1330,7 +1342,7 @@ [Channel2] - MixtrackProFX.deck[1].padsShift[7].input + MixtrackProFX.deck[1].padSection.padPress 0x85 0x23 diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 4b7482f7b1f..0f31e9024b0 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -24,6 +24,44 @@ MixtrackProFX.jogSeekSensitivity = 10000; MixtrackProFX.enableBlink = true; MixtrackProFX.blinkDelay = 700; +// autoloop sizes, for available values see: +// https://manual.mixxx.org/2.3/en/chapters/appendix/mixxx_controls.html#control-[ChannelN]-beatloop_X_toggle +MixtrackProFX.autoLoopSizes = [ + "0.0625", + "0.125", + "0.25", + "0.5", + "1", + "2", + "4", + "8" +]; + +// beatjump values, for available values see: +// https://manual.mixxx.org/2.3/en/chapters/appendix/mixxx_controls.html#control-[ChannelN]-beatjump_X_forward +// underscores (_) at the end are needed because numeric values (e.g. 8) have two underscores (e.g. beatjump_8_forward), +// but "beatjump_forward"/"beatjump_backward" have only one underscore +MixtrackProFX.beatJumpValues = [ + "0.0625_", + "0.125_", + "0.25_", + "0.5_", + "1_", + "2_", + "", // "beatjump_forward"/"beatjump_backward" - jump by the value selected in Mixxx GUI (4 by default) + "8_" +]; + +// pad modes, don't touch +MixtrackProFX.PadModeControls = { + HOTCUE: 0x00, + AUTOLOOP: 0x0D, + FADERCUTS: 0x07, + SAMPLE1: 0x0B, + BEATJUMP: 0x02, + SAMPLE2: 0x0F +}; + // state variables, don't touch MixtrackProFX.shifted = false; MixtrackProFX.scratchModeEnabled = [true, true]; @@ -106,6 +144,9 @@ MixtrackProFX.init = function() { engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); + + MixtrackProFX.deck.reconnectComponents(); + MixtrackProFX.effect.reconnectComponents(); }; MixtrackProFX.shutdown = function() { @@ -193,10 +234,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { MixtrackProFX.EffectUnit.prototype = new components.ComponentContainer(); MixtrackProFX.Deck = function(number) { - var deck = this; var channel = number - 1; - var blinkTimer = 0; - var blinkLedState = true; components.Deck.call(this, number); @@ -264,264 +302,7 @@ MixtrackProFX.Deck = function(number) { invert: true }); - this.pads = new components.ComponentContainer(); - this.padsShift = new components.ComponentContainer(); - - for (var i = 0; i < 8; i++) { - this.pads[i] = new components.Button({ - group: this.currentDeck, - midi: [0x94 + channel, 0x14 + i], - inKey: "hotcue_" + (i + 1) + "_activate", - outKey: "hotcue_" + (i + 1) + "_enabled", - number: i, - shift: function() { - this.midi = [0x94 + channel, 0x1C + this.number]; - }, - unshift: function() { - this.midi = [0x94 + channel, 0x14 + this.number]; - } - }); - - this.padsShift[i] = new components.Button({ - group: this.currentDeck, - inKey: "hotcue_" + (i + 1) + "_clear" - }); - } - - // switch pad mode to hotcue - this.modeHotcue = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - deck.blinkLedOff(); - midi.sendShortMsg(0x90 + channel, 0x00, 0x7F); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - - for (var i = 0; i < 8; i++) { - deck.pads[i].group = deck.currentDeck; - deck.pads[i].inKey = "hotcue_" + (i + 1) + "_activate"; - deck.pads[i].outKey = "hotcue_" + (i + 1) + "_enabled"; - - deck.padsShift[i].group = deck.currentDeck; - deck.padsShift[i].inKey = "hotcue_" + (i + 1) + "_clear"; - } - - deck.pads.reconnectComponents(); - } - }); - - // switch pad mode to auto loop - this.modeAutoloop = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - deck.blinkLedOff(); - midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x7F); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - - // this is just sad - deck.pads[0].inKey = "beatloop_0.0625_toggle"; - deck.pads[0].outKey = "beatloop_0.0625_enabled"; - deck.pads[1].inKey = "beatloop_0.125_toggle"; - deck.pads[1].outKey = "beatloop_0.125_enabled"; - deck.pads[2].inKey = "beatloop_0.25_toggle"; - deck.pads[2].outKey = "beatloop_0.25_enabled"; - deck.pads[3].inKey = "beatloop_0.5_toggle"; - deck.pads[3].outKey = "beatloop_0.5_enabled"; - deck.pads[4].inKey = "beatloop_1_toggle"; - deck.pads[4].outKey = "beatloop_1_enabled"; - deck.pads[5].inKey = "beatloop_2_toggle"; - deck.pads[5].outKey = "beatloop_2_enabled"; - deck.pads[6].inKey = "beatloop_4_toggle"; - deck.pads[6].outKey = "beatloop_4_enabled"; - deck.pads[7].inKey = "beatloop_8_toggle"; - deck.pads[7].outKey = "beatloop_8_enabled"; - - deck.padsShift[0].inKey = "beatlooproll_0.0625_activate"; - deck.padsShift[1].inKey = "beatlooproll_0.125_activate"; - deck.padsShift[2].inKey = "beatlooproll_0.25_activate"; - deck.padsShift[3].inKey = "beatlooproll_0.5_activate"; - deck.padsShift[4].inKey = "beatlooproll_1_activate"; - deck.padsShift[5].inKey = "beatlooproll_2_activate"; - deck.padsShift[6].inKey = "beatlooproll_4_activate"; - deck.padsShift[7].inKey = "beatlooproll_8_activate"; - - for (var i = 0; i < 8; i++) { - deck.pads[i].group = deck.currentDeck; - deck.padsShift[i].group = deck.currentDeck; - } - - deck.pads.reconnectComponents(); - } - }); - - // switch pad mode to "fader cuts" - // when pads are in "fader cuts" mode, they rapidly move the crossfader - // the feature is implemented in hardware or firmware - // holding a pad activates a "fader cut", releasing it causes the GUI crossfader - // to return to the position of physical crossfader - this.modeFadercuts = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - deck.blinkLedOff(); - midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x09); // fader cuts (0x09 works better than 0x7F for some reason) - midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - - // need to set the pads to *something* to not trigger controls - // triggered previously by the pads and not display their status (e.g. hotcue set) - // nop would be really useful in this situation - // we can assume channel 4 is unused and therefore won't mess anything up - for (var i = 0; i < 8; i++) { - deck.pads[i].group = "[Channel4]"; - deck.padsShift[i].group = "[Channel4]"; - } - - deck.pads.reconnectComponents(); - } - }); - - // switch pad mode to sampler - this.modeSample = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - deck.blinkLedOff(); - midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x90 + channel, 0x0B, 0x7F); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - - for (var i = 0; i < 8; i++) { - deck.pads[i].group = "[Sampler" + (i + 1) + "]"; - deck.pads[i].inKey = "cue_gotoandplay"; - deck.pads[i].outKey = "play"; - - deck.padsShift[i].group = "[Sampler" + (i + 1) + "]"; - deck.padsShift[i].inKey = "start_stop"; - } - - deck.pads.reconnectComponents(); - } - }); - - // switch pad mode to shifted sampler - this.modeSampleShift = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x7F); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x01); // beatjump - deck.blinkLedOn(0x90 + channel, 0x0B); // blink sample - - for (var i = 0; i < 8; i++) { - deck.pads[i].group = "[Sampler" + (i + 9) + "]"; - deck.pads[i].inKey = "cue_gotoandplay"; - deck.pads[i].outKey = "play"; - - deck.padsShift[i].group = "[Sampler" + (i + 9) + "]"; - deck.padsShift[i].inKey = "start_stop"; - } - - deck.pads.reconnectComponents(); - } - }); - - // switch pad mode to beatjump - this.modeBeatjump = new components.Button({ - input: function(channel, control, value) { - if (value !== 0x7F) { - return; - } - midi.sendShortMsg(0x90 + channel, 0x00, 0x01); // hotcue - midi.sendShortMsg(0x90 + channel, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x90 + channel, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x90 + channel, 0x0B, 0x01); // sample - midi.sendShortMsg(0x90 + channel, 0x0F, 0x01); // sample shifted - midi.sendShortMsg(0x90 + channel, 0x02, 0x7F); // beatjump - deck.blinkLedOn(0x90 + channel, 0x00); // blink hotcue - - deck.pads[0].inKey = "beatjump_0.0625_forward"; - deck.pads[0].outKey = "beatjump_0.0625_forward"; - deck.pads[1].inKey = "beatjump_0.125_forward"; - deck.pads[1].outKey = "beatjump_0.125_forward"; - deck.pads[2].inKey = "beatjump_0.25_forward"; - deck.pads[2].outKey = "beatjump_0.25_forward"; - deck.pads[3].inKey = "beatjump_0.5_forward"; - deck.pads[3].outKey = "beatjump_0.5_forward"; - deck.pads[4].inKey = "beatjump_1_forward"; - deck.pads[4].outKey = "beatjump_1_forward"; - deck.pads[5].inKey = "beatjump_2_forward"; - deck.pads[5].outKey = "beatjump_2_forward"; - deck.pads[6].inKey = "beatjump_forward"; // this button is adjustable, it uses the value set in the interface (4 by default) - deck.pads[6].outKey = "beatjump_forward"; - deck.pads[7].inKey = "beatjump_8_forward"; - deck.pads[7].outKey = "beatjump_8_forward"; - - deck.padsShift[0].inKey = "beatjump_0.0625_backward"; - deck.padsShift[1].inKey = "beatjump_0.125_backward"; - deck.padsShift[2].inKey = "beatjump_0.25_backward"; - deck.padsShift[3].inKey = "beatjump_0.5_backward"; - deck.padsShift[4].inKey = "beatjump_1_backward"; - deck.padsShift[5].inKey = "beatjump_2_backward"; - deck.padsShift[6].inKey = "beatjump_backward"; // this button is adjustable, it uses the value set in the interface (4 by default) - deck.padsShift[7].inKey = "beatjump_8_backward"; - - for (var i = 0; i < 8; i++) { - deck.pads[i].group = deck.currentDeck; - deck.padsShift[i].group = deck.currentDeck; - } - - deck.pads.reconnectComponents(); - } - }); - - // start an infinite timer that toggles led state - this.blinkLedOn = function(midi1, midi2) { - if (!MixtrackProFX.enableBlink) { - return; - } - - deck.blinkLedOff(); - blinkLedState = true; - blinkTimer = engine.beginTimer(MixtrackProFX.blinkDelay, function() { - midi.sendShortMsg(midi1, midi2, blinkLedState ? 0x7F : 0x01); - blinkLedState = !blinkLedState; - }); - }; - - // stop the blink timer - this.blinkLedOff = function() { - if (!MixtrackProFX.enableBlink || blinkTimer === 0) { - return; - } - - engine.stopTimer(blinkTimer); - blinkTimer = 0; - }; + this.padSection = new MixtrackProFX.PadSection(number); this.shiftButton = new components.Button({ input: function(channel, control, value) { @@ -540,10 +321,6 @@ MixtrackProFX.Deck = function(number) { MixtrackProFX.browse.unshift(); MixtrackProFX.effect.unshift(); } - - // for displaying pads lights when shifted - MixtrackProFX.deck[0].pads.reconnectComponents(); - MixtrackProFX.deck[1].pads.reconnectComponents(); } }); @@ -627,6 +404,252 @@ MixtrackProFX.Deck = function(number) { MixtrackProFX.Deck.prototype = new components.Deck(); +MixtrackProFX.PadSection = function(deckNumber) { + components.ComponentContainer.call(this); + + this.blinkTimer = 0; + this.blinkLedState = true; + + this.modes = {}; + this.modes[MixtrackProFX.PadModeControls.HOTCUE] = new MixtrackProFX.ModeHotcue(deckNumber); + this.modes[MixtrackProFX.PadModeControls.AUTOLOOP] = new MixtrackProFX.ModeAutoLoop(deckNumber); + this.modes[MixtrackProFX.PadModeControls.FADERCUTS] = new MixtrackProFX.ModeFaderCuts(); + this.modes[MixtrackProFX.PadModeControls.SAMPLE1] = new MixtrackProFX.ModeSample(deckNumber, false); + this.modes[MixtrackProFX.PadModeControls.BEATJUMP] = new MixtrackProFX.ModeBeatjump(deckNumber); + this.modes[MixtrackProFX.PadModeControls.SAMPLE2] = new MixtrackProFX.ModeSample(deckNumber, true); + + this.modeButtonPress = function(channel, control, value) { + if (value !== 0x7F) { + return; + } + this.setMode(channel, control); + }; + + this.padPress = function(channel, control, value, status, group) { + if (this.currentMode.control === MixtrackProFX.PadModeControls.FADERCUTS) { + // don't activate pads when in "fader cuts" mode - handled by hardware of firmware + return; + } + var i = (control - 0x14) % 8; + this.currentMode.pads[i].input(channel, control, value, status, group); + }; + + this.setMode = function(channel, control) { + var newMode = this.modes[control]; + if (this.currentMode.control === newMode.control) { + return; // selected mode already set, no need to change anything + } + + this.currentMode.forEachComponent(function(component) { + component.disconnect(); + }); + + // set the correct shift state for new mode + if (this.isShifted) { + newMode.shift(); + } else { + newMode.unshift(); + } + + newMode.forEachComponent(function(component) { + component.connect(); + component.trigger(); + }); + + if (MixtrackProFX.enableBlink) { + // stop blinking if old mode was secondary mode + if (this.currentMode.secondaryMode) { + this.blinkLedOff(); + + // disable light on the old control in case it ended up in 0x7F state + midi.sendShortMsg(0x90 + channel, this.currentMode.unshiftedControl, 0x01); + } + + // start blinking if new mode is a secondary mode + if (newMode.secondaryMode) { + this.blinkLedOn(0x90 + channel, newMode.unshiftedControl); + } + } + + // light off on old mode select button + midi.sendShortMsg(0x90 + channel, this.currentMode.control, 0x01); + + // light on on new mode select button + midi.sendShortMsg(0x90 + channel, newMode.control, newMode.lightOnValue); + + if (newMode.control === MixtrackProFX.PadModeControls.FADERCUTS) { + // in "fader cuts" mode pad lights need to be disabled manually, + // as pads are controlled by hardware or firmware in this mode + // and don't have associated controls. without this, lights from + // previously selected mode would still be on after changing mode + // to "fader cuts" + this.disablePadLights(); + } + + this.currentMode = newMode; + }; + + // start an infinite timer that toggles led state + this.blinkLedOn = function(midi1, midi2) { + this.blinkLedOff(); + this.blinkLedState = true; + this.blinkTimer = engine.beginTimer(MixtrackProFX.blinkDelay, function() { + midi.sendShortMsg(midi1, midi2, this.blinkLedState ? 0x7F : 0x01); + this.blinkLedState = !this.blinkLedState; + }); + }; + + // stop the blink timer + this.blinkLedOff = function() { + if (this.blinkTimer === 0) { + return; + } + + engine.stopTimer(this.blinkTimer); + this.blinkTimer = 0; + }; + + this.disablePadLights = function() { + for (var i = 0; i < 16; i++) { // 0-7 = unshifted; 8-15 = shifted + midi.sendShortMsg(0x93 + deckNumber, 0x14 + i, 0x01); + } + }; + + this.currentMode = this.modes[MixtrackProFX.PadModeControls.HOTCUE]; +}; +MixtrackProFX.PadSection.prototype = Object.create(components.ComponentContainer.prototype); + +MixtrackProFX.ModeHotcue = function(deckNumber) { + components.ComponentContainer.call(this); + + this.control = MixtrackProFX.PadModeControls.HOTCUE; + this.secondaryMode = false; + this.lightOnValue = 0x7F; + + this.pads = new components.ComponentContainer(); + for (var i = 0; i < 8; i++) { + this.pads[i] = new components.HotcueButton({ + group: "[Channel" + deckNumber + "]", + midi: [0x93 + deckNumber, 0x14 + i], + number: i + 1, + shiftControl: true, + sendShifted: true, + shiftOffset: 0x08, + outConnect: false + }); + } +}; +MixtrackProFX.ModeHotcue.prototype = Object.create(components.ComponentContainer.prototype); + +MixtrackProFX.ModeAutoLoop = function(deckNumber) { + components.ComponentContainer.call(this); + + this.control = MixtrackProFX.PadModeControls.AUTOLOOP; + this.secondaryMode = false; + this.lightOnValue = 0x7F; + + this.pads = new components.ComponentContainer(); + for (var i = 0; i < 8; i++) { + this.pads[i] = new components.Button({ + group: "[Channel" + deckNumber + "]", + inKey: "beatloop_" + this.size + "_toggle", + outKey: "beatloop_" + this.size + "_enabled", + midi: [0x93 + deckNumber, 0x14 + i], + size: MixtrackProFX.autoLoopSizes[i], + shiftControl: true, + sendShifted: true, + shiftOffset: 0x08, + shift: function() { + this.inKey = "beatlooproll_" + this.size + "_activate"; + this.outKey = "beatlooproll_" + this.size + "_activate"; + }, + unshift: function() { + this.inKey = "beatloop_" + this.size + "_toggle"; + this.outKey = "beatloop_" + this.size + "_enabled"; + }, + outConnect: false + }); + } +}; +MixtrackProFX.ModeAutoLoop.prototype = Object.create(components.ComponentContainer.prototype); + +// when pads are in "fader cuts" mode, they rapidly move the crossfader. +// holding a pad activates a "fader cut", releasing it causes the GUI crossfader +// to return to the position of physical crossfader +MixtrackProFX.ModeFaderCuts = function() { + components.ComponentContainer.call(this); + + this.control = MixtrackProFX.PadModeControls.FADERCUTS; + this.secondaryMode = false; + this.lightOnValue = 0x09; // for "fader cuts" 0x09 works better than 0x7F for some reason + + // pads are controlled by hardware of firmware in this mode + // pad input function is not called when pressing a pad in this mode +}; +MixtrackProFX.ModeFaderCuts.prototype = Object.create(components.ComponentContainer.prototype); + +MixtrackProFX.ModeSample = function(deckNumber, secondaryMode) { + components.ComponentContainer.call(this); + + if (!secondaryMode) { + // samples 1-8 + this.control = MixtrackProFX.PadModeControls.SAMPLE1; + this.firstSampleNumber = 1; + } else { + // samples 9-16 + this.control = MixtrackProFX.PadModeControls.SAMPLE2; + this.unshiftedControl = MixtrackProFX.PadModeControls.SAMPLE1; + this.firstSampleNumber = 9; + } + this.secondaryMode = secondaryMode; + this.lightOnValue = 0x7F; + + this.pads = new components.ComponentContainer(); + for (var i = 0; i < 8; i++) { + this.pads[i] = new components.SamplerButton({ + midi: [0x93 + deckNumber, 0x14 + i], + number: this.firstSampleNumber + i, + shiftControl: true, + sendShifted: true, + shiftOffset: 0x08, + outConnect: false + }); + } +}; +MixtrackProFX.ModeSample.prototype = Object.create(components.ComponentContainer.prototype); + +MixtrackProFX.ModeBeatjump = function(deckNumber) { + components.ComponentContainer.call(this); + + this.control = MixtrackProFX.PadModeControls.BEATJUMP; + this.secondaryMode = true; + this.unshiftedControl = MixtrackProFX.PadModeControls.HOTCUE; + this.lightOnValue = 0x7F; + + this.pads = new components.ComponentContainer(); + for (var i = 0; i < 8; i++) { + this.pads[i] = new components.Button({ + group: "[Channel" + deckNumber + "]", + key: "beatjump_" + this.size + "forward", + midi: [0x93 + deckNumber, 0x14 + i], + size: MixtrackProFX.beatJumpValues[i], + shiftControl: true, + sendShifted: true, + shiftOffset: 0x08, + shift: function() { + this.inKey = "beatjump_" + this.size + "backward"; + this.outKey = "beatjump_" + this.size + "backward"; + }, + unshift: function() { + this.inKey = "beatjump_" + this.size + "forward"; + this.outKey = "beatjump_" + this.size + "forward"; + }, + outConnect: false + }); + } +}; +MixtrackProFX.ModeBeatjump.prototype = Object.create(components.ComponentContainer.prototype); + MixtrackProFX.Browse = function() { this.knob = new components.Encoder({ group: "[Library]", From 7751cc22854321c663649dd6dffa772d646a0a99 Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 6 Aug 2021 01:07:49 +0200 Subject: [PATCH 26/52] simplified cueGain control, added js controls for cueMix and main gain --- .../Numark Mixtrack Pro FX.midi.xml | 12 ++++----- .../Numark-Mixtrack-Pro-FX-scripts.js | 26 ++++++++++++------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 3b81f3098f5..d2fc94ca66a 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -14,14 +14,14 @@ - + [Master] - gain + MixtrackProFX.gains.mainGain.input 0xBE 0x23 - + @@ -1987,7 +1987,7 @@ [Master] - MixtrackProFX.headGain.input + MixtrackProFX.gains.cueGain.input 0xBE 0x2F @@ -1997,11 +1997,11 @@ [Master] - headMix + MixtrackProFX.gains.cueMix.input 0xBE 0x27 - + diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 0f31e9024b0..74ba005b947 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -78,7 +78,7 @@ MixtrackProFX.init = function() { MixtrackProFX.deck[1] = new MixtrackProFX.Deck(2); MixtrackProFX.browse = new MixtrackProFX.Browse(); - MixtrackProFX.headGain = new MixtrackProFX.HeadGain(); + MixtrackProFX.gains = new MixtrackProFX.Gains(); var exitDemoSysex = [0xF0, 0x7E, 0x00, 0x06, 0x01, 0xF7]; midi.sendSysexMsg(exitDemoSysex, exitDemoSysex.length); @@ -703,17 +703,25 @@ MixtrackProFX.Browse = function() { } }); }; - MixtrackProFX.Browse.prototype = new components.ComponentContainer(); -MixtrackProFX.HeadGain = function() { - components.Pot.call(this); -}; +MixtrackProFX.Gains = function() { + this.mainGain = new components.Pot({ + group: "[Master]", + inKey: "gain" + }); -MixtrackProFX.HeadGain.prototype = new components.Pot({ - group: "[Master]", - inKey: "headGain" -}); + this.cueGain = new components.Pot({ + group: "[Master]", + inKey: "headGain" + }); + + this.cueMix = new components.Pot({ + group: "[Master]", + inKey: "headMix" + }); +}; +MixtrackProFX.Gains.prototype = new components.ComponentContainer(); MixtrackProFX.vuCallback = function(value, group) { var level = value * 90; From e9d24bbf1f5d8ddd97f2fcedf919f775d0652576 Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 6 Aug 2021 02:19:35 +0200 Subject: [PATCH 27/52] better shift actions handling --- .../Numark Mixtrack Pro FX.midi.xml | 72 +++--- .../Numark-Mixtrack-Pro-FX-scripts.js | 221 ++++++++---------- 2 files changed, 119 insertions(+), 174 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index d2fc94ca66a..4b3c8e0f83d 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -312,7 +312,7 @@ [Channel1] - MixtrackProFX.deck[0].cueButtonShift.input + MixtrackProFX.deck[0].cueButton.input 0x90 0x05 @@ -321,7 +321,7 @@ [Channel2] - MixtrackProFX.deck[1].cueButtonShift.input + MixtrackProFX.deck[1].cueButton.input 0x91 0x05 @@ -331,7 +331,7 @@ [Channel1] - MixtrackProFX.deck[0].cueButtonShift.input + MixtrackProFX.deck[0].cueButton.input 0x80 0x05 @@ -340,7 +340,7 @@ [Channel2] - MixtrackProFX.deck[1].cueButtonShift.input + MixtrackProFX.deck[1].cueButton.input 0x81 0x05 @@ -388,7 +388,7 @@ [Channel1] - MixtrackProFX.deck[0].playButtonStutter.input + MixtrackProFX.deck[0].playButton.input 0x90 0x04 @@ -397,7 +397,7 @@ [Channel2] - MixtrackProFX.deck[1].playButtonStutter.input + MixtrackProFX.deck[1].playButton.input 0x91 0x04 @@ -407,7 +407,7 @@ [Channel1] - MixtrackProFX.deck[0].playButtonStutter.input + MixtrackProFX.deck[0].playButton.input 0x80 0x04 @@ -416,7 +416,7 @@ [Channel2] - MixtrackProFX.deck[1].playButtonStutter.input + MixtrackProFX.deck[1].playButton.input 0x81 0x04 @@ -1466,7 +1466,7 @@ [Channel1] - MixtrackProFX.deck[0].loopIn.input + MixtrackProFX.deck[0].loopHalf.input 0x94 0x36 @@ -1475,7 +1475,7 @@ [Channel2] - MixtrackProFX.deck[1].loopIn.input + MixtrackProFX.deck[1].loopHalf.input 0x95 0x36 @@ -1485,7 +1485,7 @@ [Channel1] - MixtrackProFX.deck[0].loopIn.input + MixtrackProFX.deck[0].loopHalf.input 0x84 0x36 @@ -1494,7 +1494,7 @@ [Channel2] - MixtrackProFX.deck[1].loopIn.input + MixtrackProFX.deck[1].loopHalf.input 0x85 0x36 @@ -1542,7 +1542,7 @@ [Channel1] - MixtrackProFX.deck[0].loopOut.input + MixtrackProFX.deck[0].loopDouble.input 0x94 0x37 @@ -1551,7 +1551,7 @@ [Channel2] - MixtrackProFX.deck[1].loopOut.input + MixtrackProFX.deck[1].loopDouble.input 0x95 0x37 @@ -1561,7 +1561,7 @@ [Channel1] - MixtrackProFX.deck[0].loopOut.input + MixtrackProFX.deck[0].loopDouble.input 0x84 0x37 @@ -1570,7 +1570,7 @@ [Channel2] - MixtrackProFX.deck[1].loopOut.input + MixtrackProFX.deck[1].loopDouble.input 0x85 0x37 @@ -1628,7 +1628,7 @@ [Library] - MixtrackProFX.browse.knobShift.input + MixtrackProFX.browse.knob.input 0xBF 0x01 @@ -1658,7 +1658,7 @@ [Library] - MixtrackProFX.browse.buttonShift.input + MixtrackProFX.browse.knobButton.input 0x9F 0x06 @@ -1668,7 +1668,7 @@ [Library] - MixtrackProFX.browse.buttonShift.input + MixtrackProFX.browse.knobButton.input 0x8F 0x06 @@ -1812,7 +1812,7 @@ [Library] - MixtrackProFX.browse.setBeatgrid.input + MixtrackProFX.deck[0].setBeatgrid.input 0x98 0x01 @@ -1822,7 +1822,7 @@ [Library] - MixtrackProFX.browse.setBeatgrid.input + MixtrackProFX.deck[0].setBeatgrid.input 0x88 0x01 @@ -1870,18 +1870,9 @@ - - [Channel1] - MixtrackProFX.deck[0].beatsnap.input - 0x99 - 0x04 - - - - [Channel2] - MixtrackProFX.deck[1].beatsnap.input + MixtrackProFX.deck[1].setBeatgrid.input 0x99 0x04 @@ -1889,18 +1880,9 @@ - - [Channel1] - MixtrackProFX.deck[0].beatsnap.input - 0x89 - 0x04 - - - - [Channel2] - MixtrackProFX.deck[1].beatsnap.input + MixtrackProFX.deck[1].setBeatgrid.input 0x89 0x04 @@ -2121,7 +2103,7 @@ [Channel1] - MixtrackProFX.deck[0].keylock.input + MixtrackProFX.deck[0].pitchBendUp.input 0x90 0x2B @@ -2130,7 +2112,7 @@ [Channel2] - MixtrackProFX.deck[1].keylock.input + MixtrackProFX.deck[1].pitchBendUp.input 0x91 0x2B @@ -2140,7 +2122,7 @@ [Channel1] - MixtrackProFX.deck[0].keylock.input + MixtrackProFX.deck[0].pitchBendUp.input 0x80 0x2B @@ -2149,7 +2131,7 @@ [Channel2] - MixtrackProFX.deck[1].keylock.input + MixtrackProFX.deck[1].pitchBendUp.input 0x81 0x2B diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 74ba005b947..1dc50d81d8a 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -67,81 +67,42 @@ MixtrackProFX.shifted = false; MixtrackProFX.scratchModeEnabled = [true, true]; MixtrackProFX.init = function() { - // effects for both decks - MixtrackProFX.effect = new components.ComponentContainer(); - MixtrackProFX.effect[0] = new MixtrackProFX.EffectUnit(1); - MixtrackProFX.effect[1] = new MixtrackProFX.EffectUnit(2); - - // decks + // initialize component containers MixtrackProFX.deck = new components.ComponentContainer(); - MixtrackProFX.deck[0] = new MixtrackProFX.Deck(1); - MixtrackProFX.deck[1] = new MixtrackProFX.Deck(2); + MixtrackProFX.effect = new components.ComponentContainer(); + var i; + for (i = 0; i < 2; i++) { + MixtrackProFX.deck[i] = new MixtrackProFX.Deck(i + 1); + MixtrackProFX.effect[i] = new MixtrackProFX.EffectUnit(i + 1); + } MixtrackProFX.browse = new MixtrackProFX.Browse(); MixtrackProFX.gains = new MixtrackProFX.Gains(); + // send sysexes var exitDemoSysex = [0xF0, 0x7E, 0x00, 0x06, 0x01, 0xF7]; midi.sendSysexMsg(exitDemoSysex, exitDemoSysex.length); var statusSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0x01, 0xF7]; midi.sendSysexMsg(statusSysex, statusSysex.length); - // enables 4 bottom pads fader cuts + // enables 4 bottom pads "fader cuts" var faderCutSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0xF7]; midi.sendSysexMsg(faderCutSysex, faderCutSysex.length); - // initialize leds for both decks - for (var i = 0; i < 2; i++) { - midi.sendShortMsg(0x90 + i, 0x00, 0x01); // play - midi.sendShortMsg(0x90 + i, 0x01, 0x01); // cue - midi.sendShortMsg(0x90 + i, 0x02, 0x01); // sync - midi.sendShortMsg(0x90 + i, 0x07, 0x7f); // scratch - midi.sendShortMsg(0x90 + i, 0x1B, 0x01); // pfl - + // initialize leds + for (i = 0; i < 2; i++) { + midi.sendShortMsg(0x90 + i, 0x07, 0x7F); // scratch midi.sendShortMsg(0x94 + i, 0x00, 0x7F); // hotcue midi.sendShortMsg(0x94 + i, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x94 + i, 0x07, 0x01); // fader cuts - midi.sendShortMsg(0x94 + i, 0x0B, 0x01); // sample - - midi.sendShortMsg(0x94 + i, 0x34, 0x01); // half - midi.sendShortMsg(0x94 + i, 0x35, 0x01); // double - midi.sendShortMsg(0x94 + i, 0x40, 0x01); // loop - - // initialize leds for shifted buttons - midi.sendShortMsg(0x90 + i, 0x04, 0x01); // play - midi.sendShortMsg(0x90 + i, 0x05, 0x01); // cue - midi.sendShortMsg(0x90 + i, 0x03, 0x01); // sync - midi.sendShortMsg(0x94 + i, 0x0F, 0x01); // sample shifted + midi.sendShortMsg(0x94 + i, 0x07, 0x01); // "fader cuts" + midi.sendShortMsg(0x94 + i, 0x0B, 0x01); // sample1 + + // shifted leds + midi.sendShortMsg(0x94 + i, 0x0F, 0x01); // sample2 midi.sendShortMsg(0x94 + i, 0x02, 0x01); // beatjump - midi.sendShortMsg(0x90 + i, 0x08, 0x01); // bleep - midi.sendShortMsg(0x94 + i, 0x36, 0x01); // half - midi.sendShortMsg(0x94 + i, 0x37, 0x01); // double - midi.sendShortMsg(0x94 + i, 0x41, 0x01); // loop - - // pads - for (var j = 0; j < 8; j++) { - midi.sendShortMsg(0x94 + i, 0x14 + j, 0x01); - midi.sendShortMsg(0x94 + i, 0x1C + j, 0x01); // shifted - } } - midi.sendShortMsg(0x88, 0x09, 0x01); // tap led - - // check if quantize is enabled - var quantizeEnabled = engine.getValue("[Channel1]", "quantize"); - - // effect leds - midi.sendShortMsg(0x88, 0x00, 0x01); // hpf - midi.sendShortMsg(0x88, 0x01, 0x01); // lpf - midi.sendShortMsg(0x88, 0x02, 0x01); // flanger - midi.sendShortMsg(0x89, 0x03, 0x01); // echo - midi.sendShortMsg(0x89, 0x04, quantizeEnabled ? 0x7F : 0x01); // reverb - midi.sendShortMsg(0x89, 0x05, 0x01); // phaser - - // vumeters leds (off) - midi.sendShortMsg(0xB0, 0x1F, 0x00); - midi.sendShortMsg(0xB1, 0x1F, 0x00); - engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); @@ -234,28 +195,29 @@ MixtrackProFX.EffectUnit = function(deckNumber) { MixtrackProFX.EffectUnit.prototype = new components.ComponentContainer(); MixtrackProFX.Deck = function(number) { - var channel = number - 1; - components.Deck.call(this, number); - this.playButton = new components.PlayButton({ - midi: [0x90 + channel, 0x00] - }); + var channel = number - 1; - this.playButtonStutter = new components.Button({ - inKey: "play_stutter" + this.playButton = new components.PlayButton({ + midi: [0x90 + channel, 0x00], + shiftControl: true, + sendShifted: true, + shiftOffset: 0x04 }); this.cueButton = new components.CueButton({ - midi: [0x90 + channel, 0x01] - }); - - this.cueButtonShift = new components.Button({ - inKey: "start_stop" + midi: [0x90 + channel, 0x01], + shiftControl: true, + sendShifted: true, + shiftOffset: 0x04 }); this.syncButton = new components.SyncButton({ - midi: [0x90 + channel, 0x02] + midi: [0x90 + channel, 0x02], + shiftControl: true, + sendShifted: true, + shiftOffset: 0x01 }); this.pflButton = new components.Button({ @@ -310,14 +272,12 @@ MixtrackProFX.Deck = function(number) { // more consistent with the logic burned into hardware if (value === 0x7F) { MixtrackProFX.shifted = true; - MixtrackProFX.deck[0].shift(); - MixtrackProFX.deck[1].shift(); + MixtrackProFX.deck.shift(); MixtrackProFX.browse.shift(); MixtrackProFX.effect.shift(); - } else if (value === 0) { + } else if (value === 0x00) { MixtrackProFX.shifted = false; - MixtrackProFX.deck[0].unshift(); - MixtrackProFX.deck[1].unshift(); + MixtrackProFX.deck.unshift(); MixtrackProFX.browse.unshift(); MixtrackProFX.effect.unshift(); } @@ -325,7 +285,7 @@ MixtrackProFX.Deck = function(number) { }); this.loop = new components.Button({ - key: "loop_enabled", + outKey: "loop_enabled", midi: [0x94 + channel, 0x40], input: function(channel, control, value, status, group) { if (value !== 0x7F) { @@ -340,44 +300,65 @@ MixtrackProFX.Deck = function(number) { }); this.reloop = new components.Button({ - inKey: "reloop_toggle" // or loop_in_goto to not enable loop + key: "reloop_toggle", // or loop_in_goto to not enable loop + midi: [0x94 + channel, 0x41] }); this.loopHalf = new components.Button({ key: "loop_halve", - midi: [0x94 + channel, 0x34] + midi: [0x94 + channel, 0x34], + shiftControl: true, + sendShifted: true, + shiftOffset: 2, + shift: function() { + this.inKey = "loop_in"; + this.outKey = "loop_in"; + }, + unshift: function() { + this.inKey = "loop_halve"; + this.outKey = "loop_halve"; + } }); this.loopDouble = new components.Button({ key: "loop_double", - midi: [0x94 + channel, 0x35] - }); - - this.loopIn = new components.Button({ - inKey: "loop_in" - }); - - this.loopOut = new components.Button({ - inKey: "loop_out" + midi: [0x94 + channel, 0x35], + shiftControl: true, + sendShifted: true, + shiftOffset: 2, + shift: function() { + this.inKey = "loop_out"; + this.outKey = "loop_out"; + }, + unshift: function() { + this.inKey = "loop_double"; + this.outKey = "loop_double"; + } }); this.bleep = new components.Button({ - inKey: "reverseroll" + key: "reverseroll", + midi: [0x90 + channel, 0x08] }); this.pitchBendUp = new components.Button({ - inKey: "rate_temp_up" + inKey: "rate_temp_up", + shiftControl: true, + shiftOffset: 0x20, + shift: function() { + this.type = components.Button.prototype.types.toggle; + this.inKey = "keylock"; + }, + unshift: function() { + this.type = components.Button.prototype.types.push; + this.inKey = "rate_temp_up"; + } }); this.pitchBendDown = new components.Button({ inKey: "rate_temp_down" }); - this.keylock = new components.Button({ - type: components.Button.prototype.types.toggle, - inKey: "keylock" - }); - this.pitchRange = new components.Button({ currentRangeIdx: 0, input: function(channel, control, value, status, group) { @@ -389,10 +370,9 @@ MixtrackProFX.Deck = function(number) { } }); - this.beatsnap = new components.Button({ - type: components.Button.prototype.types.toggle, - key: "quantize", - midi: [0x89, 0x04] + this.setBeatgrid = new components.Button({ + key: "beats_translate_curpos", + midi: [0x98 + channel, 0x01 + (channel * 3)] }); this.reconnectComponents(function(component) { @@ -652,30 +632,22 @@ MixtrackProFX.ModeBeatjump.prototype = Object.create(components.ComponentContain MixtrackProFX.Browse = function() { this.knob = new components.Encoder({ - group: "[Library]", - inKey: "MoveVertical", - inValueScale: function(value) { - return (value > 0x40) ? value - 0x80 : value; - } - }); - - this.knobShift = new components.Encoder({ + shiftControl: true, + shiftOffset: 0x01, input: function(channel, control, value) { - if (value === 0x01) { - engine.setParameter("[Channel1]", "waveform_zoom_down", 1); + var direction; + if (!MixtrackProFX.shifted) { + direction = (value > 0x40) ? value - 0x80 : value; + engine.setParameter("[Library]", "MoveVertical", direction); + } else { + direction = (value > 0x40) ? "down" : "up"; + engine.setParameter("[Channel1]", "waveform_zoom_" + direction, 1); // need to zoom both channels if waveform sync is disabled in Mixxx settings. // and when it's enabled then no need to zoom 2nd channel, as it will cause // the zoom to jump 2 levels at once if (!MixtrackProFX.waveformsSynced) { - engine.setParameter("[Channel2]", "waveform_zoom_down", 1); - } - } else if (value === 0x7F) { - engine.setParameter("[Channel1]", "waveform_zoom_up", 1); - - // see above comment - if (!MixtrackProFX.waveformsSynced) { - engine.setParameter("[Channel2]", "waveform_zoom_up", 1); + engine.setParameter("[Channel2]", "waveform_zoom_" + direction, 1); } } } @@ -683,23 +655,14 @@ MixtrackProFX.Browse = function() { this.knobButton = new components.Button({ group: "[Library]", - inKey: "MoveFocusForward" - }); - - this.buttonShift = new components.Button({ - group: "[Library]", - inKey: "GoToItem" - }); - - this.setBeatgrid = new components.Button({ - group: "[Channel1]", - key: "beats_translate_curpos", - midi: [0x88, 0x01], + inKey: "MoveFocusForward", + shiftControl: true, + shiftOffset: 0x01, shift: function() { - this.group = "[Channel2]"; + this.inKey = "GoToItem"; }, unshift: function() { - this.group = "[Channel1]"; + this.inKey = "MoveFocusForward"; } }); }; From d9a1b9f48b0c44f7fddeb8fa7972de9d3252e968 Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 6 Aug 2021 20:51:09 +0200 Subject: [PATCH 28/52] FX enable switch input value scaling (debug) --- .../Numark-Mixtrack-Pro-FX-scripts.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 1dc50d81d8a..1d10bd2e340 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -66,6 +66,15 @@ MixtrackProFX.PadModeControls = { MixtrackProFX.shifted = false; MixtrackProFX.scratchModeEnabled = [true, true]; +// a helper function to convert value to binary scale (0 or 1) +MixtrackProFX.scaleToBinaryInput = function(value) { + print("debug MixtrackProFX.scaleToBinaryInput"); + if (value > 0) { + return 1; + } + return 0; +}; + MixtrackProFX.init = function() { // initialize component containers MixtrackProFX.deck = new components.ComponentContainer(); @@ -126,10 +135,9 @@ MixtrackProFX.EffectUnit = function(deckNumber) { // 1 - switch up // 2 - switch down this.enableSwitch = new components.Button({ - input: function(channel, control, value, status, group) { - // note: value is 2 when the switch is held down (1 when up) - engine.setValue(group, "enabled", value); - } + group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", + inKey: "enabled", + inValueScale: MixtrackProFX.scaleToBinaryInput }); this.dryWetKnob = new components.Pot({ From 53b8d0e7c7da5b1c25928715adfbe0defe4ee7ad Mon Sep 17 00:00:00 2001 From: h67ma Date: Fri, 6 Aug 2021 23:50:29 +0200 Subject: [PATCH 29/52] reversed direction of waveform zoom --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 1d10bd2e340..ce0b4aa6efb 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -648,7 +648,7 @@ MixtrackProFX.Browse = function() { direction = (value > 0x40) ? value - 0x80 : value; engine.setParameter("[Library]", "MoveVertical", direction); } else { - direction = (value > 0x40) ? "down" : "up"; + direction = (value > 0x40) ? "up" : "down"; engine.setParameter("[Channel1]", "waveform_zoom_" + direction, 1); // need to zoom both channels if waveform sync is disabled in Mixxx settings. From e835b1d5a2dc4ad630265311ad3d968a57f1d757 Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 9 Aug 2021 20:33:54 +0200 Subject: [PATCH 30/52] removed unnecessary in value scaling for FX enable switches --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index ce0b4aa6efb..1de42722e86 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -66,15 +66,6 @@ MixtrackProFX.PadModeControls = { MixtrackProFX.shifted = false; MixtrackProFX.scratchModeEnabled = [true, true]; -// a helper function to convert value to binary scale (0 or 1) -MixtrackProFX.scaleToBinaryInput = function(value) { - print("debug MixtrackProFX.scaleToBinaryInput"); - if (value > 0) { - return 1; - } - return 0; -}; - MixtrackProFX.init = function() { // initialize component containers MixtrackProFX.deck = new components.ComponentContainer(); @@ -136,8 +127,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { // 2 - switch down this.enableSwitch = new components.Button({ group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", - inKey: "enabled", - inValueScale: MixtrackProFX.scaleToBinaryInput + inKey: "enabled" }); this.dryWetKnob = new components.Pot({ From eaa9fbbd959a506fb93fbd1aacb686878a1f251e Mon Sep 17 00:00:00 2001 From: h67ma Date: Mon, 9 Aug 2021 20:57:08 +0200 Subject: [PATCH 31/52] removed unnecessary key attributes from components where unshift function is defined --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 1de42722e86..380330663a7 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -143,7 +143,6 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.effectParam = new components.Encoder({ group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", - inKey: "parameter1", shift: function() { this.inKey = "parameter2"; }, @@ -161,7 +160,6 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.prevEffect = new components.Button({ group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", - key: "prev_effect", midi: [0x98, (deckNumber - 1) * 2], shift: function() { this.group = "[Channel" + deckNumber + "]"; @@ -177,15 +175,16 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.nextEffect = new components.Button({ group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", - key: "next_effect", midi: [0x99, 0x03 + (deckNumber - 1) * 2], shift: function() { this.group = "[Channel" + deckNumber + "]"; this.inKey = "pitch_down"; + this.outKey = "pitch_down"; }, unshift: function() { this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; this.inKey = "next_effect"; + this.outKey = "next_effect"; } }); }; @@ -303,7 +302,6 @@ MixtrackProFX.Deck = function(number) { }); this.loopHalf = new components.Button({ - key: "loop_halve", midi: [0x94 + channel, 0x34], shiftControl: true, sendShifted: true, @@ -319,7 +317,6 @@ MixtrackProFX.Deck = function(number) { }); this.loopDouble = new components.Button({ - key: "loop_double", midi: [0x94 + channel, 0x35], shiftControl: true, sendShifted: true, @@ -340,7 +337,6 @@ MixtrackProFX.Deck = function(number) { }); this.pitchBendUp = new components.Button({ - inKey: "rate_temp_up", shiftControl: true, shiftOffset: 0x20, shift: function() { @@ -530,8 +526,6 @@ MixtrackProFX.ModeAutoLoop = function(deckNumber) { for (var i = 0; i < 8; i++) { this.pads[i] = new components.Button({ group: "[Channel" + deckNumber + "]", - inKey: "beatloop_" + this.size + "_toggle", - outKey: "beatloop_" + this.size + "_enabled", midi: [0x93 + deckNumber, 0x14 + i], size: MixtrackProFX.autoLoopSizes[i], shiftControl: true, @@ -608,7 +602,6 @@ MixtrackProFX.ModeBeatjump = function(deckNumber) { for (var i = 0; i < 8; i++) { this.pads[i] = new components.Button({ group: "[Channel" + deckNumber + "]", - key: "beatjump_" + this.size + "forward", midi: [0x93 + deckNumber, 0x14 + i], size: MixtrackProFX.beatJumpValues[i], shiftControl: true, @@ -653,7 +646,6 @@ MixtrackProFX.Browse = function() { this.knobButton = new components.Button({ group: "[Library]", - inKey: "MoveFocusForward", shiftControl: true, shiftOffset: 0x01, shift: function() { From f35255f0350b17d52d4476ed10455fbdc3b79e4d Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 10 Aug 2021 18:00:58 +0200 Subject: [PATCH 32/52] separate input and value scaling of effect param knob --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 380330663a7..9adfb29a81b 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -150,11 +150,10 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.inKey = "parameter1"; }, input: function(channel, control, value) { - if (value === 0x01) { - this.inSetParameter(this.inGetParameter() + 0.05); - } else if (value === 0x7F) { - this.inSetParameter(this.inGetParameter() - 0.05); - } + this.inSetParameter(this.inGetParameter() + this.inValueScale(value)); + }, + inValueScale: function(value) { + return (value < 0x40) ? 0.05 : -0.05; } }); From f5a68325127f1c1467e61714ba29971fcd32cc6a Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 10 Aug 2021 18:13:47 +0200 Subject: [PATCH 33/52] refactoring of shift button --- .../Numark-Mixtrack-Pro-FX-scripts.js | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 9adfb29a81b..eee4c7197f3 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -115,6 +115,20 @@ MixtrackProFX.shutdown = function() { midi.sendSysexMsg(shutdownSysex, shutdownSysex.length); }; +MixtrackProFX.shift = function() { + MixtrackProFX.shifted = true; + MixtrackProFX.deck.shift(); + MixtrackProFX.browse.shift(); + MixtrackProFX.effect.shift(); +}; + +MixtrackProFX.unshift = function() { + MixtrackProFX.shifted = false; + MixtrackProFX.deck.unshift(); + MixtrackProFX.browse.unshift(); + MixtrackProFX.effect.unshift(); +}; + // TODO in 2.3 it is not possible to "properly" map the FX selection buttons. // this should be done with load_preset and QuickEffects instead (when effect // chain preset saving/loading is available in Mixxx) @@ -266,17 +280,17 @@ MixtrackProFX.Deck = function(number) { input: function(channel, control, value) { // each shift button shifts both decks // more consistent with the logic burned into hardware + if (this.isPress(channel, control, value)) { + MixtrackProFX.shift(); + } else { + MixtrackProFX.unshift(); + } + }, + isPress: function(channel, control, value) { if (value === 0x7F) { - MixtrackProFX.shifted = true; - MixtrackProFX.deck.shift(); - MixtrackProFX.browse.shift(); - MixtrackProFX.effect.shift(); - } else if (value === 0x00) { - MixtrackProFX.shifted = false; - MixtrackProFX.deck.unshift(); - MixtrackProFX.browse.unshift(); - MixtrackProFX.effect.unshift(); + return true; } + return false; } }); From 520aea19da5f9c4ca588842aa14b475042271a9b Mon Sep 17 00:00:00 2001 From: h67ma Date: Wed, 11 Aug 2021 02:10:43 +0200 Subject: [PATCH 34/52] put together more buttons and their shifted equivalents. improved lights when shifted --- .../Numark Mixtrack Pro FX.midi.xml | 32 ++--- .../Numark-Mixtrack-Pro-FX-scripts.js | 125 ++++++++++++------ 2 files changed, 99 insertions(+), 58 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 4b3c8e0f83d..852cdc4c041 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -464,7 +464,7 @@ [Channel1] - MixtrackProFX.scratchToggle + MixtrackProFX.deck[0].scratchToggle.input 0x90 0x07 @@ -473,7 +473,7 @@ [Channel2] - MixtrackProFX.scratchToggle + MixtrackProFX.deck[1].scratchToggle.input 0x91 0x07 @@ -483,7 +483,7 @@ [Channel1] - MixtrackProFX.scratchToggle + MixtrackProFX.deck[0].scratchToggle.input 0x80 0x07 @@ -492,7 +492,7 @@ [Channel2] - MixtrackProFX.scratchToggle + MixtrackProFX.deck[1].scratchToggle.input 0x81 0x07 @@ -502,7 +502,7 @@ [Channel1] - MixtrackProFX.deck[0].bleep.input + MixtrackProFX.deck[0].scratchToggle.input 0x90 0x08 @@ -511,7 +511,7 @@ [Channel2] - MixtrackProFX.deck[1].bleep.input + MixtrackProFX.deck[1].scratchToggle.input 0x91 0x08 @@ -521,7 +521,7 @@ [Channel1] - MixtrackProFX.deck[0].bleep.input + MixtrackProFX.deck[0].scratchToggle.input 0x80 0x08 @@ -530,7 +530,7 @@ [Channel2] - MixtrackProFX.deck[1].bleep.input + MixtrackProFX.deck[1].scratchToggle.input 0x81 0x08 @@ -1390,7 +1390,7 @@ [Channel1] - MixtrackProFX.deck[0].reloop.input + MixtrackProFX.deck[0].loop.input 0x94 0x41 @@ -1399,7 +1399,7 @@ [Channel2] - MixtrackProFX.deck[1].reloop.input + MixtrackProFX.deck[1].loop.input 0x95 0x41 @@ -1409,7 +1409,7 @@ [Channel1] - MixtrackProFX.deck[0].reloop.input + MixtrackProFX.deck[0].loop.input 0x84 0x41 @@ -1418,7 +1418,7 @@ [Channel2] - MixtrackProFX.deck[1].reloop.input + MixtrackProFX.deck[1].loop.input 0x85 0x41 @@ -2027,7 +2027,7 @@ [Channel1] - MixtrackProFX.deck[0].pitchRange.input + MixtrackProFX.deck[0].pitchBendDown.input 0x90 0x2C @@ -2036,7 +2036,7 @@ [Channel2] - MixtrackProFX.deck[1].pitchRange.input + MixtrackProFX.deck[1].pitchBendDown.input 0x91 0x2C @@ -2046,7 +2046,7 @@ [Channel1] - MixtrackProFX.deck[0].pitchRange.input + MixtrackProFX.deck[0].pitchBendDown.input 0x80 0x2C @@ -2055,7 +2055,7 @@ [Channel2] - MixtrackProFX.deck[1].pitchRange.input + MixtrackProFX.deck[1].pitchBendDown.input 0x81 0x2C diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index eee4c7197f3..f85955256d0 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -64,7 +64,6 @@ MixtrackProFX.PadModeControls = { // state variables, don't touch MixtrackProFX.shifted = false; -MixtrackProFX.scratchModeEnabled = [true, true]; MixtrackProFX.init = function() { // initialize component containers @@ -92,7 +91,6 @@ MixtrackProFX.init = function() { // initialize leds for (i = 0; i < 2; i++) { - midi.sendShortMsg(0x90 + i, 0x07, 0x7F); // scratch midi.sendShortMsg(0x94 + i, 0x00, 0x7F); // hotcue midi.sendShortMsg(0x94 + i, 0x0D, 0x01); // auto loop midi.sendShortMsg(0x94 + i, 0x07, 0x01); // "fader cuts" @@ -178,11 +176,15 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.group = "[Channel" + deckNumber + "]"; this.inKey = "pitch_up"; this.outKey = "pitch_up"; + this.disconnect(); + this.connect(); }, unshift: function() { this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; this.inKey = "prev_effect"; this.outKey = "prev_effect"; + this.disconnect(); + this.connect(); } }); @@ -193,11 +195,15 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.group = "[Channel" + deckNumber + "]"; this.inKey = "pitch_down"; this.outKey = "pitch_down"; + this.disconnect(); + this.connect(); }, unshift: function() { this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; this.inKey = "next_effect"; this.outKey = "next_effect"; + this.disconnect(); + this.connect(); } }); }; @@ -208,6 +214,8 @@ MixtrackProFX.Deck = function(number) { components.Deck.call(this, number); var channel = number - 1; + var deck = this; + this.scratchModeEnabled = true; this.playButton = new components.PlayButton({ midi: [0x90 + channel, 0x00], @@ -297,35 +305,43 @@ MixtrackProFX.Deck = function(number) { this.loop = new components.Button({ outKey: "loop_enabled", midi: [0x94 + channel, 0x40], - input: function(channel, control, value, status, group) { - if (value !== 0x7F) { - return; - } - if (engine.getValue(group, "loop_enabled") === 0) { - script.triggerControl(group, "beatloop_activate"); - } else { - script.triggerControl(group, "beatlooproll_activate"); - } - } - }); - - this.reloop = new components.Button({ - key: "reloop_toggle", // or loop_in_goto to not enable loop - midi: [0x94 + channel, 0x41] + shift: function() { + this.inKey = "loop_in_goto"; + this.input = components.Button.prototype.input; + }, + unshift: function() { + this.input = function(channel, control, value, status, group) { + if (value !== 0x7F) { + return; + } + if (engine.getValue(group, "loop_enabled") === 0) { + script.triggerControl(group, "beatloop_activate"); + } else { + script.triggerControl(group, "beatlooproll_activate"); + } + }; + }, + shiftControl: true, + sendShifted: true, + shiftOffset: 0x01 }); this.loopHalf = new components.Button({ midi: [0x94 + channel, 0x34], shiftControl: true, sendShifted: true, - shiftOffset: 2, + shiftOffset: 0x02, shift: function() { this.inKey = "loop_in"; this.outKey = "loop_in"; + this.disconnect(); + this.connect(); }, unshift: function() { this.inKey = "loop_halve"; this.outKey = "loop_halve"; + this.disconnect(); + this.connect(); } }); @@ -333,20 +349,47 @@ MixtrackProFX.Deck = function(number) { midi: [0x94 + channel, 0x35], shiftControl: true, sendShifted: true, - shiftOffset: 2, + shiftOffset: 0x02, shift: function() { this.inKey = "loop_out"; this.outKey = "loop_out"; + this.disconnect(); + this.connect(); }, unshift: function() { this.inKey = "loop_double"; this.outKey = "loop_double"; + this.disconnect(); + this.connect(); } }); - this.bleep = new components.Button({ - key: "reverseroll", - midi: [0x90 + channel, 0x08] + this.scratchToggle = new components.Button({ + midi: [0x90 + channel, 0x07], + shift: function() { + this.inKey = "reverseroll"; + this.outKey = "reverseroll"; + this.connect(); + this.input = components.Button.prototype.input; + }, + unshift: function() { + this.disconnect(); + this.input = function(channel, control, value) { + if (value !== 0x7F) { + return; + } + deck.scratchModeEnabled = !deck.scratchModeEnabled; + midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? 0x7F : 0x01); + }; + + midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? 0x7F : 0x01); + + var bleepEnabled = engine.getParameter(this.group, "reverseroll") === 1; + midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, bleepEnabled ? 0x7F : 0x01); + }, + shiftControl: true, + sendShifted: true, + shiftOffset: 0x01 }); this.pitchBendUp = new components.Button({ @@ -363,17 +406,19 @@ MixtrackProFX.Deck = function(number) { }); this.pitchBendDown = new components.Button({ - inKey: "rate_temp_down" - }); - - this.pitchRange = new components.Button({ currentRangeIdx: 0, - input: function(channel, control, value, status, group) { - if (value !== 0x7F) { - return; - } - this.currentRangeIdx = (this.currentRangeIdx + 1) % MixtrackProFX.pitchRanges.length; - engine.setValue(group, "rateRange", MixtrackProFX.pitchRanges[this.currentRangeIdx]); + shift: function() { + this.input = function(channel, control, value) { + if (value !== 0x7F) { + return; + } + this.currentRangeIdx = (this.currentRangeIdx + 1) % MixtrackProFX.pitchRanges.length; + engine.setValue(this.group, "rateRange", MixtrackProFX.pitchRanges[this.currentRangeIdx]); + }; + }, + unshift: function() { + this.inKey = "rate_temp_down"; + this.input = components.Button.prototype.input; } }); @@ -623,10 +668,14 @@ MixtrackProFX.ModeBeatjump = function(deckNumber) { shift: function() { this.inKey = "beatjump_" + this.size + "backward"; this.outKey = "beatjump_" + this.size + "backward"; + this.disconnect(); + this.connect(); }, unshift: function() { this.inKey = "beatjump_" + this.size + "forward"; this.outKey = "beatjump_" + this.size + "forward"; + this.disconnect(); + this.connect(); }, outConnect: false }); @@ -695,18 +744,10 @@ MixtrackProFX.vuCallback = function(value, group) { midi.sendShortMsg(0xB0 + deckOffset, 0x1F, level); }; -MixtrackProFX.scratchToggle = function(channel, control, value) { - if (value !== 0x7F) { - return; - } - MixtrackProFX.scratchModeEnabled[channel] = !MixtrackProFX.scratchModeEnabled[channel]; - midi.sendShortMsg(0x90 | channel, 0x07, MixtrackProFX.scratchModeEnabled[channel] ? 0x7F : 0x01); -}; - MixtrackProFX.wheelTouch = function(channel, control, value) { var deckNumber = channel + 1; - if (!MixtrackProFX.shifted && MixtrackProFX.scratchModeEnabled[channel] && value === 0x7F) { + if (!MixtrackProFX.shifted && MixtrackProFX.deck[channel].scratchModeEnabled && value === 0x7F) { // touch start engine.scratchEnable(deckNumber, MixtrackProFX.jogScratchSensitivity, 33+1/3, MixtrackProFX.jogScratchAlpha, MixtrackProFX.jogScratchBeta, true); @@ -731,7 +772,7 @@ MixtrackProFX.wheelTurn = function(channel, control, value, status, group) { var oldPos = engine.getValue(group, "playposition"); engine.setValue(group, "playposition", oldPos + newValue / MixtrackProFX.jogSeekSensitivity); - } else if (MixtrackProFX.scratchModeEnabled[channel] && engine.isScratching(deckNumber)) { + } else if (MixtrackProFX.deck[channel].scratchModeEnabled && engine.isScratching(deckNumber)) { // scratch engine.scratchTick(deckNumber, newValue); } else { From 48b8756203f7558f5bb78e35c8e7aac265203c8a Mon Sep 17 00:00:00 2001 From: Sancho Date: Tue, 17 Aug 2021 19:49:33 +0200 Subject: [PATCH 35/52] update comment about shifting whole controller Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index f85955256d0..57c097f066b 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -286,7 +286,7 @@ MixtrackProFX.Deck = function(number) { this.shiftButton = new components.Button({ input: function(channel, control, value) { - // each shift button shifts both decks + // each shift button shifts the entire controller. // more consistent with the logic burned into hardware if (this.isPress(channel, control, value)) { MixtrackProFX.shift(); From fe4683f0246e9695c667dfca364679828f96f54d Mon Sep 17 00:00:00 2001 From: Sancho Date: Tue, 17 Aug 2021 20:06:35 +0200 Subject: [PATCH 36/52] remove redundant isPress property from shift button Co-authored-by: Swiftb0y <12380386+Swiftb0y@users.noreply.github.com> --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 57c097f066b..19a088af46a 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -294,12 +294,6 @@ MixtrackProFX.Deck = function(number) { MixtrackProFX.unshift(); } }, - isPress: function(channel, control, value) { - if (value === 0x7F) { - return true; - } - return false; - } }); this.loop = new components.Button({ From 4dc91a596f822c9bdfb6e3abe549ef23c5362b79 Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 19:24:55 +0200 Subject: [PATCH 37/52] trigger instead of reconnectComponents in init --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 19a088af46a..bb13ec01000 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -104,8 +104,13 @@ MixtrackProFX.init = function() { engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); - MixtrackProFX.deck.reconnectComponents(); - MixtrackProFX.effect.reconnectComponents(); + // trigger is needed to initialize lights to 0x01 + MixtrackProFX.deck.forEachComponent(function(component) { + component.trigger(); + }); + MixtrackProFX.effect.forEachComponent(function(component) { + component.trigger(); + }); }; MixtrackProFX.shutdown = function() { From c46f31c7f95c26b851970e7803bcaa1484b72184 Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 19:42:26 +0200 Subject: [PATCH 38/52] rearranged disconnect/connect calls for style points --- .../Numark-Mixtrack-Pro-FX-scripts.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index bb13ec01000..8f8944c14c4 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -178,17 +178,17 @@ MixtrackProFX.EffectUnit = function(deckNumber) { group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", midi: [0x98, (deckNumber - 1) * 2], shift: function() { + this.disconnect(); this.group = "[Channel" + deckNumber + "]"; this.inKey = "pitch_up"; this.outKey = "pitch_up"; - this.disconnect(); this.connect(); }, unshift: function() { + this.disconnect(); this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; this.inKey = "prev_effect"; this.outKey = "prev_effect"; - this.disconnect(); this.connect(); } }); @@ -197,17 +197,17 @@ MixtrackProFX.EffectUnit = function(deckNumber) { group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", midi: [0x99, 0x03 + (deckNumber - 1) * 2], shift: function() { + this.disconnect(); this.group = "[Channel" + deckNumber + "]"; this.inKey = "pitch_down"; this.outKey = "pitch_down"; - this.disconnect(); this.connect(); }, unshift: function() { + this.disconnect(); this.group = "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]"; this.inKey = "next_effect"; this.outKey = "next_effect"; - this.disconnect(); this.connect(); } }); @@ -331,15 +331,15 @@ MixtrackProFX.Deck = function(number) { sendShifted: true, shiftOffset: 0x02, shift: function() { + this.disconnect(); this.inKey = "loop_in"; this.outKey = "loop_in"; - this.disconnect(); this.connect(); }, unshift: function() { + this.disconnect(); this.inKey = "loop_halve"; this.outKey = "loop_halve"; - this.disconnect(); this.connect(); } }); @@ -350,15 +350,15 @@ MixtrackProFX.Deck = function(number) { sendShifted: true, shiftOffset: 0x02, shift: function() { + this.disconnect(); this.inKey = "loop_out"; this.outKey = "loop_out"; - this.disconnect(); this.connect(); }, unshift: function() { + this.disconnect(); this.inKey = "loop_double"; this.outKey = "loop_double"; - this.disconnect(); this.connect(); } }); @@ -368,8 +368,8 @@ MixtrackProFX.Deck = function(number) { shift: function() { this.inKey = "reverseroll"; this.outKey = "reverseroll"; - this.connect(); this.input = components.Button.prototype.input; + this.connect(); }, unshift: function() { this.disconnect(); @@ -665,15 +665,15 @@ MixtrackProFX.ModeBeatjump = function(deckNumber) { sendShifted: true, shiftOffset: 0x08, shift: function() { + this.disconnect(); this.inKey = "beatjump_" + this.size + "backward"; this.outKey = "beatjump_" + this.size + "backward"; - this.disconnect(); this.connect(); }, unshift: function() { + this.disconnect(); this.inKey = "beatjump_" + this.size + "forward"; this.outKey = "beatjump_" + this.size + "forward"; - this.disconnect(); this.connect(); }, outConnect: false From a2a35d361f679ac80260a6ac3027592fb776046f Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 19:48:28 +0200 Subject: [PATCH 39/52] trigger components after connecting them --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 8f8944c14c4..7cfb9acffb6 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -183,6 +183,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.inKey = "pitch_up"; this.outKey = "pitch_up"; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); @@ -190,6 +191,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.inKey = "prev_effect"; this.outKey = "prev_effect"; this.connect(); + this.trigger(); } }); @@ -202,6 +204,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.inKey = "pitch_down"; this.outKey = "pitch_down"; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); @@ -209,6 +212,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { this.inKey = "next_effect"; this.outKey = "next_effect"; this.connect(); + this.trigger(); } }); }; @@ -335,12 +339,14 @@ MixtrackProFX.Deck = function(number) { this.inKey = "loop_in"; this.outKey = "loop_in"; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); this.inKey = "loop_halve"; this.outKey = "loop_halve"; this.connect(); + this.trigger(); } }); @@ -354,12 +360,14 @@ MixtrackProFX.Deck = function(number) { this.inKey = "loop_out"; this.outKey = "loop_out"; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); this.inKey = "loop_double"; this.outKey = "loop_double"; this.connect(); + this.trigger(); } }); @@ -370,6 +378,7 @@ MixtrackProFX.Deck = function(number) { this.outKey = "reverseroll"; this.input = components.Button.prototype.input; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); @@ -669,12 +678,14 @@ MixtrackProFX.ModeBeatjump = function(deckNumber) { this.inKey = "beatjump_" + this.size + "backward"; this.outKey = "beatjump_" + this.size + "backward"; this.connect(); + this.trigger(); }, unshift: function() { this.disconnect(); this.inKey = "beatjump_" + this.size + "forward"; this.outKey = "beatjump_" + this.size + "forward"; this.connect(); + this.trigger(); }, outConnect: false }); From 89eedbdb910956eb1adbf553598c29003eb124fd Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 19:57:35 +0200 Subject: [PATCH 40/52] removed redundant group properties --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 7cfb9acffb6..0ed3106c5e7 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -136,8 +136,6 @@ MixtrackProFX.unshift = function() { // this should be done with load_preset and QuickEffects instead (when effect // chain preset saving/loading is available in Mixxx) MixtrackProFX.EffectUnit = function(deckNumber) { - this.group = "[EffectRack1_EffectUnit" + deckNumber + "]"; - // switch values are: // 0 - switch in the middle // 1 - switch up @@ -148,7 +146,7 @@ MixtrackProFX.EffectUnit = function(deckNumber) { }); this.dryWetKnob = new components.Pot({ - group: this.group, + group: "[EffectRack1_EffectUnit" + deckNumber + "]", inKey: "mix" }); @@ -175,7 +173,6 @@ MixtrackProFX.EffectUnit = function(deckNumber) { }); this.prevEffect = new components.Button({ - group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", midi: [0x98, (deckNumber - 1) * 2], shift: function() { this.disconnect(); @@ -196,7 +193,6 @@ MixtrackProFX.EffectUnit = function(deckNumber) { }); this.nextEffect = new components.Button({ - group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", midi: [0x99, 0x03 + (deckNumber - 1) * 2], shift: function() { this.disconnect(); From 1bdf5572248201467fc85d4c638f0e41c8728a7d Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 20:01:38 +0200 Subject: [PATCH 41/52] moved the tap button from EffectUnit to Deck --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 8 ++++---- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 852cdc4c041..1f8e1c2fc80 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -1754,7 +1754,7 @@ [Channel1] - MixtrackProFX.effect[0].tap.input + MixtrackProFX.deck[0].tap.input 0x98 0x09 @@ -1763,7 +1763,7 @@ [Channel2] - MixtrackProFX.effect[1].tap.input + MixtrackProFX.deck[1].tap.input 0x99 0x09 @@ -1773,7 +1773,7 @@ [Channel1] - MixtrackProFX.effect[0].tap.input + MixtrackProFX.deck[0].tap.input 0x88 0x09 @@ -1782,7 +1782,7 @@ [Channel2] - MixtrackProFX.effect[1].tap.input + MixtrackProFX.deck[1].tap.input 0x89 0x09 diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 0ed3106c5e7..75997479db1 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -150,12 +150,6 @@ MixtrackProFX.EffectUnit = function(deckNumber) { inKey: "mix" }); - this.tap = new components.Button({ - group: "[Channel" + deckNumber + "]", - key: "bpm_tap", - midi: [0x88, 0x09] - }); - this.effectParam = new components.Encoder({ group: "[EffectRack1_EffectUnit" + deckNumber + "_Effect1]", shift: function() { @@ -243,6 +237,12 @@ MixtrackProFX.Deck = function(number) { shiftOffset: 0x01 }); + this.tap = new components.Button({ + group: this.currentDeck, + key: "bpm_tap", + midi: [0x88, 0x09] + }); + this.pflButton = new components.Button({ type: components.Button.prototype.types.toggle, midi: [0x90 + channel, 0x1B], From 3d7fb0827b81c274b93f3e65c448ce96178b7ea2 Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 20:13:07 +0200 Subject: [PATCH 42/52] use isPress instead of checking if value is 0x7F --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 75997479db1..a233a09e585 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -298,7 +298,7 @@ MixtrackProFX.Deck = function(number) { } else { MixtrackProFX.unshift(); } - }, + } }); this.loop = new components.Button({ @@ -310,7 +310,7 @@ MixtrackProFX.Deck = function(number) { }, unshift: function() { this.input = function(channel, control, value, status, group) { - if (value !== 0x7F) { + if (!this.isPress(channel, control, value)) { return; } if (engine.getValue(group, "loop_enabled") === 0) { @@ -379,7 +379,7 @@ MixtrackProFX.Deck = function(number) { unshift: function() { this.disconnect(); this.input = function(channel, control, value) { - if (value !== 0x7F) { + if (!this.isPress(channel, control, value)) { return; } deck.scratchModeEnabled = !deck.scratchModeEnabled; @@ -413,7 +413,7 @@ MixtrackProFX.Deck = function(number) { currentRangeIdx: 0, shift: function() { this.input = function(channel, control, value) { - if (value !== 0x7F) { + if (!this.isPress(channel, control, value)) { return; } this.currentRangeIdx = (this.currentRangeIdx + 1) % MixtrackProFX.pitchRanges.length; From a255b2fbc6bf9947978fb72949649a44bf15b9db Mon Sep 17 00:00:00 2001 From: h67ma Date: Tue, 17 Aug 2021 20:41:31 +0200 Subject: [PATCH 43/52] use this.on and this.off instead of hardcoded values for lights --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index a233a09e585..5b679946125 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -383,13 +383,13 @@ MixtrackProFX.Deck = function(number) { return; } deck.scratchModeEnabled = !deck.scratchModeEnabled; - midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? 0x7F : 0x01); + midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); }; - midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? 0x7F : 0x01); + midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); var bleepEnabled = engine.getParameter(this.group, "reverseroll") === 1; - midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, bleepEnabled ? 0x7F : 0x01); + midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, bleepEnabled ? this.on : this.off); }, shiftControl: true, sendShifted: true, From c15ba38f2d981a92c826829f0723d7384957496b Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 19 Aug 2021 01:15:29 +0200 Subject: [PATCH 44/52] added some comments about scratch toggle btn lights, also simplified it a bit --- .../Numark-Mixtrack-Pro-FX-scripts.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 5b679946125..f560d0932d1 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -368,28 +368,39 @@ MixtrackProFX.Deck = function(number) { }); this.scratchToggle = new components.Button({ + // disconnects/connects are needed for the following scenario: + // 1. scratch mode is enabled (light on) + // 2. shift down + // 3. scratch button down + // 4. shift up + // 5. scratch button up + // scratch mode light is now off, should be on + key: "reverseroll", midi: [0x90 + channel, 0x07], shift: function() { - this.inKey = "reverseroll"; - this.outKey = "reverseroll"; this.input = components.Button.prototype.input; this.connect(); this.trigger(); }, unshift: function() { - this.disconnect(); + this.disconnect(); // disconnect reverseroll light this.input = function(channel, control, value) { if (!this.isPress(channel, control, value)) { return; } deck.scratchModeEnabled = !deck.scratchModeEnabled; + + // change the scratch mode status light midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); }; + // set current scratch mode status light midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); - var bleepEnabled = engine.getParameter(this.group, "reverseroll") === 1; - midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, bleepEnabled ? this.on : this.off); + // reverseroll is now disabled (because shift is not held down), disable shifted light. + // when shifting the light will be connected to reverseroll. sending this midi here + // prevents the light from blinking when shifting in some cases. + midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, this.off); }, shiftControl: true, sendShifted: true, From 2f5349b4af128d10162c5af01045664fbaa891aa Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 19 Aug 2021 01:24:39 +0200 Subject: [PATCH 45/52] updated mixxx version and changed order of authors in xml --- res/controllers/Numark Mixtrack Pro FX.midi.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/controllers/Numark Mixtrack Pro FX.midi.xml b/res/controllers/Numark Mixtrack Pro FX.midi.xml index 1f8e1c2fc80..3cac016a09a 100644 --- a/res/controllers/Numark Mixtrack Pro FX.midi.xml +++ b/res/controllers/Numark Mixtrack Pro FX.midi.xml @@ -1,8 +1,8 @@ - + Numark Mixtrack Pro FX - bad1dea5, h67ma, photoenix + h67ma, bad1dea5, photoenix Mapping for the Numark Mixtrack Pro FX https://mixxx.discourse.group/t/numark-mixtrack-pro-fx/19561 numark_mixtrack_pro_fx From 6dd0381c4a6f6407d1b9e95c5356e88af2af54d1 Mon Sep 17 00:00:00 2001 From: h67ma Date: Thu, 19 Aug 2021 01:31:28 +0200 Subject: [PATCH 46/52] moved a line at the beginning, changed some comments --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index f560d0932d1..a6646b98c0d 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -1,6 +1,3 @@ -// dim all lights when inactive instead of turning them off -components.Button.prototype.off = 0x01; - var MixtrackProFX = {}; // pitch ranges @@ -52,7 +49,10 @@ MixtrackProFX.beatJumpValues = [ "8_" ]; -// pad modes, don't touch +// dim all lights when inactive instead of turning them off +components.Button.prototype.off = 0x01; + +// pad modes control codes MixtrackProFX.PadModeControls = { HOTCUE: 0x00, AUTOLOOP: 0x0D, @@ -62,7 +62,7 @@ MixtrackProFX.PadModeControls = { SAMPLE2: 0x0F }; -// state variables, don't touch +// state variable, don't touch MixtrackProFX.shifted = false; MixtrackProFX.init = function() { From a8629db55f8e7e353d19f407d52646c86da70c8a Mon Sep 17 00:00:00 2001 From: h67ma Date: Sat, 21 Aug 2021 19:51:04 +0200 Subject: [PATCH 47/52] moved pad mode led initialization to PadSection constructor --- .../Numark-Mixtrack-Pro-FX-scripts.js | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index a6646b98c0d..ba714e72137 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -66,18 +66,6 @@ MixtrackProFX.PadModeControls = { MixtrackProFX.shifted = false; MixtrackProFX.init = function() { - // initialize component containers - MixtrackProFX.deck = new components.ComponentContainer(); - MixtrackProFX.effect = new components.ComponentContainer(); - var i; - for (i = 0; i < 2; i++) { - MixtrackProFX.deck[i] = new MixtrackProFX.Deck(i + 1); - MixtrackProFX.effect[i] = new MixtrackProFX.EffectUnit(i + 1); - } - - MixtrackProFX.browse = new MixtrackProFX.Browse(); - MixtrackProFX.gains = new MixtrackProFX.Gains(); - // send sysexes var exitDemoSysex = [0xF0, 0x7E, 0x00, 0x06, 0x01, 0xF7]; midi.sendSysexMsg(exitDemoSysex, exitDemoSysex.length); @@ -89,18 +77,18 @@ MixtrackProFX.init = function() { var faderCutSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0xF7]; midi.sendSysexMsg(faderCutSysex, faderCutSysex.length); - // initialize leds + // initialize component containers + MixtrackProFX.deck = new components.ComponentContainer(); + MixtrackProFX.effect = new components.ComponentContainer(); + var i; for (i = 0; i < 2; i++) { - midi.sendShortMsg(0x94 + i, 0x00, 0x7F); // hotcue - midi.sendShortMsg(0x94 + i, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x94 + i, 0x07, 0x01); // "fader cuts" - midi.sendShortMsg(0x94 + i, 0x0B, 0x01); // sample1 - - // shifted leds - midi.sendShortMsg(0x94 + i, 0x0F, 0x01); // sample2 - midi.sendShortMsg(0x94 + i, 0x02, 0x01); // beatjump + MixtrackProFX.deck[i] = new MixtrackProFX.Deck(i + 1); + MixtrackProFX.effect[i] = new MixtrackProFX.EffectUnit(i + 1); } + MixtrackProFX.browse = new MixtrackProFX.Browse(); + MixtrackProFX.gains = new MixtrackProFX.Gains(); + engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); @@ -457,6 +445,16 @@ MixtrackProFX.PadSection = function(deckNumber) { this.blinkTimer = 0; this.blinkLedState = true; + // initialize leds + midi.sendShortMsg(0x93 + deckNumber, 0x00, 0x7F); // hotcue + midi.sendShortMsg(0x93 + deckNumber, 0x0D, 0x01); // auto loop + midi.sendShortMsg(0x93 + deckNumber, 0x07, 0x01); // "fader cuts" + midi.sendShortMsg(0x93 + deckNumber, 0x0B, 0x01); // sample1 + + // shifted leds + midi.sendShortMsg(0x93 + deckNumber, 0x0F, 0x01); // sample2 + midi.sendShortMsg(0x93 + deckNumber, 0x02, 0x01); // beatjump + this.modes = {}; this.modes[MixtrackProFX.PadModeControls.HOTCUE] = new MixtrackProFX.ModeHotcue(deckNumber); this.modes[MixtrackProFX.PadModeControls.AUTOLOOP] = new MixtrackProFX.ModeAutoLoop(deckNumber); From 60f608494d2f974303dfd7806b5087092a2481c3 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sat, 21 Aug 2021 19:58:29 +0200 Subject: [PATCH 48/52] simplified scratch btn light logic --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index ba714e72137..af0609a228d 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -379,16 +379,11 @@ MixtrackProFX.Deck = function(number) { deck.scratchModeEnabled = !deck.scratchModeEnabled; // change the scratch mode status light - midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); + this.send(deck.scratchModeEnabled ? this.on : this.off); }; // set current scratch mode status light - midi.sendShortMsg(this.midi[0], this.midi[1], deck.scratchModeEnabled ? this.on : this.off); - - // reverseroll is now disabled (because shift is not held down), disable shifted light. - // when shifting the light will be connected to reverseroll. sending this midi here - // prevents the light from blinking when shifting in some cases. - midi.sendShortMsg(this.midi[0], this.midi[1] + this.shiftOffset, this.off); + this.send(deck.scratchModeEnabled ? this.on : this.off); }, shiftControl: true, sendShifted: true, From 1a9c8d7e179d66c1945f2f5a503754fb31f5f426 Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 22 Aug 2021 14:49:29 +0200 Subject: [PATCH 49/52] removed redundant group properties in deck components --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index af0609a228d..eacbe6bdd4a 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -226,7 +226,6 @@ MixtrackProFX.Deck = function(number) { }); this.tap = new components.Button({ - group: this.currentDeck, key: "bpm_tap", midi: [0x88, 0x09] }); @@ -242,7 +241,6 @@ MixtrackProFX.Deck = function(number) { }); this.volume = new components.Pot({ - group: this.currentDeck, inKey: "volume" }); From 45a50b079898b79551d079c251f8e7fe1efb62ae Mon Sep 17 00:00:00 2001 From: h67ma Date: Sun, 22 Aug 2021 15:05:26 +0200 Subject: [PATCH 50/52] refactoring of midi codes in PadSection lights --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index eacbe6bdd4a..d9a3b054d1b 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -439,14 +439,16 @@ MixtrackProFX.PadSection = function(deckNumber) { this.blinkLedState = true; // initialize leds - midi.sendShortMsg(0x93 + deckNumber, 0x00, 0x7F); // hotcue - midi.sendShortMsg(0x93 + deckNumber, 0x0D, 0x01); // auto loop - midi.sendShortMsg(0x93 + deckNumber, 0x07, 0x01); // "fader cuts" - midi.sendShortMsg(0x93 + deckNumber, 0x0B, 0x01); // sample1 + var ledOff = components.Button.prototype.off; + var ledOn = components.Button.prototype.on; + midi.sendShortMsg(0x93 + deckNumber, 0x00, ledOn); // hotcue + midi.sendShortMsg(0x93 + deckNumber, 0x0D, ledOff); // auto loop + midi.sendShortMsg(0x93 + deckNumber, 0x07, ledOff); // "fader cuts" + midi.sendShortMsg(0x93 + deckNumber, 0x0B, ledOff); // sample1 // shifted leds - midi.sendShortMsg(0x93 + deckNumber, 0x0F, 0x01); // sample2 - midi.sendShortMsg(0x93 + deckNumber, 0x02, 0x01); // beatjump + midi.sendShortMsg(0x93 + deckNumber, 0x0F, ledOff); // sample2 + midi.sendShortMsg(0x93 + deckNumber, 0x02, ledOff); // beatjump this.modes = {}; this.modes[MixtrackProFX.PadModeControls.HOTCUE] = new MixtrackProFX.ModeHotcue(deckNumber); From 8b7a3b9061b91a078101d4392aeac51696afc048 Mon Sep 17 00:00:00 2001 From: h67ma Date: Wed, 1 Sep 2021 20:04:59 +0200 Subject: [PATCH 51/52] moved status sysex after components creation --- res/controllers/Numark-Mixtrack-Pro-FX-scripts.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index d9a3b054d1b..3b8dc70962a 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -66,13 +66,10 @@ MixtrackProFX.PadModeControls = { MixtrackProFX.shifted = false; MixtrackProFX.init = function() { - // send sysexes + // disable demo lightshow var exitDemoSysex = [0xF0, 0x7E, 0x00, 0x06, 0x01, 0xF7]; midi.sendSysexMsg(exitDemoSysex, exitDemoSysex.length); - var statusSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0x01, 0xF7]; - midi.sendSysexMsg(statusSysex, statusSysex.length); - // enables 4 bottom pads "fader cuts" var faderCutSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0xF7]; midi.sendSysexMsg(faderCutSysex, faderCutSysex.length); @@ -89,6 +86,9 @@ MixtrackProFX.init = function() { MixtrackProFX.browse = new MixtrackProFX.Browse(); MixtrackProFX.gains = new MixtrackProFX.Gains(); + var statusSysex = [0xF0, 0x00, 0x20, 0x7F, 0x03, 0x01, 0xF7]; + midi.sendSysexMsg(statusSysex, statusSysex.length); + engine.makeConnection("[Channel1]", "VuMeter", MixtrackProFX.vuCallback); engine.makeConnection("[Channel2]", "VuMeter", MixtrackProFX.vuCallback); From 3b7c39cf67616eda57be0b5ab4fa36bae32e7bff Mon Sep 17 00:00:00 2001 From: h67ma Date: Sat, 4 Sep 2021 18:41:57 +0200 Subject: [PATCH 52/52] changed the behavior of reloop --- .../Numark-Mixtrack-Pro-FX-scripts.js | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js index 3b8dc70962a..29b9b76d7b3 100644 --- a/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js +++ b/res/controllers/Numark-Mixtrack-Pro-FX-scripts.js @@ -290,21 +290,24 @@ MixtrackProFX.Deck = function(number) { this.loop = new components.Button({ outKey: "loop_enabled", midi: [0x94 + channel, 0x40], - shift: function() { - this.inKey = "loop_in_goto"; - this.input = components.Button.prototype.input; - }, - unshift: function() { - this.input = function(channel, control, value, status, group) { - if (!this.isPress(channel, control, value)) { - return; - } + input: function(channel, control, value, status, group) { + if (!this.isPress(channel, control, value)) { + return; + } + + if (!MixtrackProFX.shifted) { if (engine.getValue(group, "loop_enabled") === 0) { script.triggerControl(group, "beatloop_activate"); } else { script.triggerControl(group, "beatlooproll_activate"); } - }; + } else { + if (engine.getValue(group, "loop_enabled") === 0) { + script.triggerControl(group, "reloop_toggle"); + } else { + script.triggerControl(group, "reloop_andstop"); + } + } }, shiftControl: true, sendShifted: true,