Skip to content

Instantly share code, notes, and snippets.

@tancredi
Last active July 16, 2022 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tancredi/483ef5a0cf8097f3581821ba934a485e to your computer and use it in GitHub Desktop.
Save tancredi/483ef5a0cf8097f3581821ba934a485e to your computer and use it in GitHub Desktop.
DDJ-200-alternative-mappings
<?xml version='1.0' encoding='utf-8'?>
<MixxxControllerPreset schemaVersion="1" mixxxVersion="2.0.0+">
<info>
<name>Pioneer DDJ-200 (Alternative)</name>
<author>Dan Giddins, Frank.Breitling at gmx.de, Geovanni Pacheco</author>
<description>2-deck USB and Bluetooth MIDI controller with support for 4-deck mode.</description>
<forum>https://mixxx.discourse.group/t/pioneer-ddj-200-mapping/18259</forum>
<manual>pioneer_ddj_200_alternative</manual>
</info>
<controller id="DDJ-200 ALT">
<scriptfiles>
<file functionprefix="DDJ200" filename="Pioneer-DDJ-200-Alternative-scripts.js"/>
</scriptfiles>
<controls>
<control>
<group>[Master]</group>
<key>crossfader</key>
<description>Master crossfader</description>
<status>0xB6</status>
<midino>0x1F</midino>
<options>
<soft-takeover/>
<fourteen-bit-msb/>
</options>
</control>
<control>
<group>[Master]</group>
<key>crossfader</key>
<description>Master crossfader</description>
<status>0xB6</status>
<midino>0x3F</midino>
<options>
<soft-takeover/>
<fourteen-bit-lsb/>
</options>
</control>
<control>
<group>[Master]</group>
<key>DDJ200.headmix</key>
<description>Headphones master as headMix knob</description>
<status>0x96</status>
<midino>0x63</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Master]</group>
<key>DDJ200.toggleFourDeckMode</key>
<description>Headphones master + shift</description>
<status>0x96</status>
<midino>0x78</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.shiftLeft</key>
<description>Deck 1: Shift pressed</description>
<status>0x90</status>
<midino>0x3F</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.shiftRight</key>
<description>Deck 2: Shift pressed</description>
<status>0x91</status>
<midino>0x3F</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.pfl</key>
<description>Deck 1: Headphone listen (pfl) button</description>
<status>0x90</status>
<midino>0x54</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.toggleDeck</key>
<description>Deck 1: Headphone (pfl) + shift</description>
<status>0x90</status>
<midino>0x68</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.pfl</key>
<description>Deck 2: Headphone listen (pfl) button</description>
<status>0x91</status>
<midino>0x54</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.toggleDeck</key>
<description>Deck 2: Headphone (pfl) + shift</description>
<status>0x91</status>
<midino>0x68</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.syncEnabled</key>
<description>Deck 1: Tap to sync tempo (and phase with quantize enabled), hold to enable permanent sync</description>
<status>0x90</status>
<midino>0x58</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.syncEnabled</key>
<description>Deck 2: Tap to sync tempo (and phase with quantize enabled), hold to enable permanent sync</description>
<status>0x91</status>
<midino>0x58</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.seek</key>
<description>Deck 2: Seek</description>
<status>0xB1</status>
<midino>0x29</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.seek</key>
<description>Deck 1: Seek</description>
<status>0xB0</status>
<midino>0x29</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[AutoDJ]</group>
<key>DDJ200.changePadMode</key>
<description>Change Pad mode</description>
<status>0x96</status>
<midino>0x59</midino>
<options>
<script-binding/>
</options>
</control>
<!--<control>
<group>[AutoDJ]</group>
<key>fade_now</key>
<description>Trigger the transition to the next track</description>
<status>0x96</status>
<midino>0x5A</midino>
<options>
<normal/>
</options>
</control>-->
<control>
<group>[Channel2]</group>
<key>DDJ200.touch</key>
<description>Deck 2: Touch</description>
<status>0x91</status>
<midino>0x36</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.touch</key>
<description>Deck 1: Touch</description>
<status>0x90</status>
<midino>0x36</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<!--key>parameter1</key-->
<key>DDJ200.eq</key>
<description>Deck 1: Adjust Low EQ</description>
<status>0xB0</status>
<midino>0x0F</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<key>parameter1</key>
<description>Deck 1: Adjust Low EQ</description>
<status>0xB0</status>
<midino>0x2F</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<!--key>parameter2</key-->
<key>DDJ200.eq</key>
<description>Deck 1: Adjust Mid EQ</description>
<status>0xB0</status>
<midino>0x0B</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<key>parameter2</key>
<description>Deck 1: Adjust Mid EQ</description>
<status>0xB0</status>
<midino>0x2B</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<key>DDJ200.eq</key>
<!--key>parameter3</key-->
<description>Deck 1: Adjust High EQ</description>
<status>0xB0</status>
<midino>0x07</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<key>parameter3</key>
<description>Deck 1: Adjust High EQ</description>
<status>0xB0</status>
<midino>0x27</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[QuickEffectRack1_[Channel1]]</group>
<key>DDJ200.super1</key>
<description>Super Knob (msb): control linked effect</description>
<status>0xB6</status>
<midino>0x17</midino>
<!--midino>lsb: 0x37</midino-->
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[EqualizerRack1_[Channel2]_Effect1]</group>
<!--key>parameter1</key-->
<key>DDJ200.eq</key>
<description>Deck 2: Adjust Low EQ</description>
<status>0xB1</status>
<midino>0x0F</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel1]_Effect1]</group>
<key>parameter1</key>
<description>Deck 2: Adjust Low EQ</description>
<status>0xB1</status>
<midino>0x2F</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[EqualizerRack1_[Channel2]_Effect1]</group>
<!--key>parameter2</key-->
<key>DDJ200.eq</key>
<description>Deck 2: Adjust Mid EQ</description>
<status>0xB1</status>
<midino>0x0B</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel2]_Effect1]</group>
<key>parameter2</key>
<description>Deck 2: Adjust Mid EQ</description>
<status>0xB1</status>
<midino>0x2B</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[EqualizerRack1_[Channel2]_Effect1]</group>
<!--key>parameter3</key-->
<key>DDJ200.eq</key>
<description>Deck 2: Adjust High EQ</description>
<status>0xB1</status>
<midino>0x07</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<!--control>
<group>[EqualizerRack1_[Channel2]_Effect1]</group>
<key>parameter3</key>
<description>Deck 2: Adjust High EQ</description>
<status>0xB1</status>
<midino>0x27</midino>
<options>
<fourteen-bit-lsb/>
</options>
</control-->
<control>
<group>[QuickEffectRack1_[Channel2]]</group>
<key>DDJ200.super1</key>
<description>Quick Effect: Quick Effect Super Knob (control linked effect parameters)</description>
<status>0xB6</status>
<midino>0x18</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[Channel1]</group>
<key>bpm_tap</key>
<description>Deck 1: BPM tap button</description>
<status>0x90</status>
<midino>0x60</midino>
<options>
<normal/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>bpm_tap</key>
<description>Deck 2: BPM tap button</description>
<status>0x91</status>
<midino>0x60</midino>
<options>
<normal/>
</options>
</control>
<control>
<group>[Channel1]</group>
<!--key>volume</key-->
<key>DDJ200.volumeMSB</key>
<description>Deck 1: Volume Fader</description>
<status>0xB0</status>
<midino>0x13</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.volumeLSB</key>
<description>Deck 1: Volume Fader</description>
<status>0xB0</status>
<midino>0x33</midino>
<options>
<script-binding/>
<!--fourteen-bit-lsb/-->
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.volumeMSB</key>
<description>Deck 2: Volume Fader</description>
<status>0xB1</status>
<midino>0x13</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.volumeLSB</key>
<description>Deck 2: Volume Fader</description>
<status>0xB1</status>
<midino>0x33</midino>
<options>
<script-binding/>
<!--fourteen-bit-lsb/-->
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.play</key>
<description>Deck 1: Play button</description>
<status>0x90</status>
<midino>0x0B</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.play</key>
<description>Deck 2: Play button</description>
<status>0x91</status>
<midino>0x0B</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<!--key>cue_default</key-->
<key>DDJ200.cueDefault</key>
<description>Deck 1: Cue button</description>
<status>0x90</status>
<midino>0x0C</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.cueDefault</key>
<description>Deck 2: Cue button</description>
<status>0x91</status>
<midino>0x0C</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.cueGotoandstop</key>
<description>Deck 1: Go to cue point and stop</description>
<status>0x90</status>
<midino>0x48</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.cueGotoandstop</key>
<description>Deck 2: Go to cue point and stop</description>
<status>0x91</status>
<midino>0x48</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.rateMSB</key>
<description>Deck 1: Playback speed control</description>
<status>0xB0</status>
<midino>0x00</midino>
<options>
<script-binding/>
<soft-takeover/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.rateLSB</key>
<description>Deck 1: Playback speed control</description>
<status>0xB0</status>
<midino>0x20</midino>
<options>
<soft-takeover/>
<script-binding/>
<!--fourteen-bit-lsb/-->
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.rateMSB</key>
<description>Deck 2: Playback speed control</description>
<status>0xB1</status>
<midino>0x00</midino>
<options>
<script-binding/>
<!--fourteen-bit-msb/-->
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.rateLSB</key>
<description>Deck 2: Playback speed control</description>
<status>0xB1</status>
<midino>0x20</midino>
<options>
<script-binding/>
<!--fourteen-bit-lsb/-->
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.jog</key>
<description>Deck 2: Jog</description>
<status>0xB1</status>
<midino>0x21</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.jog</key>
<description>Deck 1: Jog</description>
<status>0xB0</status>
<midino>0x21</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.scratch</key>
<description>Deck 2: Scratch</description>
<status>0xB1</status>
<midino>0x22</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.scratch</key>
<description>Deck 1: Scratch</description>
<status>0xB0</status>
<midino>0x22</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>cue_set</key>
<description>Deck 2: Set cue point</description>
<status>0x91</status>
<midino>0x47</midino>
<options>
<normal/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>cue_set</key>
<description>Deck 1: Set cue point</description>
<status>0x90</status>
<midino>0x47</midino>
<options>
<normal/>
</options>
</control>
<!-- ##### Hotcues ##### -->
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 1, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x00</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 2, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x01</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 3, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x02</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 4, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x03</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 5, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x04</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 6, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x05</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 7, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x06</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 8, Deck 1: Set, preview, jump to</description>
<status>0x97</status>
<midino>0x07</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 1, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x00</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 2, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x01</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 3, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x02</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 4, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x03</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 5, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x04</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 6, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x05</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 7, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x06</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padButtonClicked</key>
<description>Hotcue 8, Deck 2: Set, preview, jump to</description>
<status>0x99</status>
<midino>0x07</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<!--key>hotcue_1_clear</key-->
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 1, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x00</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 2, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x01</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 3, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x02</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 4, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x03</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 5, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x04</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 6, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x05</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 7, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x06</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel1]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 8, Deck 1: Clear</description>
<status>0x98</status>
<midino>0x07</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<!--key>hotcue_1_clear</key-->
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 1, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x00</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 2, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x01</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 3, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x02</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 4, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x03</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 5, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x04</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 6, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x05</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 7, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x06</midino>
<options>
<script-binding/>
</options>
</control>
<control>
<group>[Channel2]</group>
<key>DDJ200.padShiftButtonClicked</key>
<description>Hotcue 8, Deck 2: Clear</description>
<status>0x9A</status>
<midino>0x07</midino>
<options>
<script-binding/>
</options>
</control>
</controls>
<outputs>
<!--output>
<group>[Channel1]</group>
<key>pfl</key>
<description>Deck 1: Headphone listen (pfl) LED</description>
<status>0x90</status>
<midino>0x54</midino>
<on>0x7F</on>
<off>0x00</off>
<minimum>0.5</minimum>
</output>
<output>
<group>[Channel2]</group>
<key>pfl</key>
<description>Deck 2: Headphone listen (pfl) LED</description>
<status>0x91</status>
<midino>0x54</midino>
<on>0x7F</on>
<off>0x00</off>
<minimum>0.5</minimum>
</output-->
</outputs>
</controller>
</MixxxControllerPreset>
var DDJ200 = {
fourDeckMode: false,
vDeckNo: [0, 1, 2], // 0 is just for padding - deck numbers are accessed with 1 and 2
vDeck: {},
shiftPressed: { left: false, right: false },
jogCounter: 0,
padModeIndex: 0,
padModes: ["hotcue", "loop", "slicer"], // "effects", "slicer-loop"
scratchRPM: 200, // 33 + 1 / 3
slicer: {
beatsWindow: 8,
connections: [],
beatsPassed: [0, 0, 0, 0],
previousBeatsPassed: [0, 0, 0, 0],
alreadyJumped: [false, false, false, false],
},
};
DDJ200.init = function () {
for (var i = 1; i <= 4; i++) {
// create associative arrays for 4 virtual decks
this.vDeck[i] = {
syncEnabled: false,
volMSB: 0,
rateMSB: 0,
jogEnabled: true,
};
var vgroup = "[Channel" + i + "]";
// run updateDeckLeds after every track load to set LEDs accordingly
engine.makeConnection(vgroup, "track_loaded", function (ch, vgroup) {
DDJ200.updateDeckLeds(vgroup);
});
// run updateDeckLeds after play/pause track to set LEDs accordingly
engine.makeConnection(vgroup, "play", function (ch, vgroup) {
DDJ200.updateDeckLeds(vgroup);
});
// run updateDeckLeds after sync toogle to set LEDs accordingly
engine.makeConnection(vgroup, "sync_enabled", function (ch, vgroup) {
DDJ200.updateDeckLeds(vgroup);
});
DDJ200.updatePadModeLed();
DDJ200.listemHotcues(vgroup);
// set Pioneer CDJ cue mode for all decks
engine.setValue(vgroup, "cue_cdj", true);
}
DDJ200.LEDsOff();
DDJ200.updateAllLeds();
// start with focus on library for selecting tracks (delay seems required)
engine.beginTimer(
500,
function () {
engine.setValue("[Library]", "MoveFocus", 1);
},
true
);
// query the controller for current control positions on startup
midi.sendSysexMsg(
[0xf0, 0x00, 0x40, 0x05, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x03, 0x01, 0xf7],
12
);
};
DDJ200.updateAllLeds = function () {
DDJ200.updateAllPadLeds();
DDJ200.updatePlayLeds();
};
DDJ200.changePadMode = function (channel, control, value) {
if (value) {
if (getPadMode() === "slicer") {
DDJ200.exitSlicerMode();
}
// only if button pressed, not releases, i.e. value === 0
DDJ200.padModeIndex = (DDJ200.padModeIndex + 1) % DDJ200.padModes.length;
DDJ200.updatePadModeLed();
DDJ200.switchAllChanelsLEDs();
if (getPadMode() === "slicer") {
DDJ200.enterSlicerMode();
}
}
};
DDJ200.switchAllChanelsLEDs = function () {
for (var i = 1; i <= 2; i++) {
DDJ200.switchPadLEDs(i);
}
};
DDJ200.updatePadModeLed = function () {
if (DDJ200.padModeBlinkTimer) {
engine.stopTimer(DDJ200.padModeBlinkTimer);
DDJ200.padModeBlinkTimer = undefined;
}
if (DDJ200.padModeIndex === 2) {
var tunedOn = true;
DDJ200.padModeBlinkTimer = engine.beginTimer(250, function () {
midi.sendShortMsg(0x96, 0x59, 0x7f * (tunedOn = !tunedOn));
});
} else {
midi.sendShortMsg(0x96, 0x59, 0x7f * (DDJ200.padModeIndex === 1));
}
};
DDJ200.listemHotcues = function (vgroup) {
for (var i = 1; i <= 8; i++) {
// run updateDeckLeds after every hotcue update
engine.makeConnection(vgroup, "hotcue_" + i + "_enabled", function (
ch,
vgroup
) {
DDJ200.updateDeckLeds(vgroup);
});
}
};
DDJ200.shutdown = function () {
DDJ200.LEDsOff();
};
DDJ200.LEDsOff = function () {
// turn off LED buttons:
for (var i = 0; i <= 1; i++) {
midi.sendShortMsg(0x96 + i, 0x63, 0x00); // set headphone master
midi.sendShortMsg(0x90 + i, 0x54, 0x00); // pfl headphone
midi.sendShortMsg(0x90 + i, 0x58, 0x00); // beat sync
midi.sendShortMsg(0x90 + i, 0x0b, 0x00); // play
midi.sendShortMsg(0x90 + i, 0x0c, 0x00); // cue
for (var j = 0; j <= 8; j++) {
midi.sendShortMsg(0x97 + 2 * i, j, 0x00); // hotcue
}
}
};
DDJ200.updateDeckLeds = function (vgroup) {
// set LEDs (hotcues, etc.) for the loaded deck
// if controller is switched to this deck
var vDeckNo = getDeckFromGroup(normaliseGroupNumber(vgroup));
var deckNo = vDeckNo % 2 ? 1 : 2;
if (vDeckNo === DDJ200.vDeckNo[deckNo]) {
DDJ200.switchLEDs(vDeckNo);
}
};
DDJ200.loadSelectedTrack = function (channel, control, value, status, group) {
// only if button pressed, not releases, i.e. value === 0
if (value) {
script.triggerControl(
getChannelFromGroup(group),
"LoadSelectedTrack",
true
);
}
};
DDJ200.browseTracks = function (value) {
DDJ200.jogCounter += value - 64;
if (DDJ200.jogCounter > 9) {
engine.setValue("[Library]", "MoveDown", true);
DDJ200.jogCounter = 0;
} else if (DDJ200.jogCounter < -9) {
engine.setValue("[Library]", "MoveUp", true);
DDJ200.jogCounter = 0;
}
};
DDJ200.shiftLeft = function () {
// toggle shift left pressed variable
DDJ200.shiftPressed["left"] = !DDJ200.shiftPressed["left"];
};
DDJ200.shiftRight = function () {
// toggle shift right pressed variable
DDJ200.shiftPressed["right"] = !DDJ200.shiftPressed["right"];
};
DDJ200.jog = function (channel, control, value, status, group) {
// For a control that centers on 0x40 (64):
// Convert value down to +1/-1
// Register the movement
if (DDJ200.shiftPressed["left"]) {
DDJ200.browseTracks(value);
} else {
var deck = getDeckFromGroup(group);
var channel = getChannelFromGroup(group);
if (deck.jogEnabled) {
engine.setValue(channel, "jog", value - 64);
}
}
};
DDJ200.scratch = function (channel, control, value, status, group) {
// For a control that centers on 0x40 (64):
// Convert value down to +1/-1
// Register the movement
engine.scratchTick(DDJ200.vDeckNo[script.deckFromGroup(group)], value - 64);
};
DDJ200.touch = function (channel, control, value, status, group) {
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
if (value) {
DDJ200.vDeck[vDeckNo].realJogEnabled = true;
// enable scratch
var alpha = 1.0 / 8;
engine.scratchEnable(vDeckNo, 128, DDJ200.scratchRPM, alpha, alpha / 32);
// disable jog not to prevent track alignment
DDJ200.vDeck[vDeckNo].jogEnabled = false;
} else {
DDJ200.vDeck[vDeckNo].realJogEnabled = false;
// enable jog after 900 ms again
engine.beginTimer(
900,
function () {
DDJ200.vDeck[vDeckNo].jogEnabled = true;
},
true
);
// disable scratch
engine.scratchDisable(vDeckNo);
}
};
DDJ200.seek = function (channel, control, value, status, group) {
var oldPos = engine.getValue(group, "playposition");
// Since ‘playposition’ is normalized to unity, we need to scale by
// song duration in order for the jog wheel to cover the same amount
// of time given a constant turning angle.
var duration = engine.getValue(group, "duration");
var newPos = Math.max(0, oldPos + ((value - 64) * 0.2) / duration);
var deckNo = script.deckFromGroup(group);
var vgroup = "[Channel" + DDJ200.vDeckNo[deckNo] + "]";
engine.setValue(vgroup, "playposition", newPos); // Strip search
};
DDJ200.headmix = function (channel, control, value) {
// toggle headMix knob between -1 to 1
if (value) {
// do nothing if button is released, i.e. value === 0
var masterMixEnabled = engine.getValue("[Master]", "headMix") >= 0;
engine.setValue("[Master]", "headMix", masterMixEnabled ? -1 : 0);
midi.sendShortMsg(0x96, 0x63, masterMixEnabled ? 0 : 0x7f); // set LED
}
};
DDJ200.toggleFourDeckMode = function (channel, control, value) {
if (value) {
// // only if button pressed, not releases, i.e. value === 0
DDJ200.fourDeckMode = !DDJ200.fourDeckMode;
//
if (DDJ200.fourDeckMode) {
midi.sendShortMsg(0x90, 0x54, 0x00);
midi.sendShortMsg(0x91, 0x54, 0x00);
DDJ200.vDeckNo[1] = 3;
DDJ200.vDeckNo[2] = 4;
} else {
DDJ200.vDeckNo[1] = 1;
DDJ200.vDeckNo[2] = 2;
}
}
DDJ200.updateAllLeds();
};
DDJ200.play = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
var playing = engine.getValue(vgroup, "play");
engine.setValue(vgroup, "play", !playing);
if (engine.getValue(vgroup, "play") === playing) {
engine.setValue(vgroup, "play", !playing);
}
DDJ200.updatePlayLeds();
}
};
DDJ200.syncEnabled = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
var syncEnabled = !engine.getValue(vgroup, "sync_enabled");
DDJ200.vDeck[vDeckNo]["syncEnabled"] = syncEnabled;
engine.setValue(vgroup, "sync_enabled", syncEnabled);
midi.sendShortMsg(status, control, 0x7f * syncEnabled); // set LED
}
};
DDJ200.rateMSB = function (channel, control, value, status, group) {
// store most significant byte value of rate
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
DDJ200.vDeck[vDeckNo]["rateMSB"] = value;
};
DDJ200.rateLSB = function (channel, control, value, status, group) {
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
// calculte rate value from its most and least significant bytes
var rateMSB = DDJ200.vDeck[vDeckNo]["rateMSB"];
var rate = 1 - ((rateMSB << 7) + value) / 0x1fff;
engine.setValue(vgroup, "rate", rate);
};
DDJ200.volumeMSB = function (channel, control, value, status, group) {
// store most significant byte value of volume
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
DDJ200.vDeck[vDeckNo]["volMSB"] = value;
};
DDJ200.volumeLSB = function (channel, control, value, status, group) {
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
// calculte volume value from its most and least significant bytes
var volMSB = DDJ200.vDeck[vDeckNo]["volMSB"];
var vol = ((volMSB << 7) + value) / 0x3fff;
//var vol = ((volMSB << 7) + value); // use for linear correction
//vol = script.absoluteNonLin(vol, 0, 0.25, 1, 0, 0x3FFF);
engine.setValue(vgroup, "volume", vol);
};
DDJ200.eq = function (channel, control, value, status, group) {
var val = script.absoluteNonLin(value, 0, 1, 4);
var eq = control === 0x0b ? 2 : 1;
if (control === 0x07) {
eq = 3;
}
var deckNo = group.substring(24, 25);
// var deckNo = group.match("hannel.")[0].substring(6); // more general
// var deckNo = script.deckFromGroup(group); // working after fix
// https://github.com/mixxxdj/mixxx/pull/3178 only
var vDeckNo = DDJ200.vDeckNo[deckNo];
var vgroup = group.replace("Channel" + deckNo, "Channel" + vDeckNo);
engine.setValue(vgroup, "parameter" + eq, val);
};
DDJ200.super1 = function (channel, control, value, status, group) {
var val = script.absoluteNonLin(value, 0, 0.5, 1);
var deckNo = group.substring(26, 27);
//var deckNo = group.match("hannel.")[0].substring(6); // more general
//var deckNo = script.deckFromGroup(group); // working after fix
// https://github.com/mixxxdj/mixxx/pull/3178 only
var vDeckNo = DDJ200.vDeckNo[deckNo];
var vgroup = group.replace("Channel" + deckNo, "Channel" + vDeckNo);
engine.setValue(vgroup, "super1", val);
};
DDJ200.cueDefault = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
if (DDJ200.vDeck[vDeckNo].realJogEnabled) {
// if jog top is touched
engine.setValue(vgroup, "cue_set", true);
} else {
engine.setValue(vgroup, "cue_gotoandplay", true);
}
var cueSet = engine.getValue(vgroup, "cue_point") !== -1;
midi.sendShortMsg(status, 0x0c, 0x7f * cueSet); // set cue LED
midi.sendShortMsg(
status,
0x0b,
0x7f * engine.getValue(vgroup, "play") // set play LED
);
}
};
DDJ200.cueGotoandstop = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
engine.setValue(vgroup, "cue_gotoandstop", true);
//engine.setValue(vgroup, "start_stop", true); // go to start if preferred
midi.sendShortMsg(status, 0x0b, 0x7f * engine.getValue(vgroup, "play"));
}
};
DDJ200.hotcueNActivate = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vgroup = getChannelFromGroup(group);
var hotcue = "hotcue_" + (control + 1);
var action = engine.getValue(vgroup, hotcue + "_enabled")
? "_gotoandplay"
: "_activate";
engine.setValue(vgroup, hotcue + action, true);
midi.sendShortMsg(
status,
control,
0x7f * engine.getValue(vgroup, hotcue + "_enabled")
);
}
DDJ200.updatePlayLeds();
};
DDJ200.updatePlayLeds = function () {
for (var i = 1; i <= 2; i++) {
midi.sendShortMsg(
0x90 + getPhysicalDeckNumberFromGroup(i) - 1,
0x0b,
0x7f * engine.getValue(getChannelFromGroup(i), "play")
);
}
};
DDJ200.hotcueNClear = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
engine.setValue(vgroup, "hotcue_" + (control + 1) + "_clear", true);
midi.sendShortMsg(status - 1, control, 0x00); // set hotcue LEDs
}
};
DDJ200.repeatNActive = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
var loopSize = getLoopSizeByIndex(control);
var isBeatlooprollActivate = engine.getValue(
vgroup,
"beatlooproll_activate"
);
var currentBeatLoopSize = engine.getValue(vgroup, "beatloop_size");
if (currentBeatLoopSize === loopSize) {
engine.setValue(vgroup, "beatloop_size", 0);
engine.setValue(vgroup, "beatlooproll_activate", false);
engine.setValue(vgroup, "beatloop_activate", false);
} else {
engine.setValue(vgroup, "beatloop_size", loopSize);
if (!isBeatlooprollActivate) {
engine.setValue(vgroup, "beatloop_activate", true);
}
}
DDJ200.switchPadLEDs(vDeckNo);
}
};
DDJ200.rollRepeatN = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)];
var vgroup = "[Channel" + vDeckNo + "]";
var isBeatloopActivate = engine.getValue(vgroup, "beatloop_activate");
if (!isBeatloopActivate) {
var loopSize = getLoopSizeByIndex(control);
engine.setValue(vgroup, "beatloop_size", loopSize);
engine.setValue(vgroup, "beatlooproll_activate", true);
DDJ200.switchPadLEDs(vDeckNo);
}
}
};
DDJ200.effectNActive = function (channel, control, value, status, group) {
// d = deckNo - 1
var effectCol = (control + 1) % 4;
var effectRow = Math.floor(control / 4);
if (effectCol) {
var vDeckNo = DDJ200.vDeckNo[script.deckFromGroup(group)] + effectRow * 2;
var d = vDeckNo % 2 ? 0 : 1;
var effectNumber = effectCol;
var effect =
"[EffectRack1_EffectUnit" + vDeckNo + "_Effect" + effectNumber + "]";
engine.setValue(effect, "enabled", value);
midi.sendShortMsg(0x97 + 2 * d, control, value);
}
};
DDJ200.padButtonClicked = function (channel, control, value, status, group) {
var mode = getPadMode();
if (mode === "hotcue") {
DDJ200.hotcueNActivate(channel, control, value, status, group);
} else if (mode === "loop") {
DDJ200.repeatNActive(channel, control, value, status, group);
} else if (mode === "effects") {
DDJ200.effectNActive(channel, control, value, status, group);
} else if (mode === "slicer") {
DDJ200.handleSlicerTap(channel, control, value, status, group);
}
};
DDJ200.padShiftButtonClicked = function (
channel,
control,
value,
status,
group
) {
if (DDJ200.padModes[DDJ200.padModeIndex] === "hotcue") {
DDJ200.hotcueNClear(channel, control, value, status, group);
} else if (DDJ200.padModes[DDJ200.padModeIndex] === "loop") {
DDJ200.rollRepeatN(channel, control, value, status, group);
}
};
DDJ200.pfl = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
var deckNo = script.deckFromGroup(group);
var vDeckNo = DDJ200.vDeckNo[deckNo];
var vgroup = "[Channel" + vDeckNo + "]";
var pfl = !engine.getValue(vgroup, "pfl");
engine.setValue(vgroup, "pfl", pfl);
if (!DDJ200.fourDeckMode) {
midi.sendShortMsg(status, 0x54, 0x7f * pfl); // switch pfl LED
}
}
};
DDJ200.switchLEDs = function (vDeckNo) {
// set LEDs of controller deck 1 or 2 according to virtual deck
var d = vDeckNo % 2 ? 0 : 1; // d = deckNo - 1
var vgroup = "[Channel" + vDeckNo + "]";
midi.sendShortMsg(0x90 + d, 0x0b, 0x7f * engine.getValue(vgroup, "play"));
midi.sendShortMsg(
0x90 + d,
0x0c,
0x7f * (engine.getValue(vgroup, "cue_point") !== -1)
);
midi.sendShortMsg(
0x90 + d,
0x58,
0x7f * engine.getValue(vgroup, "sync_enabled")
);
if (!DDJ200.fourDeckMode) {
midi.sendShortMsg(0x90 + d, 0x54, 0x7f * engine.getValue(vgroup, "pfl"));
}
DDJ200.switchPadLEDs(vDeckNo);
};
DDJ200.updateAllPadLeds = function () {
DDJ200.switchPadLEDs(getDeckNumberFromGroup(1));
DDJ200.switchPadLEDs(getDeckNumberFromGroup(2));
};
DDJ200.switchPadLEDs = function (vDeckNo) {
if (DDJ200.padModes[DDJ200.padModeIndex] === "hotcue") {
DDJ200.switchHotcueLEDs(vDeckNo);
} else if (DDJ200.padModes[DDJ200.padModeIndex] === "loop") {
DDJ200.switchLoopLEDs(vDeckNo);
} else if (DDJ200.padModes[DDJ200.padModeIndex] === "effects") {
DDJ200.switchOffAllPadLEDs(vDeckNo);
} else if (DDJ200.padModes[DDJ200.padModeIndex] === "slicer") {
DDJ200.enterSlicerMode(vDeckNo);
}
};
DDJ200.switchPadLEDsRange = function (vDeckNo, start, end, status) {
for (var i = start; i < end; i++) {
DDJ200.switchPadLED(vDeckNo, i, status);
}
};
DDJ200.switchPadLED = function (vDeckNo, i, status) {
var d = vDeckNo % 2 ? 0 : 1; // d = deckNo - 1
midi.sendShortMsg(0x97 + 2 * d, i, 0x7f * status);
};
DDJ200.switchOffAllPadLEDs = function () {
DDJ200.switchPadLEDsRange(0, 8, 0);
};
DDJ200.switchLoopLEDs = function (vDeckNo) {
var d = vDeckNo % 2 ? 0 : 1; // d = deckNo - 1
var vgroup = "[Channel" + vDeckNo + "]";
var currentBeatLoopSize = engine.getValue(vgroup, "beatloop_size");
var isBeatlooprollActivate = engine.getValue(vgroup, "beatlooproll_activate");
var isBeatloopActivate = engine.getValue(vgroup, "beatloop_activate");
var isAnyLoopActive = isBeatlooprollActivate || isBeatloopActivate;
for (var i = 0; i < 8; i++) {
var loopSize = getLoopSizeByIndex(i);
var loopSizeActive = isAnyLoopActive && currentBeatLoopSize === loopSize;
midi.sendShortMsg(0x97 + 2 * d, i, 0x7f * loopSizeActive);
}
};
DDJ200.switchHotcueLEDs = function (vDeckNo) {
var d = vDeckNo % 2 ? 0 : 1; // d = deckNo - 1
var vgroup = "[Channel" + vDeckNo + "]";
for (var i = 1; i <= 8; i++) {
var hotcueEnabled = engine.getValue(vgroup, "hotcue_" + i + "_enabled");
midi.sendShortMsg(0x97 + 2 * d, i - 1, 0x7f * hotcueEnabled);
}
};
DDJ200.toggleDeck = function (channel, control, value, status, group) {
if (value) {
// only if button pressed, not releases, i.e. value === 0
if (DDJ200.shiftPressed["left"]) {
// left shift + pfl 1/2 does not toggle decks but loads track
DDJ200.loadSelectedTrack(channel, control, value, status, group);
} else if (DDJ200.fourDeckMode) {
//right shift + pfl 1/2 toggles
var deckNo = script.deckFromGroup(group);
var vDeckNo;
var led = 0x7f;
if (deckNo === 1) {
// toggle virtual deck of controller deck 1
DDJ200.vDeckNo[1] = 4 - DDJ200.vDeckNo[1];
if (DDJ200.vDeckNo[1] === 1) {
led = 0;
}
vDeckNo = DDJ200.vDeckNo[1];
} else {
// deckNo === 2
// toggle virtual deck of controller deck 2
DDJ200.vDeckNo[2] = 6 - DDJ200.vDeckNo[2];
if (DDJ200.vDeckNo[2] === 2) {
led = 0;
}
vDeckNo = DDJ200.vDeckNo[2];
}
midi.sendShortMsg(status, 0x54, led); // toggle virtual deck LED
DDJ200.switchLEDs(vDeckNo); // set LEDs of controller deck
}
}
};
DDJ200.slicerBeatCounter = function (group) {
if (
engine.getValue(group, "beat_closest") ===
engine.getValue(group, "beat_next")
) {
return;
}
var deckN = getDeckNumberFromGroup(group);
var deck = getDeckFromGroup(group);
var playposition = engine.getValue(group, "playposition");
var bpm = engine.getValue(group, "bpm");
var duration = engine.getValue(group, "duration");
DDJ200.slicer.beatsPassed[deckN] = Math.round(
playposition * duration * (bpm / 60)
);
var slicerPosInSection = Math.floor(
(DDJ200.slicer.beatsPassed[deckN] % DDJ200.slicer.beatsWindow) /
(DDJ200.slicer.beatsWindow / 8)
);
if (getPadMode === "slicer-loop") {
// jump to loop the slicer section
if (
(DDJ200.slicer.beatsPassed[deckN] - 1) % DDJ200.slicer.beatsWindow ===
DDJ200.slicer.beatsWindow - 1 &&
!DDJ200.slicer.alreadyJumped[deckN] &&
DDJ200.slicer.previousBeatsPassed[deckN] <
DDJ200.slicer.beatsPassed[deckN]
) {
engine.setValue(group, "beatjump", -DDJ200.slicer.beatsWindow);
DDJ200.slicer.alreadyJumped[deckN] = true;
} else {
DDJ200.slicer.alreadyJumped[deckN] = false;
}
}
// light the current position LED
for (var i = 0; i < 8; ++i) {
var toggleLED =
getPadMode === "slicer"
? slicerPosInSection === i
: slicerPosInSection !== i;
DDJ200.switchPadLED(deckN, i, toggleLED ? 1 : 0);
}
};
DDJ200.handleSlicerTap = function (channel, control, value, status, group) {
var isLeftDeck = control <= 8;
var deckN = getDeckNumberFromGroup(group);
var deck = getDeckFromGroup(group);
var channel = getChannelFromGroup(group);
var index = isLeftDeck ? control : control - 8;
var channelStart = isLeftDeck ? 0x94 : 0x95;
var domain = DDJ200.slicer.beatsWindow;
var beatsToJump = 0;
// LED indicator
midi.sendShortMsg(channelStart, 0x20 + index + 1, value ? 0x7f : 0x0);
if (value) {
engine.setValue(channel, "reloop_toggle", 1);
beatsToJump =
index * (domain / 8) - ((DDJ200.slicer.beatsPassed[deckN] % domain) + 1);
if (index === 0 && beatsToJump === -domain) {
beatsToJump = 0;
}
if (
DDJ200.slicer.beatsPassed[deckN] >= Math.abs(beatsToJump) &&
DDJ200.slicer.previousBeatsPassed[deckN] !==
DDJ200.slicer.beatsPassed[deckN]
) {
DDJ200.slicer.previousBeatsPassed[deckN] =
DDJ200.slicer.beatsPassed[deckN];
if (Math.abs(beatsToJump) > 0) {
engine.setValue(channel, "beatjump", beatsToJump);
}
}
}
if (getPadMode() !== "slicer-loop") {
engine.setValue(channel, "slip_enabled", value);
engine.setValue(channel, "beatloop_size", 1);
engine.setValue(channel, "beatloop_activate", value);
}
};
DDJ200.enterSlicerMode = function () {
for (var i = 1; i <= 4; i++) {
var channel = getChannelFromGroup(i);
DDJ200.slicer.connections.push(
engine.makeConnection(channel, "beat_active", function (ch, vgroup) {
DDJ200.slicerBeatCounter(vgroup);
})
);
}
};
DDJ200.exitSlicerMode = function () {
DDJ200.slicer.connections.forEach(function (connection) {
if (connection) {
connection.disconnect();
}
});
DDJ200.slicer.connections = [];
for (var i = 1; i <= 2; i++) {
var deck = getDeckFromGroup(i);
var channel = getChannelFromGroup(i);
engine.setValue(channel, "slip_enabled", false);
engine.setValue(channel, "beatloop_activate", false);
engine.setValue(channel, "beatlooproll_activate", false);
}
};
function getDeckNumberFromGroup(group) {
var groupNo = typeof group === "string" ? script.deckFromGroup(group) : group;
return DDJ200.vDeckNo[groupNo];
}
function getDeckFromGroup(group) {
return DDJ200.vDeck[getDeckNumberFromGroup(group)];
}
function getChannelFromGroup(group) {
return "[Channel" + getDeckNumberFromGroup(group) + "]";
}
function getPhysicalDeckNumberFromGroup(group) {
return script.deckFromGroup(
getChannelFromGroup(normaliseGroupNumber(group))
) % 2
? 1
: 2;
}
function normaliseGroupNumber(group) {
return typeof group === "string" ? group.substring(24, 25) : group;
}
function getLoopSizeByIndex(i) {
return Math.pow(2, i) * 0.25;
}
function getPadMode() {
return DDJ200.padModes[DDJ200.padModeIndex];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment