diff --git a/res/controllers/Soundless_joyMIDI.midi.xml b/res/controllers/Soundless_joyMIDI.midi.xml new file mode 100644 index 00000000000..cb3d68f138a --- /dev/null +++ b/res/controllers/Soundless_joyMIDI.midi.xml @@ -0,0 +1,1227 @@ + + + + Soundless joyMIDI + Ozzy Chiu + Soundless Portable MIDI Controller + https://www.mixxx.org/forums/viewtopic.php?f=7&t=13166 + https://www.mixxx.org/wiki/doku.php/soundless_studio_joymidi + + + + + + + + + [Master] + crossfader + 0xB0 + 0x01 + + + + + + [Master] + joyMIDI.fsr + 0xB0 + 0x02 + + + + + + [Master] + joyMIDI.joystick + 0xB0 + 0x10 + + + + + + [Master] + joyMIDI.joystick + 0xB0 + 0x11 + + + + + + [Master] + joyMIDI.joystick + 0xB0 + 0x12 + + + + + + [Master] + joyMIDI.joystick + 0xB0 + 0x13 + + + + + + [Master] + joyMIDI.gsensor + 0xB0 + 0x14 + + + + + + [Master] + joyMIDI.gsensor + 0xB0 + 0x15 + + + + + + [Master] + joyMIDI.gsensor + 0xB0 + 0x16 + + + + + + [Master] + joyMIDI.gsensor + 0xB0 + 0x17 + + + + + + + + [Channel1] + joyMIDI.wheel + 0xB0 + 0x0E + + + + + + + + [Channel2] + joyMIDI.wheel + 0xB0 + 0x0F + + + + + + + + [Channel1] + joyMIDI.shiftButton + 0x90 + 0x24 + + + + + + [Channel1] + joyMIDI.shiftButton + 0x80 + 0x24 + + + + + + [Channel1] + joyMIDI.syncButton + 0x90 + 0x25 + + + + + + [Channel1] + joyMIDI.syncButton + 0x80 + 0x25 + + + + + + [Channel1] + joyMIDI.cueButton + 0x90 + 0x26 + + + + + + [Channel1] + joyMIDI.cueButton + 0x80 + 0x26 + + + + + + [Channel1] + joyMIDI.playButton + 0x90 + 0x27 + + + + + + [Channel1] + joyMIDI.playButton + 0x80 + 0x27 + + + + + + [Channel1] + joyMIDI.scratchButton + 0x90 + 0x2C + + + + + + [Channel1] + joyMIDI.scratchButton + 0x80 + 0x2C + + + + + + [Channel1] + joyMIDI.keyButton + 0x90 + 0x2D + + + + + + [Channel1] + joyMIDI.keyButton + 0x80 + 0x2D + + + + + + [Channel1] + joyMIDI.beatgridButton + 0x90 + 0x2E + + + + + + [Channel1] + joyMIDI.beatgridButton + 0x80 + 0x2E + + + + + + [Channel1] + joyMIDI.volumeButton + 0x90 + 0x2F + + + + + + [Channel1] + joyMIDI.volumeButton + 0x80 + 0x2F + + + + + + + + [Channel1] + joyMIDI.shiftButton + 0x90 + 0x34 + + + + + + [Channel1] + joyMIDI.shiftButton + 0x80 + 0x34 + + + + + + [Channel1] + joyMIDI.filterLowButton + 0x90 + 0x35 + + + + + + [Channel1] + joyMIDI.filterLowButton + 0x80 + 0x35 + + + + + + [Channel1] + joyMIDI.filterMiddleButton + 0x90 + 0x36 + + + + + + [Channel1] + joyMIDI.filterMiddleButton + 0x80 + 0x36 + + + + + + [Channel1] + joyMIDI.filterHighButton + 0x90 + 0x37 + + + + + + [Channel1] + joyMIDI.filterHighButton + 0x80 + 0x37 + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x90 + 0x3C + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x80 + 0x3C + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x90 + 0x3D + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x80 + 0x3D + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x90 + 0x3E + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x80 + 0x3E + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x90 + 0x3F + + + + + + [Channel1] + joyMIDI.hotcueButton + 0x80 + 0x3F + + + + + + + + [Channel1] + joyMIDI.shiftButton + 0x90 + 0x44 + + + + + + [Channel1] + joyMIDI.shiftButton + 0x80 + 0x44 + + + + + + [Channel1] + joyMIDI.reloopToggleButton + 0x90 + 0x45 + + + + + + [Channel1] + joyMIDI.reloopToggleButton + 0x80 + 0x45 + + + + + + [Channel1] + joyMIDI.loopInButton + 0x90 + 0x46 + + + + + + [Channel1] + joyMIDI.loopInButton + 0x80 + 0x46 + + + + + + [Channel1] + joyMIDI.loopOutButton + 0x90 + 0x47 + + + + + + [Channel1] + joyMIDI.loopOutButton + 0x80 + 0x47 + + + + + + [Channel1] + joyMIDI.loop0p125Button + 0x90 + 0x4C + + + + + + [Channel1] + joyMIDI.loop0p125Button + 0x80 + 0x4C + + + + + + [Channel1] + joyMIDI.loop0p25Button + 0x90 + 0x4D + + + + + + [Channel1] + joyMIDI.loop0p25Button + 0x80 + 0x4D + + + + + + [Channel1] + joyMIDI.loop0p5Button + 0x90 + 0x4E + + + + + + [Channel1] + joyMIDI.loop0p5Button + 0x80 + 0x4E + + + + + + [Channel1] + joyMIDI.loop1Button + 0x90 + 0x4F + + + + + + [Channel1] + joyMIDI.loop1Button + 0x80 + 0x4F + + + + + + + + [Channel1] + joyMIDI.shiftButton + 0x90 + 0x54 + + + + + + [Channel1] + joyMIDI.shiftButton + 0x80 + 0x54 + + + + + + [Channel1] + joyMIDI.loadButton + 0x90 + 0x55 + + + + + + [Channel1] + joyMIDI.loadButton + 0x80 + 0x55 + + + + + + [Sampler1] + joyMIDI.sampler1Button + 0x90 + 0x5C + + + + + + [Sampler1] + joyMIDI.sampler1Button + 0x80 + 0x5C + + + + + + [Sampler2] + joyMIDI.sampler2Button + 0x90 + 0x5D + + + + + + [Sampler2] + joyMIDI.sampler2Button + 0x80 + 0x5D + + + + + + [Channel1] + joyMIDI.fx1Button + 0x90 + 0x5E + + + + + + [Channel1] + joyMIDI.fx1Button + 0x80 + 0x5E + + + + + + [Channel1] + joyMIDI.fx2Button + 0x90 + 0x5F + + + + + + [Channel1] + joyMIDI.fx2Button + 0x80 + 0x5F + + + + + + + + [Channel2] + joyMIDI.shiftButton + 0x90 + 0x28 + + + + + + [Channel2] + joyMIDI.shiftButton + 0x80 + 0x28 + + + + + + [Channel2] + joyMIDI.syncButton + 0x90 + 0x29 + + + + + + [Channel2] + joyMIDI.syncButton + 0x80 + 0x29 + + + + + + [Channel2] + joyMIDI.cueButton + 0x90 + 0x2A + + + + + + [Channel2] + joyMIDI.cueButton + 0x80 + 0x2A + + + + + + [Channel2] + joyMIDI.playButton + 0x90 + 0x2B + + + + + + [Channel2] + joyMIDI.playButton + 0x80 + 0x2B + + + + + + [Channel2] + joyMIDI.scratchButton + 0x90 + 0x30 + + + + + + [Channel2] + joyMIDI.scratchButton + 0x80 + 0x30 + + + + + + [Channel2] + joyMIDI.keyButton + 0x90 + 0x31 + + + + + + [Channel2] + joyMIDI.keyButton + 0x80 + 0x31 + + + + + + [Channel2] + joyMIDI.beatgridButton + 0x90 + 0x32 + + + + + + [Channel2] + joyMIDI.beatgridButton + 0x80 + 0x32 + + + + + + [Channel2] + joyMIDI.volumeButton + 0x90 + 0x33 + + + + + + [Channel2] + joyMIDI.volumeButton + 0x80 + 0x33 + + + + + + + + [Channel2] + joyMIDI.shiftButton + 0x90 + 0x38 + + + + + + [Channel2] + joyMIDI.shiftButton + 0x80 + 0x38 + + + + + + [Channel2] + joyMIDI.filterLowButton + 0x90 + 0x39 + + + + + + [Channel2] + joyMIDI.filterLowButton + 0x80 + 0x39 + + + + + + [Channel2] + joyMIDI.filterMiddleButton + 0x90 + 0x3A + + + + + + [Channel2] + joyMIDI.filterMiddleButton + 0x80 + 0x3A + + + + + + [Channel2] + joyMIDI.filterHighButton + 0x90 + 0x3B + + + + + + [Channel2] + joyMIDI.filterHighButton + 0x80 + 0x3B + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x90 + 0x40 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x80 + 0x40 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x90 + 0x41 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x80 + 0x41 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x90 + 0x42 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x80 + 0x42 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x90 + 0x43 + + + + + + [Channel2] + joyMIDI.hotcueButton + 0x80 + 0x43 + + + + + + + + [Channel2] + joyMIDI.shiftButton + 0x90 + 0x48 + + + + + + [Channel2] + joyMIDI.shiftButton + 0x80 + 0x48 + + + + + + [Channel2] + joyMIDI.reloopToggleButton + 0x90 + 0x49 + + + + + + [Channel2] + joyMIDI.reloopToggleButton + 0x80 + 0x49 + + + + + + [Channel2] + joyMIDI.loopInButton + 0x90 + 0x4A + + + + + + [Channel2] + joyMIDI.loopInButton + 0x80 + 0x4A + + + + + + [Channel2] + joyMIDI.loopOutButton + 0x90 + 0x4B + + + + + + [Channel2] + joyMIDI.loopOutButton + 0x80 + 0x4B + + + + + + [Channel2] + joyMIDI.loop0p125Button + 0x90 + 0x50 + + + + + + [Channel2] + joyMIDI.loop0p125Button + 0x80 + 0x50 + + + + + + [Channel2] + joyMIDI.loop0p25Button + 0x90 + 0x51 + + + + + + [Channel2] + joyMIDI.loop0p25Button + 0x80 + 0x51 + + + + + + [Channel2] + joyMIDI.loop0p5Button + 0x90 + 0x52 + + + + + + [Channel2] + joyMIDI.loop0p5Button + 0x80 + 0x52 + + + + + + [Channel2] + joyMIDI.loop1Button + 0x90 + 0x53 + + + + + + [Channel2] + joyMIDI.loop1Button + 0x80 + 0x53 + + + + + + + + [Channel2] + joyMIDI.shiftButton + 0x90 + 0x58 + + + + + + [Channel2] + joyMIDI.shiftButton + 0x80 + 0x58 + + + + + + [Channel2] + joyMIDI.loadButton + 0x90 + 0x59 + + + + + + [Channel2] + joyMIDI.loadButton + 0x80 + 0x59 + + + + + + [Sampler3] + joyMIDI.sampler3Button + 0x90 + 0x60 + + + + + + [Sampler3] + joyMIDI.sampler3Button + 0x80 + 0x60 + + + + + + [Sampler4] + joyMIDI.sampler4Button + 0x90 + 0x61 + + + + + + [Sampler4] + joyMIDI.sampler4Button + 0x80 + 0x61 + + + + + + [Channel2] + joyMIDI.fx1Button + 0x90 + 0x62 + + + + + + [Channel2] + joyMIDI.fx1Button + 0x80 + 0x62 + + + + + + [Channel2] + joyMIDI.fx2Button + 0x90 + 0x63 + + + + + + [Channel2] + joyMIDI.fx2Button + 0x80 + 0x63 + + + + + + + + diff --git a/res/controllers/Soundless_joyMIDI_scripts.js b/res/controllers/Soundless_joyMIDI_scripts.js new file mode 100644 index 00000000000..0b6f47e263c --- /dev/null +++ b/res/controllers/Soundless_joyMIDI_scripts.js @@ -0,0 +1,710 @@ +/******************************************************************* + * Soundless studio. + * Author: Ozzy Chiu (ozzy.chc@gmail.com) + * Version: 2020-01-17 + * + * Variables on joyMIDI.userSetting can be modified by users to suit their preferences + *******************************************************************/ +var joyMIDI = { + + // User Setting + "userSetting": { + // Enable the knob(button+jog) function + "knobEnable": true, + // Enable the beatloop with roll(1) function otherwise toggle(0) + "beatLoopRollEnable": true, + // Enable the samplers played from cue(1) otherwise from track start(0) + "samplerCueModeEnable": true, + }, + + // Channel1 variable + "[Channel1]": { + btnShift: 0, + btnSync: 0, syncTimerID: null, syncLongPress: 0, + btnScratch: 0, isScratchPermanent: 0, scratchTimerID: 0, + btnKey: 0, + btnBeatgrid: 0, + btnVolume: 0, + btnFilter: {"low": 0, "middle": 0, "high": 0}, + btnFx: {"1": 0, "2": 0}, + + connBeatIndicator: {}, + }, + + // Channel2 variable + "[Channel2]": { + btnShift: 0, + btnSync: 0, syncTimerID: null, syncLongPress: 0, + btnScratch: 0, isScratchPermanent: 0, scratchTimerID: 0, + btnKey: 0, + btnBeatgrid: 0, + btnVolume: 0, + btnFilter: {"low": 0, "middle": 0, "high": 0}, + btnFx: {"1": 0, "2": 0}, + + connBeatIndicator: {}, + }, +}; + +// Constant +var RELEASED = 0, + PRESSED = 1, + ADJUSTED = 2; + +//---------------------------- +// Constants for scratching +//---------------------------- + +/* Internal jog-wheel */ +var forwardFinetune = 0; +var backwardFinetune = 0; + +var intervalPerRev = 64; +var rpm = 33 + 1 / 3; +var alpha = 1 / 16; +var beta = (1 / 12) / 32; + +var scratchDisableTime = 100; +var enableAccVal = true; + +/* external jog-wheel */ +// var forwardFinetune = 0; +// var backwardFinetune = 1; + +// var intervalPerRev = 1000; +// var rpm = 33 + 1 / 3; +// var alpha = 1.0 / 8; +// var beta = alpha / 32; + +// var scratchDisableTime = 150; +// var enableAccVal = false; + +//---------------------------- +// Common variable +//---------------------------- +var joystickDelay = false; +var fsrDelay = false; + + + + +//==== Init, Shutdown ======================================================== +joyMIDI.init = function(_id, _debug) { + joyMIDI["[Channel1]"].connBeatIndicator = engine.makeConnection("[Channel1]", "beat_active", joyMIDI.onBeatIndicator); + joyMIDI["[Channel2]"].connBeatIndicator = engine.makeConnection("[Channel2]", "beat_active", joyMIDI.onBeatIndicator); +}; + +joyMIDI.shutdown = function() { + joyMIDI["[Channel1]"].connBeatIndicator.disconnect(); + joyMIDI["[Channel2]"].connBeatIndicator.disconnect(); +}; + +//==== Callback ============================================================== +joyMIDI.onBeatIndicator = function(value, group, _control) { + var fader = engine.getParameter("[Master]", "crossfader"); + if (fader < 0.5) { + // Left + if (group === "[Channel1]") { + midi.sendShortMsg(0x91, 0x00, (value) ? 0x7F : 0x00); + } + } else { + // Right + if (group === "[Channel2]") { + midi.sendShortMsg(0x92, 0x00, (value) ? 0x7F : 0x00); + } + } +}; + +//==== Button ================================================================ +joyMIDI.shiftButton = function(channel, control, value, status, group) { + joyMIDI[group].btnShift = (value > 0) ? PRESSED : RELEASED; +}; + +joyMIDI.syncButton = function(channel, control, value, status, group) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + if (engine.getValue(group, "sync_enabled") > 0) { + engine.setValue(group, "sync_enabled", 0); + } else { + engine.setValue(group, "sync_enabled", 1); + if (joyMIDI[group].syncTimerID !== null) { + engine.stopTimer(joyMIDI[group].syncTimerID); + } + joyMIDI[group].syncLongPress = 0; + joyMIDI[group].syncTimerID = + engine.beginTimer(1000, function() { joyMIDI.syncTimerHandler(group); }, true); + } + } else { + engine.setValue(group, "rate", 0); + } + } else { + // release + if (!joyMIDI[group].btnShift) { + if (joyMIDI[group].syncTimerID !== null) { + if (joyMIDI[group].syncLongPress === 0 && engine.getValue(group, "sync_enabled") === 1) { + engine.stopTimer(joyMIDI[group].syncTimerID); + engine.setValue(group, "sync_enabled", 0); + } + joyMIDI[group].syncTimerID = null; + } + } + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnSync = PRESSED; + } else { + // release + if (joyMIDI[group].btnSync !== ADJUSTED) { + if (!joyMIDI[group].btnShift) { + engine.setValue(group, "beatsync", 1); + } else { + engine.setValue(group, "rate", 0); + } + } + joyMIDI[group].btnSync = RELEASED; + } + } +}; + +joyMIDI.syncTimerHandler = function(group) { + joyMIDI[group].syncLongPress = 1; +}; + +joyMIDI.cueButton = function(channel, control, value, status, group) { + var sft = joyMIDI[group].btnShift; + var cmd = sft ? "start" : "cue_default"; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.playButton = function(channel, control, value, status, group) { + var sft = joyMIDI[group].btnShift; + var cmd = sft ? "reverse" : "play"; + + if (value > 0) { + script.toggleControl(group, cmd); + } +}; + +joyMIDI.scratchButton = function(channel, control, value, status, group) { + if (value > 0) { + joyMIDI[group].isScratchPermanent = !joyMIDI[group].isScratchPermanent; + } +}; + +joyMIDI.keyButton = function(channel, control, value, status, group) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + engine.setValue(group, "sync_key", 1); + } else { + engine.setValue(group, "reset_key", 1); + } + } else { + // release + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnKey = PRESSED; + } else { + // release + if (joyMIDI[group].btnKey !== ADJUSTED) { + if (joyMIDI[group].btnShift === RELEASED) { + engine.setValue(group, "sync_key", 1); + } else { + engine.setValue(group, "reset_key", 1); + } + } + joyMIDI[group].btnKey = RELEASED; + } + } +}; + +joyMIDI.beatgridButton = function(channel, control, value, status, group) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + engine.setValue(group, "beats_translate_curpos", 1); + engine.setValue(group, "beats_translate_curpos", 0); + } else { + engine.setValue(group, "beats_translate_match_alignment", 1); + engine.setValue(group, "beats_translate_match_alignment", 0); + } + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnBeatgrid = PRESSED; + } else { + // release + if (joyMIDI[group].btnBeatgrid !== ADJUSTED) { + if (joyMIDI[group].btnShift === RELEASED) { + engine.setValue(group, "beats_translate_curpos", 1); + engine.setValue(group, "beats_translate_curpos", 0); + } else { + engine.setValue(group, "beats_translate_match_alignment", 1); + engine.setValue(group, "beats_translate_match_alignment", 0); + } + } + joyMIDI[group].btnBeatgrid = RELEASED; + } + } +}; + +joyMIDI.volumeButton = function(channel, control, value, status, group) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + engine.setValue(group, "volume", 1.0); + } + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnVolume = PRESSED; + } else { + // release + if (joyMIDI[group].btnVolume !== ADJUSTED) { + if (joyMIDI[group].btnShift === RELEASED) { + engine.setValue(group, "volume", 1.0); + } + } + joyMIDI[group].btnVolume = RELEASED; + } + } +}; + +joyMIDI.filterLowButton = function(channel, control, value, status, group) { + joyMIDI.filterButton(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "button_parameter1", "low"); +}; + +joyMIDI.filterMiddleButton = function(channel, control, value, status, group) { + joyMIDI.filterButton(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "button_parameter2", "middle"); +}; + +joyMIDI.filterHighButton = function(channel, control, value, status, group) { + joyMIDI.filterButton(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "button_parameter3", "high"); +}; + +joyMIDI.filterButton = function(channel, control, value, status, group, group2, param, select) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + script.toggleControl(group2, param); + } + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnFilter[select] = PRESSED; + } else { + // release + if (joyMIDI[group].btnFilter[select] !== ADJUSTED) { + if (joyMIDI[group].btnShift === RELEASED) { + script.toggleControl(group2, param); + } + } + joyMIDI[group].btnFilter[select] = RELEASED; + } + } +}; + +joyMIDI.hotcueButton = function(channel, control, value, status, group) { + var num = control - ((group === "[Channel1]") ? 0x3B : 0x3F); + var sft = joyMIDI[group].btnShift; + var cmd = "hotcue_" + num + (sft ? "_clear" : "_activate"); + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.reloopToggleButton = function(channel, control, value, status, group) { + var usr = joyMIDI.userSetting.beatLoopRollEnable; + var sft = joyMIDI[group].btnShift; + var cmd = sft ? (usr?"beatlooproll_activate":"beatloop_activate") : "reloop_toggle"; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.loopInButton = function(channel, control, value, status, group) { + var sft = joyMIDI[group].btnShift; + var cmd = sft ? "loop_halve" : "loop_in"; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.loopOutButton = function(channel, control, value, status, group) { + var sft = joyMIDI[group].btnShift; + var cmd = sft ? "loop_double" : "loop_out"; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.loop0p125Button = function(channel, control, value, status, group) { + joyMIDI.loopXButton(channel, control, value, status, group, + ["beatloop_0.125_toggle", "beatloop_2_toggle", + "beatlooproll_0.125_activate", "beatlooproll_2_activate"]); +}; + +joyMIDI.loop0p25Button = function(channel, control, value, status, group) { + joyMIDI.loopXButton(channel, control, value, status, group, + ["beatloop_0.25_toggle", "beatloop_4_toggle", + "beatlooproll_0.25_activate", "beatlooproll_4_activate"]); +}; + +joyMIDI.loop0p5Button = function(channel, control, value, status, group) { + joyMIDI.loopXButton(channel, control, value, status, group, + ["beatloop_0.5_toggle", "beatloop_8_toggle", + "beatlooproll_0.5_activate", "beatlooproll_8_activate"]); +}; + +joyMIDI.loop1Button = function(channel, control, value, status, group) { + joyMIDI.loopXButton(channel, control, value, status, group, + ["beatloop_1_toggle", "beatloop_16_toggle", + "beatlooproll_1_activate", "beatlooproll_16_activate"]); +}; + +joyMIDI.loopXButton = function(channel, control, value, status, group, commands) { + var usr = joyMIDI.userSetting.beatLoopRollEnable; + var sft = joyMIDI[group].btnShift; + var cmd = commands[sft + (usr?2:0)]; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.loadButton = function(channel, control, value, status, group) { + var sft = joyMIDI[group].btnShift; + var cmd = sft ? "eject" : "LoadSelectedTrack"; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.sampler1Button = function(channel, control, value, status, group) { + joyMIDI.samplerButton(channel, control, value, status, group, 1); +}; + +joyMIDI.sampler2Button = function(channel, control, value, status, group) { + joyMIDI.samplerButton(channel, control, value, status, group, 2); +}; + +joyMIDI.sampler3Button = function(channel, control, value, status, group) { + joyMIDI.samplerButton(channel, control, value, status, group, 3); +}; + +joyMIDI.sampler4Button = function(channel, control, value, status, group) { + joyMIDI.samplerButton(channel, control, value, status, group, 4); +}; + +joyMIDI.samplerButton = function(channel, control, value, status, group, number) { + var commands = ["start_play", "start_stop", "cue_gotoandplay", "cue_default"]; + var usr = joyMIDI.userSetting.samplerCueModeEnable; + var sft = joyMIDI["[Channel"+ ((number > 2) ? 2 : 1) +"]"].btnShift; + var cmd = commands[sft + (usr?2:0)]; + var val = (value > 0) ? 1 : 0; + + engine.setValue(group, cmd, val); +}; + +joyMIDI.fx1Button = function(channel, control, value, status, group) { + joyMIDI.fxButton(channel, control, value, status, group, + "[EffectRack1_EffectUnit1]", "group_"+group+"_enable", 1); +}; + +joyMIDI.fx2Button = function(channel, control, value, status, group) { + joyMIDI.fxButton(channel, control, value, status, group, + "[EffectRack1_EffectUnit2]", "group_"+group+"_enable", 2); +}; + +joyMIDI.fxButton = function(channel, control, value, status, group, group2, param, select) { + if (!joyMIDI.userSetting.knobEnable) { + // knob disabled + if (value > 0) { + // press + if (!joyMIDI[group].btnShift) { + script.toggleControl(group2, param); + } + } + } else { + // knob enabled + if (value > 0) { + // press + joyMIDI[group].btnFx[select] = PRESSED; + } else { + // release + if (joyMIDI[group].btnFx[select] !== ADJUSTED) { + if (joyMIDI[group].btnShift === RELEASED) { + script.toggleControl(group2, param); + } + } + joyMIDI[group].btnFx[select] = RELEASED; + } + } +}; + +//==== Wheel ============================================================ +joyMIDI.wheel = function(channel, control, value, status, group) { + if (joyMIDI[group].btnSync >= PRESSED) { + joyMIDI.wheelSync(channel, control, value, status, group); + joyMIDI[group].btnSync = ADJUSTED; + } else if (joyMIDI[group].btnKey >= PRESSED) { + joyMIDI.wheelKey(channel, control, value, status, group); + joyMIDI[group].btnKey = ADJUSTED; + } else if (joyMIDI[group].btnBeatgrid >= PRESSED) { + joyMIDI.wheelBeatgrid(channel, control, value, status, group); + joyMIDI[group].btnBeatgrid = ADJUSTED; + } else if (joyMIDI[group].btnVolume >= PRESSED) { + joyMIDI.wheelVolume(channel, control, value, status, group); + joyMIDI[group].btnVolume = ADJUSTED; + + } else if (joyMIDI[group].btnFilter["low"] >= PRESSED) { + joyMIDI.wheelFilterLow(channel, control, value, status, group); + joyMIDI[group].btnFilter["low"] = ADJUSTED; + } else if (joyMIDI[group].btnFilter["middle"] >= PRESSED) { + joyMIDI.wheelFilterMiddle(channel, control, value, status, group); + joyMIDI[group].btnFilter["middle"] = ADJUSTED; + } else if (joyMIDI[group].btnFilter["high"] >= PRESSED) { + joyMIDI.wheelFilterHigh(channel, control, value, status, group); + joyMIDI[group].btnFilter["high"] = ADJUSTED; + + } else if (joyMIDI[group].btnFx["1"] >= PRESSED) { + joyMIDI.wheelFx1(channel, control, value, status, group); + joyMIDI[group].btnFx["1"] = ADJUSTED; + } else if (joyMIDI[group].btnFx["2"] >= PRESSED) { + joyMIDI.wheelFx2(channel, control, value, status, group); + joyMIDI[group].btnFx["2"] = ADJUSTED; + } else if (joyMIDI[group].btnFx["3"] >= PRESSED) { + joyMIDI.wheelFx3(channel, control, value, status, group); + joyMIDI[group].btnFx["3"] = ADJUSTED; + + } else if (joyMIDI[group].isScratchPermanent) { + joyMIDI.wheelScratch(channel, control, value, status, group); + } else { + joyMIDI.wheelPitchBend(channel, control, value, status, group); + } +}; + +joyMIDI.wheelPitchBend = function(channel, control, value, status, group) { + var newValue = joyMIDI.helperAccel(value - 64); + + engine.setValue(group, "jog", newValue); + print(group + "jog=" + newValue); +}; + +joyMIDI.wheelScratch = function(channel, control, value, status, group) { + var deck = script.deckFromGroup(group); + var newValue = joyMIDI.helperAccel(value - 64); + + if (newValue > 0) newValue = newValue + forwardFinetune; + else newValue = newValue - backwardFinetune; + + if (joyMIDI[group].scratchTimerID) { + engine.stopTimer(joyMIDI[group].scratchTimerID); + } + + // if (!engine.isScratching(deck)) { + engine.scratchEnable(deck, intervalPerRev, rpm, alpha, beta); + // } + + engine.scratchTick(deck, newValue); + + joyMIDI[group].scratchTimerID = + engine.beginTimer(scratchDisableTime, function() { joyMIDI.ScratchTimerHandler(deck, group); }, true); +}; + +joyMIDI.ScratchTimerHandler = function(deck, group) { + engine.scratchDisable(deck); + joyMIDI[group].scratchTimerID = 0; +}; + +joyMIDI.wheelSync = function(channel, control, value, status, group) { + var delta = joyMIDI.helperAccel(value - 64) * 0.01; + var oldValue = engine.getValue(group, "rate"); + var newValue = oldValue + delta; + + newValue = joyMIDI.helperLimit(newValue, 1.0, -1.0); + engine.setValue(group, "rate", newValue); + print(group + "rate=" + newValue); +}; + +joyMIDI.wheelKey = function(channel, control, value, status, group) { + var delta = /*joyMIDI.helperAccel*/(value - 64) * 0.2; + var oldValue = engine.getValue(group, "pitch"); + var newValue = oldValue + delta; + + newValue = joyMIDI.helperLimit(newValue, 6.0, -6.0); + engine.setValue(group, "pitch", newValue); + print(group + "pitch=" + newValue); +}; + +joyMIDI.wheelBeatgrid = function(channel, control, value, status, group) { + var delta = joyMIDI.helperAccel(value - 64); + var count = Math.abs(delta); + + for (var i=0; i 0) { + engine.setValue(group, "beats_translate_earlier", 1); + print(group + "beats_translate_earlier"); + } else { + engine.setValue(group, "beats_translate_later", 1); + print(group + "beats_translate_later"); + } + } +}; + +joyMIDI.wheelVolume = function(channel, control, value, status, group) { + var delta = joyMIDI.helperAccel(value - 64) * 0.01; + var oldValue = engine.getValue(group, "volume"); + var newValue = oldValue + delta; + + newValue = joyMIDI.helperLimit(newValue, 1.0, 0); + engine.setValue(group, "volume", newValue); + print(group + "volume=" + newValue); +}; + +joyMIDI.wheelFilterLow = function(channel, control, value, status, group) { + joyMIDI.wheelFilter(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "parameter1", "low"); +}; + +joyMIDI.wheelFilterMiddle = function(channel, control, value, status, group) { + joyMIDI.wheelFilter(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "parameter2", "middle"); +}; + +joyMIDI.wheelFilterHigh = function(channel, control, value, status, group) { + joyMIDI.wheelFilter(channel, control, value, status, group, + "[EqualizerRack1_" + group + "_Effect1]", "parameter3", "high"); +}; + +joyMIDI.wheelFilter = function(channel, control, value, status, group, group2, param, select) { + var delta = joyMIDI.helperAccel(value - 64) * 0.01; + var oldValue = engine.getParameter(group2, param); + var newValue = oldValue + delta; + + newValue = joyMIDI.helperLimit(newValue, 1.0, 0); + engine.setParameter(group2, param, newValue); + print(group + "EQ_" + select + "=" + newValue); +}; + +joyMIDI.wheelFx1 = function(channel, control, value, status, group) { + if (group === "[Channel1]") { + joyMIDI.wheelFx(channel, control, value, status, group, + "[EffectRack1_EffectUnit1]", "mix", 1); + } else { + joyMIDI.wheelFx(channel, control, value, status, group, + "[EffectRack1_EffectUnit2]", "mix", 1); + } +}; + +joyMIDI.wheelFx2 = function(channel, control, value, status, group) { + if (group === "[Channel1]") { + joyMIDI.wheelFx(channel, control, value, status, group, + "[EffectRack1_EffectUnit1]", "super1", 2); + } else { + joyMIDI.wheelFx(channel, control, value, status, group, + "[EffectRack1_EffectUnit2]", "super1", 2); + } +}; + +joyMIDI.wheelFx = function(channel, control, value, status, group, group2, param, _select) { + var delta = joyMIDI.helperAccel(value - 64) * 0.01; + var oldValue = engine.getParameter(group2, param); + var newValue = oldValue + delta; + + newValue = joyMIDI.helperLimit(newValue, 1.0, 0); + engine.setParameter(group2, param, newValue); +}; + + +//==== Jojstick ============================================================ +joyMIDI.joystick = function(channel, control, _value, _status, _group) { + + if (joystickDelay === false) { + /* Delay a while */ + joystickDelay = true; + engine.beginTimer(300, function() { joystickDelay = false; }, true); + + if (!joyMIDI["[Channel1]"].btnShift) { + /* Joystick only */ + switch (control) { + case 0x10: engine.setValue("[Library]", "MoveLeft", true); break; + case 0x11: engine.setValue("[Library]", "MoveRight", true); break; + case 0x12: engine.setValue("[Library]", "MoveDown", true); break; + case 0x13: engine.setValue("[Library]", "MoveUp", true); break; + } + } else { + /* Joystick + shift */ + switch (control) { + case 0x10: /* Do nothing */ break; + case 0x11: /* Do nothing */ break; + case 0x12: engine.setValue("[Library]", "ScrollDown", true); break; + case 0x13: engine.setValue("[Library]", "ScrollUp", true); break; + } + } + } +}; + + +//==== FSR ============================================================ +joyMIDI.fsr = function(_channel, _control, _value, _status, _group) { + + if (fsrDelay === false) { + /* Delay a while */ + fsrDelay = true; + engine.beginTimer(300, function() { fsrDelay = false; }, true); + + var isShift = joyMIDI["[Channel1]"].btnShift === true || joyMIDI["[Channel2]"].btnShift === true; + if (! isShift) { + /* FSR only */ + engine.setValue("[Library]", "MoveFocusForward", true); + } else { + /* FSR + shift */ + engine.setValue("[Library]", "MoveFocusBackward", true); + } + } +}; + +//==== Helper ============================================================= +joyMIDI.helperLimit = function(input, max, min) { + input = input > max ? max : input; + input = input < min ? min : input; + return input; +}; + +joyMIDI.helperAccel = function(input) { + var acc = 0; + if (enableAccVal === true) { + acc = Math.pow(Math.abs(input), 2); + acc = (input > 0) ? acc : -acc; + } else { + acc = input; + } + return acc; +};