From 7f43a2abeec58801ad62cb278f707078519de639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Mon, 9 Apr 2018 18:33:30 +0200 Subject: [PATCH 01/11] Roland DJ-202: Map slip button --- res/controllers/Roland_DJ-202.midi.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index ec8827eceb7..8d74798ec80 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -547,6 +547,15 @@ + + [Channel1] + slip_enabled + 0x90 + 0x07 + + + + [Channel1] From 62044ae0ce8d94d8e128fac1e2a2fe902bd5f73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Mon, 9 Apr 2018 18:37:55 +0200 Subject: [PATCH 02/11] Roland DJ-202: Map tap tempo button --- res/controllers/Roland_DJ-202-scripts.js | 7 ++++++- res/controllers/Roland_DJ-202.midi.xml | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index d909ed764a5..c89dbbe0326 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -198,9 +198,14 @@ DJ202.Deck = function (deckNumbers, offset) { type: components.Button.prototype.types.toggle, inKey: 'pfl', outKey: 'pfl', - // missing: shift -> TAP }); + this.tapBPM = function (channel, control, value, status, group) { + if (value == 127) { + bpm.tapButton(script.deckFromGroup(this.currentDeck)); + } + }; + this.volume = new components.Pot({ midi: [0xB0 + offset, 0x1C], inKey: 'volume', diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index 8d74798ec80..9364ac69a3f 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -611,6 +611,15 @@ + + [Channel1] + DJ202.leftDeck.tapBPM + 0x90 + 0x12 + + + + [Channel1] DJ202.leftDeck.volume.input From 6d07b1eb989d3a6892cc6df12baced683a1bde78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Mon, 9 Apr 2018 18:41:29 +0200 Subject: [PATCH 03/11] Roland DJ-202: Support strip search --- res/controllers/Roland_DJ-202-scripts.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index c89dbbe0326..e159fe66233 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -98,7 +98,7 @@ DJ202.Deck = function (deckNumbers, offset) { // ============================= JOG WHEELS ================================= this.wheelTouch = function (channel, control, value, status, group) { - if (value === 0x7F) { + if (value === 0x7F && !this.isShifted) { var alpha = 1.0/8; var beta = alpha/32; engine.scratchEnable(script.deckFromGroup(this.currentDeck), 512, 45, alpha, beta); @@ -109,8 +109,14 @@ DJ202.Deck = function (deckNumbers, offset) { this.wheelTurn = function (channel, control, value, status, group) { var newValue = value - 64; - if (engine.isScratching(1)) { - engine.scratchTick(script.deckFromGroup(this.currentDeck), newValue); // Scratch! + var deck = script.deckFromGroup(this.currentDeck); + if (engine.isScratching(deck)) { + engine.scratchTick(deck, newValue); // Scratch! + } else if (this.isShifted) { + // Strip search. + var oldPos = engine.getValue(this.currentDeck, 'playposition'); + var newPos = Math.max(0, oldPos + newValue / 0xff); + engine.setValue(this.currentDeck, 'playposition', newPos); } else { engine.setValue(this.currentDeck, 'jog', newValue); // Pitch bend } From aae792e281cccabf3746b0920ccdd4037c666763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Tue, 10 Apr 2018 17:54:33 +0200 Subject: [PATCH 04/11] Roland DJ-202: Map shifted FX inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the shift button applies both to the FX racks as well as the decks, the button is now a property of the controller instance. - Shift+FX₁{1…4} ⇒ Cycle selected effect - Shift+Level-knob ⇒ Control FX rack super knob --- res/controllers/Roland_DJ-202-scripts.js | 93 ++++++++++++++++-------- res/controllers/Roland_DJ-202.midi.xml | 2 +- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index e159fe66233..55c6907623c 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -4,9 +4,18 @@ DJ202.tempoRange = [0.08, 0.16, 0.5] DJ202.init = function () { + DJ202.shiftButton = function (channel, control, value, status, group) { + DJ202.deck.concat(DJ202.effectUnit).forEach( + value + ? function (module) { module.shift(); } + : function (module) { module.unshift(); } + ); + }; + DJ202.leftDeck = new DJ202.Deck([1,3], 0); DJ202.rightDeck = new DJ202.Deck([2,4], 1); - + DJ202.deck = [DJ202.leftDeck, DJ202.rightDeck]; + DJ202.effectUnit = []; DJ202.effectUnit[1] = new DJ202.EffectUnit(1); DJ202.effectUnit[2] = new DJ202.EffectUnit(2); @@ -43,14 +52,6 @@ DJ202.Deck = function (deckNumbers, offset) { components.Deck.call(this, deckNumbers); channel = offset+1; - this.shiftButton = function (channel, control, value, status, group) { - if (value === 127) { - this.shift(); - } else { - this.unshift(); - } - }; - this.loadTrack = new components.Button({ midi: [0x9F, 0x02 + offset], unshift: function () { @@ -237,6 +238,20 @@ DJ202.EffectUnit = function (unitNumber) { this.group = '[EffectRack1_EffectUnit' + unitNumber + ']'; engine.setValue(this.group, 'show_focus', 1); + this.shift = function () { + this.button.forEach(function (button) { + button.shift(); + }); + this.knob.shift(); + }; + + this.unshift = function () { + this.button.forEach(function (button) { + button.unshift(); + }); + this.knob.unshift(); + }; + this.EffectButton = function (buttonNumber) { this.buttonNumber = buttonNumber; @@ -246,33 +261,41 @@ DJ202.EffectUnit = function (unitNumber) { components.Button.call(this); }; this.EffectButton.prototype = new components.Button({ - input: function (channel, control, value, status) { - if (this.isPress(channel, control, value, status)) { - this.isLongPressed = false; - this.longPressTimer = engine.beginTimer(this.longPressTimeout, function () { - var effectGroup = '[EffectRack1_EffectUnit' + unitNumber + '_Effect' + this.buttonNumber + ']'; - script.toggleControl(effectGroup, 'enabled'); - this.isLongPressed = true; - }, true); - } else { - if (!this.isLongPressed) { - var focusedEffect = engine.getValue(eu.group, 'focused_effect'); - if (focusedEffect === this.buttonNumber) { - engine.setValue(eu.group, 'focused_effect', 0); - } else { - engine.setValue(eu.group, 'focused_effect', this.buttonNumber); + unshift: function() { + this.input = function (channel, control, value, status) { + if (this.isPress(channel, control, value, status)) { + this.isLongPressed = false; + this.longPressTimer = engine.beginTimer(this.longPressTimeout, function () { + var effectGroup = '[EffectRack1_EffectUnit' + unitNumber + '_Effect' + this.buttonNumber + ']'; + script.toggleControl(effectGroup, 'enabled'); + this.isLongPressed = true; + }, true); + } else { + if (!this.isLongPressed) { + var focusedEffect = engine.getValue(eu.group, 'focused_effect'); + if (focusedEffect === this.buttonNumber) { + engine.setValue(eu.group, 'focused_effect', 0); + } else { + engine.setValue(eu.group, 'focused_effect', this.buttonNumber); + } } + this.isLongPressed = false; + engine.stopTimer(this.longPressTimer); } - this.isLongPressed = false; - engine.stopTimer(this.longPressTimer); } + this.outKey = 'focused_effect'; + this.output = function (value, group, control) { + this.send((value === this.buttonNumber) ? this.on : this.off); + }; + this.sendShifted = true; + this.shiftOffset = 0x0B; }, - outKey: 'focused_effect', - output: function (value, group, control) { - this.send((value === this.buttonNumber) ? this.on : this.off); - }, - sendShifted: true, - shiftOffset: 0x0B, + shift: function () { + this.input = function (channel, control, value, status) { + var group = '[EffectRack1_EffectUnit' + unitNumber + '_Effect' + this.buttonNumber + ']'; + script.toggleControl(group, 'next_effect'); + }; + } }); this.button = []; @@ -298,6 +321,12 @@ DJ202.EffectUnit = function (unitNumber) { } }; }, + shift: function() { + this.input = function (channel, control, value, status) { + var group = '[EffectRack1_EffectUnit' + unitNumber + ']'; + engine.setParameter(group, 'super1', value / 0x7f); + } + } }); this.knobSoftTakeoverHandler = engine.makeConnection(eu.group, 'focused_effect', function (value, group, control) { diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index 9364ac69a3f..506b4db3cf9 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -15,7 +15,7 @@ [Channel1] - DJ202.leftDeck.shiftButton + DJ202.shiftButton 0x9F 0x00 From 9b14c845f8363baf65550ef22f995da2d3e214ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Tue, 10 Apr 2018 18:22:06 +0200 Subject: [PATCH 05/11] Roland DJ-202: Map FX-rack headphones cue --- res/controllers/Roland_DJ-202-scripts.js | 17 +++++++++++++++++ res/controllers/Roland_DJ-202.midi.xml | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index 55c6907623c..c2d4541cf28 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -307,6 +307,23 @@ DJ202.EffectUnit = function (unitNumber) { engine.softTakeover(eu.group, 'mix', true); } + this.headphones = new components.Button({ + group: '[EffectRack1_EffectUnit' + unitNumber + ']', + midi: [0x98, 0x04], + unshift: function() { + this.outKey = 'group_[Headphone]_enable'; + this.inKey = this.outKey; + this.input = function (channel, control, value, status) { + // FIXME Trigger *after* release, to work-around the device + // disabling the LED on release. Refactor this once a customized + // ‘Button’ class is available. + if (!value) { + script.toggleControl(this.group, this.outKey); + }; + }; + } + }); + this.knob = new components.Pot({ unshift: function () { this.input = function (channel, control, value, status) { diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index 506b4db3cf9..a6c5c095812 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -528,6 +528,15 @@ + + [Channel1] + DJ202.effectUnit[1].headphones.input + 0x98 + 0x04 + + + + [Channel1] From 0bd482c7ae00edaadcf697de179134461388fd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Tue, 10 Apr 2018 21:15:23 +0200 Subject: [PATCH 06/11] Roland DJ-202: Map beat grid functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Shift+Cue (“tap tempo”), short ⇒ tap tempo, align beat grid to play-back position - Shift+Cue (“tap tempo”), long ⇒ align beat grid to other deck --- res/controllers/Roland_DJ-202-scripts.js | 18 +++++++++++++++--- res/controllers/Roland_DJ-202.midi.xml | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index c2d4541cf28..5183a7c490b 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -207,11 +207,23 @@ DJ202.Deck = function (deckNumbers, offset) { outKey: 'pfl', }); - this.tapBPM = function (channel, control, value, status, group) { + this.tapBPM = new components.Button({ + input: function (channel, control, value, status, group) { if (value == 127) { - bpm.tapButton(script.deckFromGroup(this.currentDeck)); + script.triggerControl(group, 'beats_translate_curpos'); + bpm.tapButton(script.deckFromGroup(group)); + this.longPressTimer = engine.beginTimer( + this.longPressTimeout, + function () { + script.triggerControl(group, 'beats_translate_match_alignment'); + }, + true + ); + } else { + engine.stopTimer(this.longPressTimer); } - }; + } + }); this.volume = new components.Pot({ midi: [0xB0 + offset, 0x1C], diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index a6c5c095812..c3a598ace5c 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -622,7 +622,7 @@ [Channel1] - DJ202.leftDeck.tapBPM + DJ202.leftDeck.tapBPM.input 0x90 0x12 From 067e97fe77c9fe8e48db12b56d289fbb71714835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Tue, 10 Apr 2018 22:29:48 +0200 Subject: [PATCH 07/11] Roland DJ-202: Map key shift functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Key-Lock (long) + Param{Up,Down} ⇒ Shift musical key - Key-Lock (long) + ParamUp + ParamDown ⇒ Reset musical key --- res/controllers/Roland_DJ-202-scripts.js | 48 ++++++++++++++++++++- res/controllers/Roland_DJ-202.midi.xml | 54 ++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index 5183a7c490b..0e66a46e149 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -62,6 +62,34 @@ DJ202.Deck = function (deckNumbers, offset) { }, }); + this.paramUp = function (channel, control, value, status, group) { + if (value) { + this.paramUp.active = true; + if (this.paramDown.active) { + script.triggerControl(group, 'reset_key'); + } else if (this.keylock.is_held) { + var adjust = engine.getValue(group, 'pitch_adjust'); + engine.setValue(group, 'pitch_adjust', Math.min(7, adjust + 1)); + } + } else { + this.paramUp.active = false; + } + }; + + this.paramDown = function (channel, control, value, status, group) { + if (value) { + this.paramDown.active = true; + if (this.paramUp.active) { + script.triggerControl(group, 'reset_key'); + } else if (this.keylock.is_held) { + var adjust = engine.getValue(group, 'pitch_adjust'); + engine.setValue(group, 'pitch_adjust', Math.max(-7, adjust - 1)); + } + } else { + this.paramDown.active = false; + } + }; + this.keylock = new components.Button({ midi: [0x90 + offset, 0x0D], shiftOffset: 1, @@ -70,9 +98,25 @@ DJ202.Deck = function (deckNumbers, offset) { outKey: 'keylock', currentRangeIndex: 0, unshift: function () { - this.type = components.Button.prototype.types.toggle; - this.input = components.Button.prototype.input; + this.input = function (channel, control, value, status, group) { + if (value) { + this.longPressTimer = engine.beginTimer(this.longPressTimeout, function () { + this.is_held = true; + }, true); + } else { + if (!this.is_held) { + script.toggleControl(this.group, this.outKey); + }; + engine.stopTimer(this.longPressTimer); + this.is_held = false; + } + }; this.inKey = 'keylock'; + this.outKey = 'keylock'; + // The DJ-202 disables the keylock LED when the button is pressed + // shifted. Restore the LED when shift is released. + this.send(this.outGetValue()); + midi.sendShortMsg(0x84, 0x00, 0x3); }, shift: function () { this.inKey = 'rateRange'; diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index c3a598ace5c..c0f37084e8a 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -620,6 +620,60 @@ + + [Channel1] + DJ202.leftDeck.paramDown + 0x94 + 0x42 + + + + + + [Channel1] + DJ202.leftDeck.paramDown + 0x94 + 0x44 + + + + + + [Channel1] + DJ202.leftDeck.paramDown + 0x94 + 0x46 + + + + + + [Channel1] + DJ202.leftDeck.paramUp + 0x94 + 0x41 + + + + + + [Channel1] + DJ202.leftDeck.paramUp + 0x94 + 0x43 + + + + + + [Channel1] + DJ202.leftDeck.paramUp + 0x94 + 0x45 + + + + [Channel1] DJ202.leftDeck.tapBPM.input From 1f111be40c407b09bd7f5993a2ed06070d1afb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Wed, 11 Apr 2018 21:05:15 +0200 Subject: [PATCH 08/11] Roland DJ-202: Replace deprecated control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per the wiki, ‘SelectTrackKnob’ is deprecated. --- res/controllers/Roland_DJ-202-scripts.js | 7 ++----- res/controllers/Roland_DJ-202.midi.xml | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index 0e66a46e149..87c6aee0641 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -30,14 +30,11 @@ DJ202.shutdown = function () { }; DJ202.browseEncoder = new components.Encoder({ - midi: [0xBF, 0x00], - group: '[Playlist]', - inKey: 'SelectTrackKnob', input: function (channel, control, value, status, group) { if (value === 1) { - this.inSetParameter(1); + script.triggerControl(group, 'MoveUp'); } else if (value === 127) { - this.inSetParameter(-1); + script.triggerControl(group, 'MoveDown'); } }, }); diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index c0f37084e8a..83b5d6b1e4c 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -711,7 +711,7 @@ - [Master] + [Library] DJ202.browseEncoder.input 0xBF 0x00 From 8ce5fd168cbeae7b670270dafae20539538c75f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Wed, 11 Apr 2018 21:16:20 +0200 Subject: [PATCH 09/11] Roland DJ-202: Map shifted rotary encoder --- res/controllers/Roland_DJ-202-scripts.js | 7 ++++--- res/controllers/Roland_DJ-202.midi.xml | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index 87c6aee0641..b2430dea932 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -31,12 +31,13 @@ DJ202.shutdown = function () { DJ202.browseEncoder = new components.Encoder({ input: function (channel, control, value, status, group) { + var isShifted = control === 1; if (value === 1) { - script.triggerControl(group, 'MoveUp'); + script.triggerControl(group, isShifted ? 'ScrollUp' : 'MoveUp'); } else if (value === 127) { - script.triggerControl(group, 'MoveDown'); + script.triggerControl(group, isShifted ? 'ScrollDown' : 'MoveDown'); } - }, + } }); DJ202.crossfader = new components.Pot({ diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index 83b5d6b1e4c..1d84b8386e6 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -719,6 +719,15 @@ + + [Library] + DJ202.browseEncoder.input + 0xBF + 0x01 + + + + [Master] DJ202.crossfader.input From 69ea8d895f642089d942d7883160646b1f602154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Wed, 11 Apr 2018 21:28:55 +0200 Subject: [PATCH 10/11] Roland DJ-202: Map rotary encoder button push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Push ⇒ Move focus forward • Shift+Push ⇒ Move focus backward --- res/controllers/Roland_DJ-202-scripts.js | 18 +++++++++++++----- res/controllers/Roland_DJ-202.midi.xml | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index b2430dea932..8e797d95135 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -31,11 +31,19 @@ DJ202.shutdown = function () { DJ202.browseEncoder = new components.Encoder({ input: function (channel, control, value, status, group) { - var isShifted = control === 1; - if (value === 1) { - script.triggerControl(group, isShifted ? 'ScrollUp' : 'MoveUp'); - } else if (value === 127) { - script.triggerControl(group, isShifted ? 'ScrollDown' : 'MoveDown'); + var isShifted = control % 2 != 0; + switch (status) { + case 0xBF: // Rotate. + if (value === 1) { + script.triggerControl(group, isShifted ? 'ScrollUp' : 'MoveUp'); + } else if (value === 127) { + script.triggerControl(group, isShifted ? 'ScrollDown' : 'MoveDown'); + } + break; + case 0x9F: // Push. + if (value) { + script.triggerControl(group, isShifted ? 'MoveFocusBackward' : 'MoveFocusForward'); + } } } }); diff --git a/res/controllers/Roland_DJ-202.midi.xml b/res/controllers/Roland_DJ-202.midi.xml index 1d84b8386e6..d8e072fc68b 100644 --- a/res/controllers/Roland_DJ-202.midi.xml +++ b/res/controllers/Roland_DJ-202.midi.xml @@ -728,6 +728,24 @@ + + [Library] + DJ202.browseEncoder.input + 0x9F + 0x06 + + + + + + [Library] + DJ202.browseEncoder.input + 0x9F + 0x07 + + + + [Master] DJ202.crossfader.input From 3b2e934f38c0251396843dd1de77b4d23a5c0917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Date: Wed, 11 Apr 2018 22:07:48 +0200 Subject: [PATCH 11/11] Roland DJ-202: Map BPM reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Sync-Button (double-tap) ⇒ Reset deck BPM to file BPM --- res/controllers/Roland_DJ-202-scripts.js | 55 +++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/res/controllers/Roland_DJ-202-scripts.js b/res/controllers/Roland_DJ-202-scripts.js index 8e797d95135..813747e00c8 100644 --- a/res/controllers/Roland_DJ-202-scripts.js +++ b/res/controllers/Roland_DJ-202-scripts.js @@ -227,7 +227,60 @@ DJ202.Deck = function (deckNumbers, offset) { // ============================= TRANSPORT ================================== this.play = new components.PlayButton([0x90 + offset, 0x00]); // LED doesn't stay on this.cue = new components.CueButton([0x90 + offset, 0x01]); - this.sync = new components.SyncButton([0x90 + offset, 0x02]); // doesn't work properly + var SyncButton = function (options) { + components.SyncButton.call(this, options); + }; + + SyncButton.prototype = new components.SyncButton({ + doubleTapTimeout: 500, + unshift: function () { + this.input = function (channel, control, value, status, group) { + if (this.isPress(channel, control, value, status)) { + if (this.isDoubleTap) { + var fileBPM = engine.getValue(this.group, 'file_bpm'); + engine.setValue(this.group, 'bpm', fileBPM); + } else if (engine.getValue(this.group, 'sync_enabled') === 0) { + engine.setValue(this.group, 'beatsync', 1); + this.longPressTimer = engine.beginTimer(this.longPressTimeout, function () { + engine.setValue(this.group, 'sync_enabled', 1); + this.longPressTimer = 0; + }, true); + this.isDoubleTap = true; // For the next call. + this.doubleTapTimer = engine.beginTimer(this.doubleTapTimeout, function () { + this.isDoubleTap = false; + }, true); + } else { + engine.setValue(this.group, 'sync_enabled', 0); + }; + } else { + if (this.longPressTimer !== 0) { + engine.stopTimer(this.longPressTimer); + this.longPressTimer = 0; + }; + // Apparently some DJ-202 button LEDS reset themselves when + // a button is released, so we need to re-enable the LED + // again. + if(engine.getValue(group, 'sync_enabled')) { + midi.sendShortMsg(0x90 + offset, 0x02, 0x7f); + } + }; + }; + + var ledControl = engine.getValue(this.group, 'sync_enabled') ? 0x02 : 0x03; + this.output = function (value, group, control) { + // To disable the sync LED, the note must be shifted. This + // corresponds to the DJ-202 surface, which has sync off on the + // shift layer. + midi.sendShortMsg(0x90 + offset, ledControl, 0x7f); + }; + // Pressing shift + sync off on the controller will disable the sync + // LED even when sync is still enabled within mixxx. + midi.sendShortMsg(0x90 + offset, ledControl, 0x7f); + }, + + }); + + this.sync = new SyncButton(); // =============================== MIXER ==================================== this.pregain = new components.Pot({