From fc04e79ddd7c1a8bee9e3b64ef23b70ef1048791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Sun, 9 Feb 2025 18:20:22 +0100 Subject: [PATCH 01/40] Add Hercules DJControl Inpulse 500 mapping --- .../Hercules-DJControl-Inpulse-500-script.js | 1566 ++++++++ .../Hercules_DJControl_Inpulse_500.midi.xml | 3424 +++++++++++++++++ 2 files changed, 4990 insertions(+) create mode 100644 res/controllers/Hercules-DJControl-Inpulse-500-script.js create mode 100644 res/controllers/Hercules_DJControl_Inpulse_500.midi.xml diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js new file mode 100644 index 000000000000..89a2b9f48947 --- /dev/null +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -0,0 +1,1566 @@ + +// DJControl_Inpulse_500_script.js +// +// *************************************************************************** +// * Mixxx mapping script file for the Hercules DJControl Inpulse 500. +// * Authors: Ev3nt1ne, DJ Phatso, resetreboot +// * contributions by Kerrick Staley, Bentheshrubber, ThatOneRuffian +// +// Version 1.6c: (August 2023) resetreboot +// * Requires Mixxx >= 2.3.4 +// * Volume meters follow correctly the selected channel +// * Use the full 14 bits for knobs for more precission +// * Add effects to the PAD 7 mode +// * Create decks for four channel mode +// * Change the behavior of the FX buttons, use them as Channel selector, using the LEDs +// as indicators of current channel. +// +// +// * When enabling multichannel, ensure: +// - Beat matching guide follows correctly the selected channels +// +// * Move the sampler buttons to the Deck component as well as the new effect buttons +// * Made the filter knob have a function with filter, effect and filter + effect +// * Use the Hotcue component for hotcues +// * Use components and add for the rest of the controls: +// - Play +// - Cue +// - Sync +// - Volume fader +// - EQs +// - PFL +// - Pad Selectors +// - Loop PADs +// - Roll PADs +// - Beat jump PADs +// - Tone key PADs +// - Slicer +// - Loop pot +// - In and Out loop +// - Load button +// - Vinyl +// - Slip +// - Quant +// - Pitch fader +// - Jog wheels (Using the new JogWheelBasic component! +// - Also probably fixed the shift behavior not working properly +// +// * Added option so the browser knob can behave with out of focus window +// +// * Version 1.5c (Summer 2023) +// * Forum: https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 +// * Wiki: https://mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 +// +// Version 1.0c: +// * Hot Cue: implementation of the Color API (Work in progress) +// - Assigned color directly to pad (XML) +// * Added DECK LED number - On when playing +// * Moved Beatjump to Pad mode 3 (Slicer) +// * Set different color for upper (Sampler 1-4) and lower (Sampler 5-8) sampler pads +// +// Version 1.0 - Based upon Inpulse 300 v1.2 (official) +// +// TO DO: +// * Browser knob has a ton of colors to do things! +// * Vinyl + SHIFT led should reflect brake status +// * Quant + SHIFT led should reflect key lock status +// * Add beat jump + SHIFT jumps +// +// **************************************************************************** +var DJCi500 = {}; +/////////////////////////////////////////////////////////////// +// USER OPTIONS // +/////////////////////////////////////////////////////////////// + +// If you are spinning your set list and you have your Mixxx window out +// of focus and you want to be able to use the browser knob to traverse +// the current crate or playlist, set to true. Especially useful to spin +// when using Twitch, VRChat or Second Life +DJCi500.browserOffFocusMode = false; + +// Set initial state for vinyl mode button +DJCi500.initialVinylMode = true; + +// Colors +DJCi500.PadColorMapper = new ColorMapper({ + 0xFF0000: 0x60, + 0xFFFF00: 0x7C, + 0x00FF00: 0x1C, + 0x00FFFF: 0x1F, + 0x0000FF: 0x03, + 0xFF00FF: 0x42, + 0xFF88FF: 0x63, + 0xFFFFFF: 0x7F, + 0x000088: 0x02, + 0x008800: 0x10, + 0x008888: 0x12, + 0x228800: 0x30, + 0x880000: 0x40, + 0x882200: 0x4C, + 0x888800: 0x50, + 0x888888: 0x52, + 0x88FF00: 0x5C, + 0xFF8800: 0x74, +}); + +// Constants + +DJCi500.EFFECT_ONLY_MODE = 1; +DJCi500.FILTER_AND_EFFECT_MODE = 2; + +// For key shift pads and beat jump pads +const pairColorsOn = [0x1F, 0x1F, 0x03, 0x03, 0x74, 0x74, 0x60, 0x60]; +const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; + + +/////////////////////////////////////////////////////////////// +// SLICER // +/////////////////////////////////////////////////////////////// +DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; //length of the Slicer domain +//PioneerDDJSX.slicerDomains = [8, 16, 32, 64]; + +// slicer storage: +DJCi500.slicerBeatsPassed = [0, 0, 0, 0]; +DJCi500.slicerPreviousBeatsPassed = [0, 0, 0, 0]; +DJCi500.slicerTimer = [false, false, false, false]; +//DJCi500.slicerJumping = [0, 0, 0, 0]; +DJCi500.slicerActive = [false, false, false, false]; +DJCi500.slicerAlreadyJumped = [false, false, false, false]; +DJCi500.slicerButton = [-1, -1, -1, -1]; +DJCi500.slicerModes = { + 'contSlice': 0, + 'loopSlice': 1 +}; +DJCi500.activeSlicerMode = [ + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice +]; +DJCi500.slicerLoopBeat8 = [0, 0, 0, 0]; +/////////////////////// + +// Master VU Meter callbacks +DJCi500.vuMeterUpdateMaster = function(value, _group, control) { + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); + var control = (control === "vu_meter_left") ? 0x40 : 0x41; + midi.sendShortMsg(0xB0, control, value); +}; + +DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { + if (value) { + midi.sendShortMsg(0x90, 0x0A, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0A, 0x00); + } +}; + +DJCi500.vuMeterPeakRightMaster = function(value, group, control, status) { + if (value) { + midi.sendShortMsg(0x90, 0x0F, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0F, 0x00); + } +}; + +// Deck VU Meter callbacks +DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0xB1, 0x40, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0xB2, 0x40, value); + } +}; + +DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { + var channel = 0x00; + if (DJCi500.deckA.currentDeck === group) { + channel = 0x91; + } else if (DJCi500.deckB.currentDeck === group) { + channel = 0x92; + } + + if (channel > 0x00) { + if (value) { + midi.sendShortMsg(channel, 0x39, 0x7F); + } else { + midi.sendShortMsg(channel, 0x39, 0x00); + } + } +}; + +DJCi500.numberIndicator = function(value, group, _control, _status) { + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0x91, 0x30, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0x92, 0x30, value); + } +} + +DJCi500.fxSelIndicator = function(_value, group, _control, _status) { + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + var active = false; + + if (group === "[EffectRack1_EffectUnit1]") { + active = engine.getValue(group, 'group_' + deckA + '_enable'); + if (active) { + midi.sendShortMsg(0x96, 0x63, 0x74); + } else { + midi.sendShortMsg(0x96, 0x63, 0x00); + } + active = engine.getValue(group, 'group_' + deckB + '_enable'); + if (active) { + midi.sendShortMsg(0x97, 0x63, 0x74); + } else { + midi.sendShortMsg(0x97, 0x63, 0x00); + } + } else if (group === "[EffectRack1_EffectUnit2]") { + active = engine.getValue(group, 'group_' + deckA + '_enable'); + if (active) { + midi.sendShortMsg(0x96, 0x67, 0x74); + } else { + midi.sendShortMsg(0x96, 0x67, 0x00); + } + active = engine.getValue(group, 'group_' + deckB + '_enable'); + if (active) { + midi.sendShortMsg(0x97, 0x67, 0x74); + } else { + midi.sendShortMsg(0x97, 0x67, 0x00); + } + } +} + +DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + var active = engine.getValue(group, 'enabled'); + + if (group == "[QuickEffectRack1_" + deckA + "]") { + midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60) + } else if (group == "[QuickEffectRack1_" + deckB + "]") { + midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60) + } +} + +DJCi500.Deck = function (deckNumbers, midiChannel) { + components.Deck.call(this, deckNumbers); + // Allow components to access deck variables + var deckData = this; + + // For loop and looprolls + var fractions = ['0.125', '0.25', '0.5', '1', '2', '4', '8', '16']; + var shiftFractions = ['0.03125', '0.0625', '32', '64', '128', '256', '512', '512']; + + // For beatjumps + var jumpValues = ['1', '1', '2', '2', '4', '4', '8', '8']; + var jumpValuesShift = ['16', '16', '32', '32', '64', '64', '128', '128']; + + // Brake status for this deck + this.slowPauseSetState = [false, false, false, false]; + + // Vinyl button state + this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; + + // Pitch ranges and status + this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; //select pitch range + this.pitchRangeId = 0; //id of the array, one for each deck + + // Effect section components + this.effectEnabled = false; + + // Make sure the shift button remaps the shift actions + this.shiftButton = new components.Button({ + midi: [0x90 + midiChannel, 0x04], + input: function(_channel, _control, value, _status, _group) { + if (value === 0x7F) { + deckData.forEachComponent(function(component) { + if (component.unshift) { + component.shift(); + } + }); + } else { + deckData.forEachComponent(function(component) { + if (component.unshift) { + component.unshift(); + } + }); + } + }, + }); + + this.loadButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0D], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.inKey = 'LoadSelectedTrack'; + }, + shift: function () { + this.inKey = 'eject'; + }, + }); + + // Transport section + // Play button, for some reason the group is not correct on this one? + this.playButton = new components.PlayButton({ + midi: [0x90 + midiChannel, 0x07], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.input = function (channel, control, value, status, group) { + if (value === 0x7F) { + if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched + var deck = parseInt(deckData.currentDeck.charAt(8)); + if (deckData.slowPauseSetState[deck - 1]) { + engine.brake(deck, + 1,//((status & 0xF0) !=== 0x80 && value > 0), + 54); + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } + }; + }, + shift: function () { + this.input = function (_channel, _control, _value, _status, group) { + engine.setValue(deckData.currentDeck, "play_stutter", true); + }; + }, + }); + + this.cueButton = new components.CueButton({ + midi: [0x90 + midiChannel, 0x06], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function () { + this.inKey = "start_play"; + }, + }); + + this.syncButton = new components.SyncButton({ + midi: [0x90 + midiChannel, 0x05], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function () { + this.inKey = "sync_key"; + }, + }); + + this.pflButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0C], + type: components.Button.prototype.types.toggle, + key: 'pfl', + }); + + // Top controls + // Vinyl button + this.vinylButton = new components.Button({ + midi: [0x90 + midiChannel, 0x03], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.input = function(channel, _control, value, status, group) { + if (value === 0x7F) { + var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; + var new_status = !deckData.vinylButtonState[deck]; + deckData.jogWheel.vinylMode = new_status; + deckData.jogWheelShift.vinylMode = new_status; + deckData.vinylButtonState[deck] = new_status; + var new_message = new_status ? 0x7F : 0x00; + midi.sendShortMsg(this.midi[0], 0x03, new_message); + } + }; + }, + shift: function () { + this.input = function (channel, control, value, status, group) { + if (value === 0x7F){ + var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; + deckData.slowPauseSetState[deck] = !deckData.slowPauseSetState[deck]; + } + }; + } + }); + + // SLIP mode button + this.slipButton = new components.Button({ + midi: [0x90 + midiChannel, 0x01], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + key: 'slip_enabled', + }); + + // Quant button + this.quantButton = new components.Button({ + midi: [0x90 + midiChannel, 0x02], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'quantize', + unshift: function () { + this.inKey = 'quantize'; + }, + shift: function () { + this.inKey = 'keylock'; + }, + }); + + // Knobs + this.volume = new components.Pot({ + midi: [0xB0 + midiChannel, 0x00], + inKey: 'volume', + }); + + this.eqKnob = []; + for (var k = 1; k <= 3; k++) { + this.eqKnob[k] = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01 + k], + group: '[EqualizerRack1_' + this.currentDeck + '_Effect1]', + inKey: 'parameter' + k, + }); + } + + this.gainKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x05], + key: 'pregain', + }); + + // Pitch-tempo fader + this.pitchFader = new components.Pot({ + midi: [0xB0 + midiChannel, 0x08], + key: 'rate', + }); + + // Jog Wheel + // TODO: Handle with less repeat the shift key for this + this.jogWheel = new components.JogWheelBasic({ + midi: [0xB0 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: "[Channel"+midiChannel+"]", + inputWheel: function(_channel, _control, value, _status, group) { + var deck = parseInt(deckData.currentDeck.charAt(8)); + value = this.inValueScale(value); + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, 'jog', value); + } + }, + inputTouch: function(channel, control, value, status, group) { + var deck = parseInt(deckData.currentDeck.charAt(8)); + if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + this.jogWheelShift = new components.JogWheelBasic({ + midi: [0xB3 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: "[Channel"+midiChannel+"]", + inputWheel: function(_channel, _control, value, _status, group) { + var deck = parseInt(deckData.currentDeck.charAt(8)); + value = this.inValueScale(value) * 4; + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, 'jog', value); + } + }, + inputTouch: function(channel, control, value, status, group) { + var deck = parseInt(deckData.currentDeck.charAt(8)); + if (this.isPress(channel, control, value, status) && this.vinylMode) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + // Loop controls + this.loopInButton = new components.Button({ + midi: [0x90 + midiChannel, 0x09], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'loop_enabled', // TODO: Check with loop_in? + unshift: function () { + this.inKey = 'loop_in'; + }, + shift: function () { + this.inKey = 'loop_in_goto'; + }, + }); + + this.loopOutButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0A], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'loop_enabled', // TODO: Check with loop_in? + unshift: function () { + this.inKey = 'loop_out'; + }, + shift: function () { + this.inKey = 'loop_out_goto'; + }, + }); + + // Loop rotary encoder functions + // + // Push the rotary encoder + this.loopEncoderPush = new components.Button({ + midi: [0x90 + midiChannel, 0x2C], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.inKey = 'reloop_toggle'; + }, + shift: function () { + this.inKey = 'beatloop_4_activate'; + }, + }); + + // Loop encoder + this.loopEncoder = new components.Encoder({ + midi: [0xB0 + midiChannel, 0x0E], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + input: function (channel, control, value, status, group) { + // FIXME: Toggle for loop halve and double?? + var deckGroup = deckData.currentDeck; + if (value >= 0x40) { + engine.setValue(deckGroup, "loop_halve", true); + } else { + engine.setValue(deckGroup, "loop_double", true); + } + } + }); + + // We only check and attach for slicer mode, but we have all + // pad buttons here if we need something extra! + this.padSelectButtons = []; + for (var i = 1; i <= 8; i++) { + this.padSelectButtons[i] = new components.Button({ + midi: [0x90 + midiChannel, 0x0F + (i - 1)], + input: function(channel, control, value, status, group) { + var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; + if (control === 0x11) { + DJCi500.slicerActive[deck] = true; + } else { + DJCi500.slicerActive[deck] = false; + } + }, + }); + } + + // Hotcue buttons (PAD Mode 1) + this.hotcueButtons = []; + for (var i = 1; i <= 8; i++) { + this.hotcueButtons[i] = new components.HotcueButton({ + midi: [0x95 + midiChannel, 0x00 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + colorMapper: DJCi500.PadColorMapper, + off: 0x00, + }); + }; + + // Loop buttons (PAD Mode 2) + this.loopButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1)], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: 'beatloop_' + fractions[i - 1] + '_enabled', + inKey: 'beatloop_' + fractions[i - 1] + '_toggle', + }); + }; + + // A bit repeated code, but I want the leds to react accordingly + this.loopShiftButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopShiftButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: 'beatloop_' + shiftFractions[i - 1] + '_enabled', + inKey: 'beatloop_' + shiftFractions[i - 1] + '_toggle', + }); + }; + + // Slicer buttons (PAD Mode 3) + this.slicerButtons = []; + for (var i = 1; i <= 8; i++) { + this.slicerButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x20 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + input: function(channel, control, value, status, group) { + // This is kind of a hack... somehow this is not getting the group correctly! + DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); + }, + }); + }; + + // Sampler buttons (PAD Mode 4) + this.samplerButtons = []; + for (var i = 1; i <= 8; i++) { + this.samplerButtons[i] = new components.SamplerButton({ + midi: [0x95 + midiChannel, 0x30 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + loaded: 0x42, + empty: 0x00, + playing: 0x63, + looping: 0x74, + }); + }; + + // Pitch buttons (PAD Mode 5) + this.pitchDownTone = new components.Button({ + midi: [0x95 + midiChannel, 0x40], + on: pairColorsOn[0], + off: pairColorsOff[0], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_down", 1); + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchDownSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x41], + on: pairColorsOn[1], + off: pairColorsOff[1], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchUpSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x42], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchUpTone = new components.Button({ + midi: [0x95 + midiChannel, 0x43], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_up", 1); + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchSliderIncrease = new components.Button({ + midi: [0x95 + midiChannel, 0x46], + on: 0x63, + off: 0x42, + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId++; + if (deckData.pitchRangeId > 6) + { + deckData.pitchRangeId = 6; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + this.pitchSliderDecrease = new components.Button({ + midi: [0x95 + midiChannel, 0x45], + on: pairColorsOn[3], + off: pairColorsOff[3], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId = deckData.pitchRangeId - 1; + if (deckData.pitchRangeId < 0) + { + deckData.pitchRangeId = 0; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + this.pitchSliderReset = new components.Button({ + midi: [0x95 + midiChannel, 0x44], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId = 0; + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + // Beatloop rolls buttons (PAD Mode 6) + this.rollButtons = []; + for (var i = 1; i <= 8; i++) { + this.rollButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x50 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: 0x1F, + off: 0x12, + key: 'beatlooproll_' + fractions[i - 1] + '_activate', + }); + }; + + // Effect buttons (PAD Mode 7) + this.effectButtons = []; + for (var i = 1; i <= 3; i++) { + // First top row effects buttons, just the effect, disable HPF/LPF knob + this.effectButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x60 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", + outKey: "enabled", + output: function (value, group, control) { + if (value) { + this.send(0x7F); + } else { + this.send(0x7C); + } + }, + unshift: function() { + // Normal effect button operation, toggling the effect assigned to it + this.input = function (channel, control, value, status, group) { + var fxNo = control - 0x5F; + var unit = channel - 0x95; + if (value === 0x7F){ + script.toggleControl(this.group, "enabled"); + } + }; + }, + shift: function () { + // Shift button will change the effect to the next in the list + this.input = function (channel, control, value, status, group) { + var fxNo = control - 0x67; + var unit = channel - 0x95; + if (value === 0x7F){ + engine.setValue(this.group, 'effect_selector', +1); + } + }; + } + }); + }; + + // Effect chain selectors + this.effectButtons[5] = new components.Button({ + midi: [0x95 + midiChannel, 0x64], + number: 5, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + on: 0x5C, + off: 0x30, + input: function (channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, 'chain_preset_selector', -1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + } + }); + + this.effectButtons[6] = new components.Button({ + midi: [0x95 + midiChannel, 0x65], + number: 6, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + on: 0x5C, + off: 0x30, + input: function (channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, 'chain_preset_selector', 1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + } + }); + + // Filter kill switch + this.effectButtons[7] = new components.Button({ + midi: [0x95 + midiChannel, 0x66], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + input: function (_channel, _control, value, _status, _group) { + if (value === 0x7F) { + script.toggleControl(this.group, 'enabled'); + } + } + }); + + // Set the current channel FX route with the two extra PADs + this.effectButtons[4] = new components.Button({ + midi: [0x95 + midiChannel, 0x63], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[EffectRack1_EffectUnit1]", + input: function (channel, _control, value, _status, group) { + if (value === 0x7F) { + var deckGroup = deckData.currentDeck; + script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); + } + } + }); + + this.effectButtons[8] = new components.Button({ + midi: [0x95 + midiChannel, 0x67], + number: 8, + shiftOffset: 8, + shiftControl: true, + sendShifted: false, + group: "[EffectRack1_EffectUnit2]", + input: function (_channel, _control, value, _status, _group) { + if (value === 0x7F) { + var deckGroup = deckData.currentDeck; + script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); + } + } + }); + + // Filter knob is here since it is affected by effects pads + this.filterKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01], + number: midiChannel, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + input: function (channel, control, value, status, group) { + if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { + // Move the effects knobs + engine.setValue("[EffectRack1_EffectUnit" + this.number + "]", "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2 ); + } else { + // Move the filter knob + engine.setValue("[QuickEffectRack1_" + deckData.currentDeck + "]", "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); + } + }, + }); + + // Beat jump (PAD Mode 8) + this.beatJumpButtons = []; + for (var i = 1; i <= 8; i++) { + var movement = (i % 2 === 0) ? '_forward' : '_backward'; + var jmpVal = jumpValues[i - 1]; + var jmpValShft = jumpValuesShift[i - 1]; + this.beatJumpButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x70 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: pairColorsOn[i - 1], + off: pairColorsOff[i - 1], + jump: 'beatjump_' + jmpVal + movement, + jumpShift: 'beatjump_' + jmpValShft + movement, + unshift: function () { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jump, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + } + }, + shift: function () { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jumpShift, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + } + }, + }); + }; + + // As per Mixxx wiki, set the group properties + this.reconnectComponents(function (c) { + if (c.group === undefined) { + c.group = this.currentDeck; + } + }); +} + +// Give the custom Deck all the methods of the generic deck +DJCi500.Deck.prototype = new components.Deck(); + +// INIT for the controller and decks +DJCi500.init = function() { + DJCi500.AutoHotcueColors = true; + + // Take care of the status of the crossfader status + DJCi500.crossfaderEnabled = true; + DJCi500.xFaderScratch = false; + + // Setup Vinyl buttons LED(one for each deck). + midi.sendShortMsg(0x91, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + midi.sendShortMsg(0x92, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + + //Turn On Browser button LED + midi.sendShortMsg(0x90, 0x05, 0x10); + + // Connect the VUMeters + engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + + // Deck VU meters peak indicators + engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel2]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel3]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel4]", "peak_indicator", DJCi500.vuMeterPeakDeck); + + // Connect number leds + engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); + + // Connect Master VU meter + engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); + engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); + + engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + + // Connect the FX selection leds + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + + engine.makeConnection("[QuickEffectRack1_[Channel1]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel2]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel3]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel4]]", "enabled", DJCi500.fxEnabledIndicator); + + // Connect the slicer beats + DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); + //var controlsToFunctions = {'beat_active': 'DJCi500.slicerBeatActive'}; + //script.bindConnections('[Channel1]', controlsToFunctions, true); + + // Ask the controller to send all current knob/slider values over MIDI, which will update + // the corresponding GUI controls in MIXXX. + midi.sendShortMsg(0xB0, 0x7F, 0x7F); + + // Turn on lights: + for (var i = 0; i < 2; i++) { + // PAD 5 Key and tempo range controls + midi.sendShortMsg(0x96+i, 0x40, 0x12); + midi.sendShortMsg(0x96+i, 0x41, 0x12); + midi.sendShortMsg(0x96+i, 0x42, 0x40); + midi.sendShortMsg(0x96+i, 0x43, 0x40); + midi.sendShortMsg(0x96+i, 0x44, 0x40); + midi.sendShortMsg(0x96+i, 0x45, 0x02); + midi.sendShortMsg(0x96+i, 0x46, 0x42); + + // PAD 8 Beatjump leds + midi.sendShortMsg(0x96+i, 0x70, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x71, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x72, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x73, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x74, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x75, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x76, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x77, pairColorsOff[7]); + // PAD 8 shift + midi.sendShortMsg(0x96+i, 0x78, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x79, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x7A, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x7B, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x7C, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x7D, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x7E, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x7F, pairColorsOff[7]); + // Light up FX quick effect chain selector buttons + midi.sendShortMsg(0x96+i, 0x64, 0x30); + midi.sendShortMsg(0x96+i, 0x65, 0x30); + } + + DJCi500.tempoTimer = engine.beginTimer(250, DJCi500.tempoLEDs); + + // FX buttons, light them to signal the current deck 1 and 2 as active + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x15, 0x7F); + + // Create the deck objects + DJCi500.deckA = new DJCi500.Deck([1, 3], 1); + DJCi500.deckB = new DJCi500.Deck([2, 4], 2); + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.deckB.setCurrentDeck("[Channel2]"); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel1]]", 0, 0); + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel2]]", 0, 0); +}; + +// Crossfader control, set the curve +DJCi500.crossfaderSetCurve = function(channel, control, value, _status, _group) { + switch(value) { + case 0x00: + // Mix + script.crossfaderCurve(0,0,127); + DJCi500.xFaderScratch = false; + break; + case 0x7F: + // Scratch + script.crossfaderCurve(127,0,127); + DJCi500.xFaderScratch = true; + break; + } +} + +// Crossfader enable or disable +DJCi500.crossfaderEnable = function(channel, control, value, _status, _group) { + if(value) { + DJCi500.crossfaderEnabled = true; + } else { + DJCi500.crossfaderEnabled = false; + engine.setValue("[Master]", "crossfader", 0); // Set the crossfader in the middle + } +} + +// Crossfader function +DJCi500.crossfader = function(channel, control, value, status, group) { + if (DJCi500.crossfaderEnabled) { + // Eventine's crossfader scratch mode + if (DJCi500.xFaderScratch) { + var result = 0; + if (value <= 0) { + result = -1; + } + else if (value >= 127) { + result = 1; + } + else { + result = Math.tan((value-64)*Math.PI/2/63)/32; + } + engine.setValue(group, "crossfader", result); + } + else { + engine.setValue(group, "crossfader", (value/64)-1); + } + } +} + +// Browser button. We move it to a custom JS function to avoid having to focus the Mixxx window for it to respond +DJCi500.moveLibrary = function(channel, control, value, status, group) { + if (value > 0x3F) { + if (DJCi500.browserOffFocusMode) { + engine.setValue('[Playlist]', 'SelectTrackKnob', -1); + } else { + engine.setValue('[Library]', 'MoveUp', 1); + } + } else { + if (DJCi500.browserOffFocusMode) { + engine.setValue('[Playlist]', 'SelectTrackKnob', 1); + } else { + engine.setValue('[Library]', 'MoveDown', 1); + } + } +} + +DJCi500.spinback_button = function(channel, control, value, status, group) { + var deck = parseInt(group.substring(8,9)); // work out which deck we are using + engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly +} + +// Update the Tempo and phase sync leds +DJCi500.tempoLEDs = function () { + // Current active decks + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + + //Tempo: + var tempo1 = engine.getValue(deckA, "bpm"); + var tempo2 = engine.getValue(deckB, "bpm"); + var diff = tempo1 - tempo2; + + //Check double tempo: + var doubleTempo = 0; + if (diff > 0){ + if ((tempo1 / tempo2) > 1.5){doubleTempo = 1; diff = tempo1/2 - tempo2;} + } + else{ + if ((tempo2 / tempo1) > 1.5){doubleTempo = 1; diff = tempo1 - tempo2/2;} + } + + if ( diff < -0.25) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x1E, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + else if ( diff > 0.25) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x1E, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x2C, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x2C, 0x7F); + + //Do beat alignement only if the tracks are already on Tempo + // and only if they are playing + if ( (engine.getValue(deckA, "play_latched")) && (engine.getValue(deckB, "play_latched")) ){ + + var beat1 = engine.getValue(deckA, "beat_distance"); + var beat2 = engine.getValue(deckB, "beat_distance"); + if (doubleTempo){ + if (tempo1 > tempo2){ + if (beat2 > 0.5){ + beat2 -= 0.5; + } + beat2 *= 2; + } + else{ //tempo2 >(=) tempo1 + if (beat1 > 0.5){ + beat1 -= 0.5; + } + beat1 *= 2; + } + } + diff = beat1 - beat2; + if (diff < 0){ + diff = 1+diff; + } + if ((diff < 0.02) || (diff > 1-0.02)) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x7F); + } + else if ( diff < 0.5) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + } + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x7F); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//if playing + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//else tempo +}; + +// After a channel change, make sure we read the current status +DJCi500.updateDeckStatus = function(group) { + var playing = engine.getValue(group, "play_indicator"); + var volume = script.absoluteLinInverse(engine.getValue(group, "vu_meter"), 0.0, 1.0, 0, 127); + + // Update the vinyl button + var vinylState = false; + var deckIndex = parseInt(group.charAt(8)) - 1; + var channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; + if (channel === 1) { + vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; + } else { + vinylState = DJCi500.deckB.vinylButtonState[deckIndex]; + } + midi.sendShortMsg(0x90 + channel, 0x03, (vinylState) ? 0x7F : 0x00); + midi.sendShortMsg(0xB0 + channel, 0x40, volume); + midi.sendShortMsg(0x90 + channel, 0x30, playing ? 0x7F : 0x00); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_" + group + "]", 0, 0); + + // Slicer + switch(group) { + case "[Channel1]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel2]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + case "[Channel3]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection('[Channel3]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel4]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel4]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + }; +} + +// This is where we choose the channel using the FX buttons and light them +// up correctly +DJCi500.deckSelector = function(channel, control, value, status, group) { + if (value === 0x7F) { + var deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number + switch (deckChosen) { + case 1: + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.updateDeckStatus("[Channel1]"); + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x16, 0x00); + break; + case 2: + DJCi500.deckB.setCurrentDeck("[Channel2]"); + DJCi500.updateDeckStatus("[Channel2]"); + midi.sendShortMsg(0x90, 0x15, 0x7F); + midi.sendShortMsg(0x90, 0x17, 0x00); + break; + case 3: + DJCi500.deckA.setCurrentDeck("[Channel3]"); + DJCi500.updateDeckStatus("[Channel3]"); + midi.sendShortMsg(0x90, 0x14, 0x00); + midi.sendShortMsg(0x90, 0x16, 0x7F); + break; + case 4: + DJCi500.deckB.setCurrentDeck("[Channel4]"); + DJCi500.updateDeckStatus("[Channel4]"); + midi.sendShortMsg(0x90, 0x15, 0x00); + midi.sendShortMsg(0x90, 0x17, 0x7F); + break; + }; + }; +}; + +DJCi500.updateEffectStatus = function(midiChannel, channel) { + let status = false; + for (var i = 1; i <= 3; i++) { + status = status || engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", "enabled"); + } + return status; + // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); +} + +/////////////////////////////////////////////////////////////// +// SLICER // +/////////////////////////////////////////////////////////////// +DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { + var index = control - 0x20, + deck = parseInt(group.charAt(8)) - 1, + domain = DJCi500.selectedSlicerDomain[deck], + beatsToJump = 0, + passedTime = engine.getValue(group, "beat_distance"), + loopEnabled = engine.getValue(group, "loop_enabled"); + + if (value) { + DJCi500.slicerButton[deck] = index; + //Maybe I need to update this (seems sometimes it does not work.) + //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); + beatsToJump -= passedTime; + + //activate the one-shot timer for the slip end. + if (!DJCi500.slicerTimer[deck]){ + DJCi500.slicerTimer[deck] = true; + var timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; + + //quality of life fix for not-precise hands or beatgrid + // also good fix for really small timer_ms values. + if ( (passedTime >= 0.8) && + //this is because while looping doing this thing on beat 8 break the flow. + ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1)) ) { + timer_ms += 60.0/engine.getValue(group, "bpm")*1000; + } + + engine.beginTimer( timer_ms, + //"DJCi500.slicerTimerCallback("+group+")", true); + function() { + //need to do this otherwise loop does not work on beat 8 because of slip. + if ((engine.getValue(group, "loop_enabled") === true)){ + //on the wiki it says it returns an integer, but I tested and instead seems a Real value: + // But it does not work cuz the value does not relate to beat. they are samples. + //var endLoop = engine.getValue(group, "loop_end_position"); + engine.setValue(group, "reloop_toggle", true); //false + engine.setValue(group, "slip_enabled", false); + //Aleatory behavior, probably because the slip does not always have completed before "returning" + //so I need to introduce a timer waiting the slip function to be completely resolved + engine.beginTimer( 2, function () { + var bpm_file = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"); + /* + if (Math.floor((playposition * duration) * (bpm_file / 60.0)) > endLoop) { + engine.setValue(group, "beatjump", -8); + }*/ + engine.setValue(group, "reloop_toggle", true);}, + true); + } + else { + engine.setValue(group, "slip_enabled", false); + } + DJCi500.slicerTimer[deck] = false; + DJCi500.slicerButton[deck] = -1;}, + true); + } + + engine.setValue(group, "slip_enabled", true); + + //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping + // also there is no "lopp_deactivate" and loop_activate false does not work. + if (loopEnabled) { + engine.setValue(group, "reloop_toggle", true); + } + engine.setValue(group, "beatjump", beatsToJump); + //This sadly does not work. + //engine.setValue(group, "loop_move", -beatsToJump); + if (loopEnabled){ + engine.setValue(group, "reloop_toggle", true); + } + midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); + } //if value +}; + +//this below is connected to beat_active +DJCi500.slicerBeatActive = function(value, group, control) { + // This slicer implementation will work for constant beatgrids only! + var deck = parseInt(group.charAt(8)) - 1; + var channel = deck % 2; + + print("***** SLICER ACTIVE VALUE: " + DJCi500.slicerActive[deck]); + print("***** SLICER: deck " + deck + " channel " + channel); + + var bpm = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"), + slicerPosInSection = 0, + ledBeatState = false, + domain = DJCi500.selectedSlicerDomain[deck]; + + //this works. + if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { + return; + } + + DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + + if (DJCi500.slicerActive[deck]){ + slicerPosInSection = Math.floor((DJCi500.slicerBeatsPassed[deck] % domain) / (domain / 8)); + // PAD Led control: + if (DJCi500.slicerButton[deck] !== slicerPosInSection) { + for (var i = 0; i < 8; i++) { + active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; + midi.sendShortMsg((0x96+channel), 0x20+i, active); + } + } else { + midi.sendShortMsg((0x96+channel), 0x20+DJCi500.slicerButton[deck], 0x62); + } + } else { + DJCi500.slicerAlreadyJumped[deck] = false; + DJCi500.slicerPreviousBeatsPassed[deck] = 0; + } +}; + +DJCi500.shutdown = function() { + //cleanup + midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off + midi.sendShortMsg(0xB0, 0x7F, 0x7E); +}; diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml new file mode 100644 index 000000000000..7bf3703a82bb --- /dev/null +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -0,0 +1,3424 @@ + + + + Hercules DJControl Inpulse 500 1d + DJ Phatso for Hercules Technical Support + MIDI Preset for Hercules DJControl Inpulse 500 + https://www.mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 + https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 + + + + + + + + + + + + + + [Library] + MoveFocus + Browser button + 0x90 + 0x00 + + + + + + + + [AutoDJ] + enabled + AutoDJ On/Off + 0x90 + 0x03 + + + + + + [Mixer Profile] + DJCi500.crossfaderEnable + CROSS FADER ENABLE + 0x90 + 0x18 + + + + + + + [Mixer Profile] + DJCi500.crossfaderSetCurve + CROSS FADER SET CURVE + 0xB0 + 0x0B + + + + + + + + + + [Channel1] + DJCi500.deckA.playButton.input + Play button + 0x91 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.cueButton.input + Cue button + 0x91 + 0x06 + + + + + + + [Channel1] + DJCi500.deckA.syncButton.input + Sync button + 0x91 + 0x05 + + + + + + + [Channel1] + DJCi500.deckA.pflButton.input + PFL button + 0x91 + 0x0C + + + + + + + [Channel1] + DJCi500.deckA.loadButton.input + LOAD A button + 0x91 + 0x0D + + + + + + + [Channel1] + DJCi500.deckA.loadButton.input + LOAD A button + 0x94 + 0x0D + + + + + + + [Channel1] + DJCi500.deckA.shiftButton.input + Shift Deck A button + 0x91 + 0x04 + + + + + + + [Channel1] + DJCi500.deckA.slipButton.input + SLIP button + 0x91 + 0x01 + + + + + + + [Channel1] + DJCi500.deckA.quantButton.input + Quantize button - Deck 1 + 0x91 + 0x02 + + + + + + + [Channel1] + DJCi500.deckA.quantButton.input + Keylock button (shift+quant) - Deck 1 + 0x94 + 0x02 + + + + + + + + [Master] + DJCi500.deckA.vinylButton.input + Vinyl Deck A + 0x91 + 0x03 + + + + + + + + [Channel1] + DJCi500.deckA.vinylButton.input + Shift + Vinyl Deck A + 0x94 + 0x03 + + + + + + + + [Channel1] + DJCi500.deckA.loopInButton.input + Loop In button + 0x91 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.loopOutButton.input + Loop Out button + 0x91 + 0x0A + + + + + + + [Channel1] + DJCi500.deckA.loopInButton.input + S+Loop In button (loop in goto) + 0x94 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.loopOutButton.input + S+Loop Out button (loop out goto) + 0x94 + 0x0A + + + + + + + + [Channel1] + DJCi500.deckA.loopEncoderPush.input + Loop Encoder Push button Deck A Reloop toggle + 0x91 + 0x2C + + + + + + + [Channel1] + DJCi500.deckA.loopEncoderPush.input + Loop Encoder Push button Deck A 4 Beat loop activate + 0x94 + 0x2C + + + + + + + + [Channel1] + DJCi500.deckA.loopEncoder.input + Loop Halve/Double (Loop Knob Deck A) + 0xB1 + 0x0E + + + + + + + + + + [Channel2] + DJCi500.deckB.playButton.input + Play button + 0x92 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.cueButton.input + Cue button + 0x92 + 0x06 + + + + + + + [Channel2] + DJCi500.deckB.syncButton.input + Sync button + 0x92 + 0x05 + + + + + + + [Channel2] + DJCi500.deckB.pflButton.input + PFL button + 0x92 + 0x0C + + + + + + + [Channel2] + DJCi500.deckB.loadButton.input + LOAD B button + 0x92 + 0x0D + + + + + + + [Channel2] + DJCi500.deckB.loadButton.input + LOAD B button + 0x95 + 0x0D + + + + + + + [Channel1] + DJCi500.deckB.shiftButton.input + Shift Deck A button + 0x92 + 0x04 + + + + + + + [Channel2] + DJCi500.deckB.slipButton.input + SLIP button + 0x92 + 0x01 + + + + + + + [Channel2] + DJCi500.deckB.quantButton.input + Quantize button - Deck 2 + 0x92 + 0x02 + + + + + + + [Channel2] + DJCi500.deckB.quantButton.input + Keylock button (shift+quant) - Deck 2 + 0x95 + 0x02 + + + + + + + + [Master] + DJCi500.deckB.vinylButton.input + Vinyl Deck B + 0x92 + 0x03 + + + + + + + + [Channel2] + DJCi500.deckB.vinylButton.input + Shift + Vinyl Deck B + 0x95 + 0x03 + + + + + + + + [Channel2] + DJCi500.deckB.loopInButton.input + Loop In button + 0x92 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.loopOutButton.input + Loop Out button + 0x92 + 0x0A + + + + + + + [Channel2] + DJCi500.deckB.loopInButton.input + Loop In button (Loop In Goto) + 0x95 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.loopOutButton.input + Loop Out button (loop out goto) + 0x95 + 0x0A + + + + + + + + [Channel2] + DJCi500.deckB.loopEncoderPush.input + Loop Encoder Push button Deck B (reloop toggle) + 0x92 + 0x2C + + + + + + + [Channel2] + DJCi500.deckB.loopEncoderPush.input + Loop Encoder Push button Deck B (beatloop 4 activated) + 0x95 + 0x2C + + + + + + + + + [Channel2] + DJCi500.deckB.loopEncoder.input + Loop Halve/Double (Loop Knob Deck B) + 0xB2 + 0x0E + + + + + + + + + + [Skin] + show_maximized_library + Browser button - Maximize Library view + 0x93 + 0x00 + + + + + + + + + + [Channel1] + DJCi500.deckA.playButton.input + SHIFT + Play: Play Stutter + 0x94 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.cueButton.input + SHIFT + Cue: REWIND to beginning + 0x94 + 0x06 + + + + + + + [Channel1] + DJCi500.deckA.syncButton.input + SHIFT + Sync: Match key + 0x94 + 0x05 + + + + + + + + + [Channel2] + DJCi500.deckB.playButton.input + SHIFT + Play: Play Stutter + 0x95 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.cueButton.input + SHIFT + Cue: REWIND to beginning + 0x95 + 0x06 + + + + + + + [Channel2] + DJCi500.deckB.syncButton.input + SHIFT + Sync: Sync key + 0x95 + 0x05 + + + + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[1].input + PAD select + 0x91 + 0x0F + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[2].input + PAD select + 0x91 + 0x10 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[3].input + PAD select + 0x91 + 0x11 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[4].input + PAD select + 0x91 + 0x12 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[5].input + PAD select + 0x91 + 0x13 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[6].input + PAD select + 0x91 + 0x14 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[7].input + PAD select + 0x91 + 0x15 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[8].input + PAD select + 0x91 + 0x16 + + + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[1].input + PAD 1 + 0x96 + 0x00 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[2].input + PAD 2 + 0x96 + 0x01 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[3].input + PAD 3 + 0x96 + 0x02 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[4].input + PAD 4 + 0x96 + 0x03 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[5].input + PAD 5 + 0x96 + 0x04 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[6].input + PAD 6 + 0x96 + 0x05 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[7].input + PAD 7 + 0x96 + 0x06 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[8].input + PAD 8 + 0x96 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[1].input + PAD 1 + L-Shift + 0x96 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[2].input + PAD 2 + L-Shift + 0x96 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[3].input + PAD 3 + L-Shift + 0x96 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[4].input + PAD 4 + L-Shift + 0x96 + 0x0B + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[5].input + PAD 5 + L-Shift + 0x96 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[6].input + PAD 6 + L-Shift + 0x96 + 0x0D + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[7].input + PAD 7 + L-Shift + 0x96 + 0x0E + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[8].input + PAD 8 + L-Shift + 0x96 + 0x0F + + + + + + + + [Channel1] + DJCi500.deckA.loopButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x96 + 0x10 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x96 + 0x11 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x96 + 0x12 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[4].input + Loop 1 Beat (Pad 4) + 0x96 + 0x13 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[5].input + Loop 2 Beat (Pad 5) + 0x96 + 0x14 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[6].input + Loop 4 Beat (Pad 6) + 0x96 + 0x15 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[7].input + Loop 8 Beat (Pad 7) + 0x96 + 0x16 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[8].input + Loop 16 Beat (Pad 8) + 0x96 + 0x17 + + + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[1].input + Loop 3/4 Beat (Pad 1) + 0x96 + 0x18 + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[2].input + Loop 5/4 Beat (Pad 2) + 0x96 + 0x19 + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[3].input + Loop 6/4 Beat (Pad 3) + 0x96 + 0x1A + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[4].input + Loop 7/4 Beat (Pad 4) + 0x96 + 0x1B + + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[5].input + Loop 32 Beat (Pad 5) + 0x96 + 0x1C + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[6].input + Loop 64 Beat (Pad 6) + 0x96 + 0x1D + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[7].input + Loop 128 Beat (Pad 7) + 0x96 + 0x1E + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[8].input + Loop 256 Beat (Pad 8) + 0x96 + 0x1F + + + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[1].input + PAD 1 + 0x96 + 0x20 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[2].input + PAD 2 + 0x96 + 0x21 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[3].input + PAD 3 + 0x96 + 0x22 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[4].input + PAD 4 + 0x96 + 0x23 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[5].input + PAD 5 + 0x96 + 0x24 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[6].input + PAD 6 + 0x96 + 0x25 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[7].input + PAD 7 + 0x96 + 0x26 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[8].input + PAD 8 + 0x96 + 0x27 + + + + + + + + [Sampler1] + DJCi500.deckA.samplerButtons[1].input + PAD 1 + 0x96 + 0x30 + + + + + + [Sampler2] + DJCi500.deckA.samplerButtons[2].input + PAD 2 + 0x96 + 0x31 + + + + + + [Sampler3] + DJCi500.deckA.samplerButtons[3].input + PAD 3 + 0x96 + 0x32 + + + + + + [Sampler4] + DJCi500.deckA.samplerButtons[4].input + PAD 4 + 0x96 + 0x33 + + + + + + [Sampler5] + DJCi500.deckA.samplerButtons[5].input + PAD 5 + 0x96 + 0x34 + + + + + + [Sampler6] + DJCi500.deckA.samplerButtons[6].input + PAD 6 + 0x96 + 0x35 + + + + + + [Sampler7] + DJCi500.deckA.samplerButtons[7].input + PAD 7 + 0x96 + 0x36 + + + + + + [Sampler8] + DJCi500.deckA.samplerButtons[8].input + PAD 8 + 0x96 + 0x37 + + + + + + + + [Sampler1] + DJCi500.deckA.samplerButtons[1].input + PAD 1 + 0x96 + 0x38 + + + + + + [Sampler2] + DJCi500.deckA.samplerButtons[2].input + PAD 2 + 0x96 + 0x39 + + + + + + [Sampler3] + DJCi500.deckA.samplerButtons[3].input + PAD 3 + 0x96 + 0x3A + + + + + + [Sampler4] + DJCi500.deckA.samplerButtons[4].input + PAD 4 + 0x96 + 0x3B + + + + + + [Sampler5] + DJCi500.deckA.samplerButtons[5].input + PAD 5 + 0x96 + 0x3C + + + + + + [Sampler6] + DJCi500.deckA.samplerButtons[6].input + PAD 6 + 0x96 + 0x3D + + + + + + [Sampler7] + DJCi500.deckA.samplerButtons[7].input + PAD 7 + 0x96 + 0x3E + + + + + + [Sampler8] + DJCi500.deckA.samplerButtons[8].input + PAD 8 + 0x96 + 0x3F + + + + + + + + [Channel1] + DJCi500.deckA.pitchDownTone.input + Pitch down - tone + 0x96 + 0x40 + + + + + + [Channel1] + DJCi500.deckA.pitchDownSemiTone.input + Pitch down - semitone + 0x96 + 0x41 + + + + + + [Channel1] + DJCi500.deckA.pitchUpSemiTone.input + Pitch up - semitone + 0x96 + 0x42 + + + + + + [Channel1] + DJCi500.deckA.pitchUpTone.input + Pitch up - tone + 0x96 + 0x43 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderIncrease.input + Pitch slider increase resolution + 0x96 + 0x46 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderDecrease.input + Pitch slider Decrease resolution + 0x96 + 0x45 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderReset.input + Pitch slider Reset resolution + 0x96 + 0x44 + + + + + + + + [Channel1] + DJCi500.deckA.rollButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x96 + 0x50 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x96 + 0x51 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x96 + 0x52 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[4].input + Loop 1 Beat (Pad 4) + 0x96 + 0x53 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[5].input + Loop 2 Beat (Pad 5) + 0x96 + 0x54 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[6].input + Loop 2 Beat (Pad 6) + 0x96 + 0x55 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[7].input + Loop 8 Beat (Pad 7) + 0x96 + 0x56 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[8].input + Loop 2 Beat (Pad 8) + 0x96 + 0x57 + + + + + + + + [Channel1] + DJCi500.deckA.effectButtons[1].input + PAD 1 + 0x96 + 0x60 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[2].input + PAD 2 + 0x96 + 0x61 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[3].input + PAD 3 + 0x96 + 0x62 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[4].input + PAD 4 + 0x96 + 0x63 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[5].input + PAD 5 + 0x96 + 0x64 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[6].input + PAD 6 + 0x96 + 0x65 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[7].input + PAD 7 + 0x96 + 0x66 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[8].input + PAD 8 + 0x96 + 0x67 + + + + + + + + [Channel1] + DJCi500.deckA.effectButtons[1].input + PAD 1 + 0x96 + 0x68 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[2].input + PAD 2 + 0x96 + 0x69 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[3].input + PAD 3 + 0x96 + 0x6A + + + + + + [Channel1] + DJCi500.deckA.effectButtons[4].input + PAD 4 + 0x96 + 0x6B + + + + + + [Channel1] + DJCi500.deckA.effectButtons[5].input + PAD 5 + 0x96 + 0x6C + + + + + + [Channel1] + DJCi500.deckA.effectButtons[6].input + PAD 6 + 0x96 + 0x6D + + + + + + [Channel1] + DJCi500.deckA.effectButtons[7].input + PAD 7 + 0x96 + 0x6E + + + + + + [Channel1] + DJCi500.deckA.effectButtons[8].input + PAD 8 + 0x96 + 0x6F + + + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[1].input + Beat jump 1 backward + 0x96 + 0x70 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[2].input + Beat jump 1 forward + 0x96 + 0x71 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[3].input + Beat jump 2 backward + 0x96 + 0x72 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[4].input + Beat jump 2 forward + 0x96 + 0x73 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[5].input + Beat jump 4 backward + 0x96 + 0x74 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[6].input + Beat jump 4 forward + 0x96 + 0x75 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[7].input + Beat jump 8 backward + 0x96 + 0x76 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[8].input + Beat jump 8 forward + 0x96 + 0x77 + + + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[1].input + Beat jump 16 backward + 0x96 + 0x78 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[2].input + Beat jump 16 forward + 0x96 + 0x79 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[3].input + Beat jump 32 backward + 0x96 + 0x7A + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[4].input + Beat jump 32 forward + 0x96 + 0x7B + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[5].input + Beat jump 64 backward + 0x96 + 0x7C + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[6].input + Beat jump 64 forward + 0x96 + 0x7D + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[7].input + Beat jump 128 backward + 0x96 + 0x7E + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[8].input + Beat jump 128 forward + 0x96 + 0x7F + + + + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[1].input + PAD select + 0x92 + 0x0F + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[2].input + PAD select + 0x92 + 0x10 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[3].input + PAD select + 0x92 + 0x11 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[4].input + PAD select + 0x92 + 0x12 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[5].input + PAD select + 0x92 + 0x13 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[6].input + PAD select + 0x92 + 0x14 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[7].input + PAD select + 0x92 + 0x15 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[8].input + PAD select + 0x92 + 0x16 + + + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[1].input + PAD 1 + 0x97 + 0x00 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[2].input + PAD 2 + 0x97 + 0x01 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[3].input + PAD 3 + 0x97 + 0x02 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[4].input + PAD 4 + 0x97 + 0x03 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[5].input + PAD 5 + 0x97 + 0x04 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[6].input + PAD 6 + 0x97 + 0x05 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[7].input + PAD 7 + 0x97 + 0x06 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[8].input + PAD 8 + 0x97 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[1].input + PAD 1 + R-Shift + 0x97 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[2].input + PAD 2 + R-Shift + 0x97 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[3].input + PAD 3 + R-Shift + 0x97 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[4].input + PAD 4 + R-Shift + 0x97 + 0x0B + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[5].input + PAD 5 + R-Shift + 0x97 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[6].input + PAD 6 + R-Shift + 0x97 + 0x0D + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[7].input + PAD 7 + R-Shift + 0x97 + 0x0E + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[8].input + PAD 8 + R-Shift + 0x97 + 0x0F + + + + + + + [Channel2] + DJCi500.deckB.loopButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x97 + 0x10 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x97 + 0x11 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x97 + 0x12 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[4].input + Loop 1 Beat (Pad 4) + 0x97 + 0x13 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[5].input + Loop 2 Beat (Pad 5) + 0x97 + 0x14 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[6].input + Loop 4 Beat (Pad 6) + 0x97 + 0x15 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[7].input + Loop 8 Beat (Pad 7) + 0x97 + 0x16 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[8].input + Loop 16 Beat (Pad 8) + 0x97 + 0x17 + + + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[1].input + Loop 3/4 Beat (Pad 1) + 0x97 + 0x18 + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[2].input + Loop 5/4 Beat (Pad 2) + 0x97 + 0x19 + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[3].input + Loop 6/4 Beat (Pad 3) + 0x97 + 0x1A + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[4].input + Loop 7/4 Beat (Pad 4) + 0x97 + 0x1B + + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[5].input + Loop 32 Beat (Pad 5) + 0x97 + 0x1C + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[6].input + Loop 64 Beat (Pad 6) + 0x97 + 0x1D + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[7].input + Loop 128 Beat (Pad 7) + 0x97 + 0x1E + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[8].input + Loop 256 Beat (Pad 8) + 0x97 + 0x1F + + + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[1].input + PAD 1 + 0x97 + 0x20 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[2].input + PAD 2 + 0x97 + 0x21 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[3].input + PAD 3 + 0x97 + 0x22 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[4].input + PAD 4 + 0x97 + 0x23 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[5].input + PAD 5 + 0x97 + 0x24 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[6].input + PAD 6 + 0x97 + 0x25 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[7].input + PAD 7 + 0x97 + 0x26 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[8].input + PAD 8 + 0x97 + 0x27 + + + + + + + + [Sampler1] + DJCi500.deckB.samplerButtons[1].input + PAD 1 + 0x97 + 0x30 + + + + + + [Sampler2] + DJCi500.deckB.samplerButtons[2].input + PAD 2 + 0x97 + 0x31 + + + + + + [Sampler3] + DJCi500.deckB.samplerButtons[3].input + PAD 3 + 0x97 + 0x32 + + + + + + [Sampler4] + DJCi500.deckB.samplerButtons[4].input + PAD 4 + 0x97 + 0x33 + + + + + + [Sampler5] + DJCi500.deckB.samplerButtons[5].input + PAD 5 + 0x97 + 0x34 + + + + + + [Sampler6] + DJCi500.deckB.samplerButtons[6].input + PAD 6 + 0x97 + 0x35 + + + + + + [Sampler7] + DJCi500.deckB.samplerButtons[7].input + PAD 7 + 0x97 + 0x36 + + + + + + [Sampler8] + DJCi500.deckB.samplerButtons[8].input + PAD 8 + 0x97 + 0x37 + + + + + + + + [Sampler1] + DJCi500.deckB.samplerButtons[1].input + PAD 1 + 0x97 + 0x38 + + + + + + [Sampler2] + DJCi500.deckB.samplerButtons[2].input + PAD 2 + 0x97 + 0x39 + + + + + + [Sampler3] + DJCi500.deckB.samplerButtons[3].input + PAD 3 + 0x97 + 0x3A + + + + + + [Sampler4] + DJCi500.deckB.samplerButtons[4].input + PAD 4 + 0x97 + 0x3B + + + + + + [Sampler5] + DJCi500.deckB.samplerButtons[5].input + PAD 5 + 0x97 + 0x3C + + + + + + [Sampler6] + DJCi500.deckB.samplerButtons[6].input + PAD 6 + 0x97 + 0x3D + + + + + + [Sampler7] + DJCi500.deckB.samplerButtons[7].input + PAD 7 + 0x97 + 0x3E + + + + + + [Sampler8] + DJCi500.deckB.samplerButtons[8].input + PAD 8 + 0x97 + 0x3F + + + + + + + + + [Channel2] + DJCi500.deckB.pitchUpSemiTone.input + Pitch up - semitone + 0x97 + 0x42 + + + + + + [Channel2] + DJCi500.deckB.pitchDownSemiTone.input + Pitch down - semitone + 0x97 + 0x41 + + + + + + [Channel2] + DJCi500.deckB.pitchUpTone.input + Pitch up - tone + 0x97 + 0x43 + + + + + + [Channel2] + DJCi500.deckB.pitchDownTone.input + Pitch down - tone + 0x97 + 0x40 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderIncrease.input + Pitch slider increase resolution + 0x97 + 0x46 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderDecrease.input + Pitch slider Decrease resolution + 0x97 + 0x45 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderReset.input + Pitch slider Reset resolution + 0x97 + 0x44 + + + + + + + + [Channel2] + DJCi500.deckB.rollButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x97 + 0x50 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x97 + 0x51 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x97 + 0x52 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[4].input + Loop 1 Beat (Pad 4) + 0x97 + 0x53 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[5].input + Loop 2 Beat (Pad 5) + 0x97 + 0x54 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[6].input + Loop 2 Beat (Pad 6) + 0x97 + 0x55 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[7].input + Loop 8 Beat (Pad 7) + 0x97 + 0x56 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[8].input + Loop 2 Beat (Pad 8) + 0x97 + 0x57 + + + + + + + + [Channel2] + DJCi500.deckB.effectButtons[1].input + PAD 1 + 0x97 + 0x60 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[2].input + PAD 2 + 0x97 + 0x61 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[3].input + PAD 3 + 0x97 + 0x62 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[4].input + PAD 4 + 0x97 + 0x63 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[5].input + PAD 5 + 0x97 + 0x64 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[6].input + PAD 6 + 0x97 + 0x65 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[7].input + PAD 7 + 0x97 + 0x66 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[8].input + PAD 8 + 0x97 + 0x67 + + + + + + + + [Channel2] + DJCi500.deckB.effectButtons[1].input + PAD 1 + 0x97 + 0x68 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[2].input + PAD 2 + 0x97 + 0x69 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[3].input + PAD 3 + 0x97 + 0x6A + + + + + + [Channel2] + DJCi500.deckB.effectButtons[4].input + PAD 4 + 0x97 + 0x6B + + + + + + [Channel2] + DJCi500.deckB.effectButtons[5].input + PAD 5 + 0x97 + 0x6C + + + + + + [Channel2] + DJCi500.deckB.effectButtons[6].input + PAD 6 + 0x97 + 0x6D + + + + + + [Channel2] + DJCi500.deckB.effectButtons[7].input + PAD 7 + 0x97 + 0x6E + + + + + + [Channel2] + DJCi500.deckB.effectButtons[8].input + PAD 8 + 0x97 + 0x6F + + + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[1].input + Beat jump 1 backward + 0x97 + 0x70 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[2].input + Beat jump 1 forward + 0x97 + 0x71 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[3].input + Beat jump 2 backward + 0x97 + 0x72 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[4].input + Beat jump 2 forward + 0x97 + 0x73 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[5].input + Beat jump 4 backward + 0x97 + 0x74 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[6].input + Beat jump 4 forward + 0x97 + 0x75 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[7].input + Beat jump 8 backward + 0x97 + 0x76 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[8].input + Beat jump 8 forward + 0x97 + 0x77 + + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[1].input + Beat jump 16 backward + 0x97 + 0x78 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[2].input + Beat jump 16 forward + 0x97 + 0x79 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[3].input + Beat jump 32 backward + 0x97 + 0x7A + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[4].input + Beat jump 32 forward + 0x97 + 0x7B + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[5].input + Beat jump 64 backward + 0x97 + 0x7C + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[6].input + Beat jump 64 forward + 0x97 + 0x7D + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[7].input + Beat jump 128 backward + 0x97 + 0x7E + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[8].input + Beat jump 128 forward + 0x97 + 0x7F + + + + + + + + + + + [Master] + DJCi500.crossfader + Crossfader + 0xB0 + 0x00 + + + + + + + [Library] + DJCi500.moveLibrary + Move Vertical (Browser Knob) + 0xB0 + 0x01 + + + + + + [Library] + MoveHorizontal + Move Horizontal (Browser Knob) + 0xB3 + 0x01 + + + + + + + + + + [Channel1] + DJCi500.deckA.volume.inputMSB + Volume Deck A + 0xB1 + 0x00 + + + + + + [Channel1] + DJCi500.deckA.volume.inputLSB + Volume Deck A + 0xB1 + 0x20 + + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[1].inputMSB + EQ LOW Deck A + 0xB1 + 0x02 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[1].inputLSB + EQ LOW Deck A + 0xB1 + 0x22 + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[2].inputMSB + EQ MID Deck A + 0xB1 + 0x03 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[2].inputLSB + EQ MID Deck A + 0xB1 + 0x23 + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[3].inputMSB + EQ HIGH Deck A + 0xB1 + 0x04 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[3].inputLSB + EQ HIGH Deck A + 0xB1 + 0x24 + + + + + + + [Channel1] + DJCi500.deckA.gainKnob.inputMSB + Gain Deck A + 0xB1 + 0x05 + + + + + + [Channel1] + DJCi500.deckA.gainKnob.inputLSB + Gain Deck A + 0xB1 + 0x25 + + + + + + + [Channel1] + DJCi500.deckA.filterKnob.input + Filter Deck A + 0xB1 + 0x01 + + + + + + + [Channel1] + DJCi500.deckA.pitchFader.inputMSB + 0xB1 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.pitchFader.inputLSB + 0xB1 + 0x28 + + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0x91 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0xB1 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputWheel + Scratch Deck A (Jog-Wheel) + 0xB1 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputWheel + Pitch Bend Deck A (Jog-Wheel) + 0xB1 + 0x09 + + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0x94 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputTouch + Jog Wheel Shift Touch Deck A + 0xB4 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputWheel + Scratch Deck A (Jog-Wheel) + 0xB4 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputWheel + Pitch Bend Deck A (Jog-Wheel) + 0xB4 + 0x09 + + + + + + + + + [Channel2] + DJCi500.deckB.volume.inputMSB + Volume Deck B + 0xB2 + 0x00 + + + + + + [Channel2] + DJCi500.deckB.volume.inputLSB + Volume Deck B + 0xB2 + 0x20 + + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[1].inputMSB + EQ LOW Deck B + 0xB2 + 0x02 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[1].inputLSB + EQ LOW Deck B + 0xB2 + 0x22 + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[2].inputMSB + EQ MID Deck B + 0xB2 + 0x03 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[2].inputLSB + EQ MID Deck B + 0xB2 + 0x23 + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[3].inputMSB + EQ HIGH Deck B + 0xB2 + 0x04 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[3].inputLSB + EQ HIGH Deck B + 0xB2 + 0x24 + + + + + + + [Channel2] + DJCi500.deckB.gainKnob.inputMSB + Gain Deck A + 0xB2 + 0x05 + + + + + + [Channel2] + DJCi500.deckB.gainKnob.inputLSB + Gain Deck A + 0xB2 + 0x25 + + + + + + + [Channel2] + DJCi500.deckB.filterKnob.input + Filter Deck B + 0xB2 + 0x01 + + + + + + + [Channel2] + DJCi500.deckB.pitchFader.inputMSB + 0xB2 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.pitchFader.inputLSB + 0xB2 + 0x28 + + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0x92 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0xB2 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputWheel + Scratch Deck B (Jog-Wheel) + 0xB2 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputWheel + Pitch Bend Deck B (Jog-Wheel) + 0xB2 + 0x09 + + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0x95 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputTouch + Jog Wheel Shift Touch Deck B + 0xB5 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputWheel + Scratch Deck B (Jog-Wheel) + 0xB5 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputWheel + Pitch Bend Deck B (Jog-Wheel) + 0xB5 + 0x09 + + + + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck1 (FX1 button) + 0x90 + 0x14 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck2 (FX2 button) + 0x90 + 0x15 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck3 (FX3 button) + 0x90 + 0x16 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck4 (FX4 button) + 0x90 + 0x17 + + + + + + + + + + + + + [Library] + MoveFocus + Browser LED (Green) + 0.5 + 1 + 0x90 + 0x05 + 0x10 + 0x05 + + + [Skin] + show_maximized_library + Browser LED (BLUE) + 0.5 + 1 + 0x90 + 0x05 + 0x05 + 0x10 + + + + [AutoDJ] + enabled + Auto DJ On + 0.5 + 1 + 0x90 + 0x03 + 0x7f + 0x0 + + + + From e236755cd05be82a725149c7a1256e0fb4829abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:19:02 +0100 Subject: [PATCH 02/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 89a2b9f48947..44f369c298c2 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1487,10 +1487,6 @@ DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { var bpm_file = engine.getValue(group, "file_bpm"), playposition = engine.getValue(group, "playposition"), duration = engine.getValue(group, "duration"); - /* - if (Math.floor((playposition * duration) * (bpm_file / 60.0)) > endLoop) { - engine.setValue(group, "beatjump", -8); - }*/ engine.setValue(group, "reloop_toggle", true);}, true); } From d022af74c6194fc85122a34cd29f83953a02fc2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:19:23 +0100 Subject: [PATCH 03/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 44f369c298c2..e178402cdc07 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -123,7 +123,6 @@ DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; //length of the Slicer domain DJCi500.slicerBeatsPassed = [0, 0, 0, 0]; DJCi500.slicerPreviousBeatsPassed = [0, 0, 0, 0]; DJCi500.slicerTimer = [false, false, false, false]; -//DJCi500.slicerJumping = [0, 0, 0, 0]; DJCi500.slicerActive = [false, false, false, false]; DJCi500.slicerAlreadyJumped = [false, false, false, false]; DJCi500.slicerButton = [-1, -1, -1, -1]; From 267a72f9d0637aaaf792b2882d18614e79b8fc37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:19:46 +0100 Subject: [PATCH 04/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index e178402cdc07..192967c3adf2 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -104,7 +104,6 @@ DJCi500.PadColorMapper = new ColorMapper({ }); // Constants - DJCi500.EFFECT_ONLY_MODE = 1; DJCi500.FILTER_AND_EFFECT_MODE = 2; From d4edbdddc974cab706045cf9c9d4dcc590caf39c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:20:00 +0100 Subject: [PATCH 05/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 1 + 1 file changed, 1 insertion(+) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 192967c3adf2..abba0c67b644 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -68,6 +68,7 @@ // // **************************************************************************** var DJCi500 = {}; + /////////////////////////////////////////////////////////////// // USER OPTIONS // /////////////////////////////////////////////////////////////// From e3fd7ef0f6c82a804b4b3901d3d1bc61b534b03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:20:23 +0100 Subject: [PATCH 06/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index abba0c67b644..f66d02f08811 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -116,7 +116,7 @@ const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; /////////////////////////////////////////////////////////////// // SLICER // /////////////////////////////////////////////////////////////// -DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; //length of the Slicer domain +DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; // Length of the Slicer domain //PioneerDDJSX.slicerDomains = [8, 16, 32, 64]; // slicer storage: From b8c7b6718c7020eab2d0ee706bfd307f7382489c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:20:34 +0100 Subject: [PATCH 07/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index f66d02f08811..48a86987ca35 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -112,7 +112,6 @@ DJCi500.FILTER_AND_EFFECT_MODE = 2; const pairColorsOn = [0x1F, 0x1F, 0x03, 0x03, 0x74, 0x74, 0x60, 0x60]; const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; - /////////////////////////////////////////////////////////////// // SLICER // /////////////////////////////////////////////////////////////// From a21d10dcdd6a27621ea6d38a2a947b831fb70950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:20:45 +0100 Subject: [PATCH 08/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 48a86987ca35..6bc0df70fb76 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -266,8 +266,8 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; // Pitch ranges and status - this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; //select pitch range - this.pitchRangeId = 0; //id of the array, one for each deck + this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; // Select pitch range + this.pitchRangeId = 0; // id of the array, one for each deck // Effect section components this.effectEnabled = false; From dbc50742eaba1c26a50c0df29a2c0580586e417d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:21:33 +0100 Subject: [PATCH 09/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- .../Hercules-DJControl-Inpulse-500-script.js | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 6bc0df70fb76..f00017fa20e4 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -277,18 +277,11 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { midi: [0x90 + midiChannel, 0x04], input: function(_channel, _control, value, _status, _group) { if (value === 0x7F) { - deckData.forEachComponent(function(component) { - if (component.unshift) { - component.shift(); - } - }); + deckData.shift(); } else { - deckData.forEachComponent(function(component) { - if (component.unshift) { - component.unshift(); - } - }); + deckData.unshift(); } + }, }); From b6b100a8cf7f9f20518180a8d7a5e98b3b9de001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:21:54 +0100 Subject: [PATCH 10/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index f00017fa20e4..3cc7ac9a97bc 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -311,7 +311,7 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { this.input = function (channel, control, value, status, group) { if (value === 0x7F) { if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched - var deck = parseInt(deckData.currentDeck.charAt(8)); + var deck = script.deckFromGroup(deckData.currentDeck); if (deckData.slowPauseSetState[deck - 1]) { engine.brake(deck, 1,//((status & 0xF0) !=== 0x80 && value > 0), From d5fa2c09a567481ed77167039b2ad7d856123563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:22:12 +0100 Subject: [PATCH 11/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 3cc7ac9a97bc..91005adc26cb 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -371,8 +371,8 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { unshift: function () { this.input = function(channel, _control, value, status, group) { if (value === 0x7F) { - var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; - var new_status = !deckData.vinylButtonState[deck]; + var deck = script.deckFromGroup(deckData.currentDeck); + var new_status = !deckData.vinylButtonState[deck - 1]; deckData.jogWheel.vinylMode = new_status; deckData.jogWheelShift.vinylMode = new_status; deckData.vinylButtonState[deck] = new_status; From f04380d77a150a865a6b15e61bffb9b348b55f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:22:38 +0100 Subject: [PATCH 12/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 91005adc26cb..0c81375f71f3 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -384,8 +384,9 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { shift: function () { this.input = function (channel, control, value, status, group) { if (value === 0x7F){ - var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; - deckData.slowPauseSetState[deck] = !deckData.slowPauseSetState[deck]; + var deck = script.deckFromGroup(deckData.currentDeck); + deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; + } }; } From 008cbcd885e6c61ae59cb2efba244cadbf1ff1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:22:55 +0100 Subject: [PATCH 13/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 0c81375f71f3..aea95da38bac 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -457,7 +457,7 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { rpm: 33 + 1/3, group: "[Channel"+midiChannel+"]", inputWheel: function(_channel, _control, value, _status, group) { - var deck = parseInt(deckData.currentDeck.charAt(8)); + var deck = script.deckFromGroup(deckData.currentDeck); value = this.inValueScale(value); if (engine.isScratching(deck)) { engine.scratchTick(deck, value); From 68e2b922f6f7951254153b171a2699549d9076c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:23:19 +0100 Subject: [PATCH 14/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index aea95da38bac..36dcde340b6c 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -466,7 +466,7 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { } }, inputTouch: function(channel, control, value, status, group) { - var deck = parseInt(deckData.currentDeck.charAt(8)); + var deck = script.deckFromGroup(deckData.currentDeck); if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { engine.scratchEnable(deck, this.wheelResolution, From a53db1c4d533000102c8767f0ff3d0aa13938679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:23:36 +0100 Subject: [PATCH 15/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 36dcde340b6c..7b9ee07ad04b 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -488,7 +488,7 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { rpm: 33 + 1/3, group: "[Channel"+midiChannel+"]", inputWheel: function(_channel, _control, value, _status, group) { - var deck = parseInt(deckData.currentDeck.charAt(8)); + var deck = script.deckFromGroup(deckData.currentDeck); value = this.inValueScale(value) * 4; if (engine.isScratching(deck)) { engine.scratchTick(deck, value); From fa367792b335022942bb37f89941d167c2a84d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:23:51 +0100 Subject: [PATCH 16/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 7b9ee07ad04b..9d952e18adc4 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1272,7 +1272,8 @@ DJCi500.tempoLEDs = function () { //Do beat alignement only if the tracks are already on Tempo // and only if they are playing - if ( (engine.getValue(deckA, "play_latched")) && (engine.getValue(deckB, "play_latched")) ){ + if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")){ + var beat1 = engine.getValue(deckA, "beat_distance"); var beat2 = engine.getValue(deckB, "beat_distance"); From 9e4febf17035baa984beb0cea73ea3d37a2f0f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:24:10 +0100 Subject: [PATCH 17/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 9d952e18adc4..460939389131 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -497,7 +497,7 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { } }, inputTouch: function(channel, control, value, status, group) { - var deck = parseInt(deckData.currentDeck.charAt(8)); + var deck = script.deckFromGroup(deckData.currentDeck); if (this.isPress(channel, control, value, status) && this.vinylMode) { engine.scratchEnable(deck, this.wheelResolution, From cbac34fddd709c78c66162e9b294359b9b26ee42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:24:29 +0100 Subject: [PATCH 18/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 460939389131..4cf7ff0ed4ef 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -582,12 +582,12 @@ DJCi500.Deck = function (deckNumbers, midiChannel) { for (var i = 1; i <= 8; i++) { this.padSelectButtons[i] = new components.Button({ midi: [0x90 + midiChannel, 0x0F + (i - 1)], - input: function(channel, control, value, status, group) { - var deck = parseInt(deckData.currentDeck.charAt(8)) - 1; + input: function(_channel, control, _value, _status, _group) { + var deck = script.deckFromGroup(deckData.currentDeck); if (control === 0x11) { - DJCi500.slicerActive[deck] = true; + DJCi500.slicerActive[deck - 1] = true; } else { - DJCi500.slicerActive[deck] = false; + DJCi500.slicerActive[deck - 1] = false; } }, }); From 6dca6d205ba88337e14df7cc6e07f91068513bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:24:47 +0100 Subject: [PATCH 19/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 4cf7ff0ed4ef..22b36432245e 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1194,7 +1194,7 @@ DJCi500.moveLibrary = function(channel, control, value, status, group) { } DJCi500.spinback_button = function(channel, control, value, status, group) { - var deck = parseInt(group.substring(8,9)); // work out which deck we are using + var deck = script.deckFromGroup(group); engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly } From e8b0480d1ad2861dbab61e994e2ac0479ffe2398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:25:03 +0100 Subject: [PATCH 20/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 22b36432245e..203c12186945 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1204,7 +1204,7 @@ DJCi500.tempoLEDs = function () { var deckA = DJCi500.deckA.currentDeck; var deckB = DJCi500.deckB.currentDeck; - //Tempo: + // Tempo: var tempo1 = engine.getValue(deckA, "bpm"); var tempo2 = engine.getValue(deckB, "bpm"); var diff = tempo1 - tempo2; From 70deb55e957c0fd42899a582f8a0fcfa86657c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:25:20 +0100 Subject: [PATCH 21/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 203c12186945..49cdd293e693 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1218,7 +1218,7 @@ DJCi500.tempoLEDs = function () { if ((tempo2 / tempo1) > 1.5){doubleTempo = 1; diff = tempo1 - tempo2/2;} } - if ( diff < -0.25) + if (diff < -0.25) { //Deck1 midi.sendShortMsg(0x91, 0x1E, 0x0); From 63d737efb8607c7d6a37882fc9fa4fe63f2f0e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:25:42 +0100 Subject: [PATCH 22/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- .../Hercules-DJControl-Inpulse-500-script.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 49cdd293e693..34ac64b24872 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1212,10 +1212,15 @@ DJCi500.tempoLEDs = function () { //Check double tempo: var doubleTempo = 0; if (diff > 0){ - if ((tempo1 / tempo2) > 1.5){doubleTempo = 1; diff = tempo1/2 - tempo2;} - } - else{ - if ((tempo2 / tempo1) > 1.5){doubleTempo = 1; diff = tempo1 - tempo2/2;} + if ((tempo1 / tempo2) > 1.5) { + doubleTempo = 1; + diff = tempo1 / 2 - tempo2; + } + } else { + if ((tempo2 / tempo1) > 1.5) { + doubleTempo = 1; + diff = tempo1 - tempo2 / 2; + } } if (diff < -0.25) From bf792bb453a9b4f89997ae06438dbccdc5526209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:25:52 +0100 Subject: [PATCH 23/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 34ac64b24872..d37ac8db1964 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1353,7 +1353,7 @@ DJCi500.updateDeckStatus = function(group) { // Update the vinyl button var vinylState = false; - var deckIndex = parseInt(group.charAt(8)) - 1; + var deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; var channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; if (channel === 1) { vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; From c68b201d1cf76f6c1febedda3362247ecbad59e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:26:01 +0100 Subject: [PATCH 24/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index d37ac8db1964..0d981298fc9a 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1516,7 +1516,7 @@ DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { //this below is connected to beat_active DJCi500.slicerBeatActive = function(value, group, control) { // This slicer implementation will work for constant beatgrids only! - var deck = parseInt(group.charAt(8)) - 1; + var deck = script.deckFromGroup(deckData.currentDeck) - 1; var channel = deck % 2; print("***** SLICER ACTIVE VALUE: " + DJCi500.slicerActive[deck]); From 97d28555db36700dcc1d9d08cbea2f2592b80c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:26:17 +0100 Subject: [PATCH 25/40] Update res/controllers/Hercules-DJControl-Inpulse-500-script.js Co-authored-by: Lukas Waslowski --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 0d981298fc9a..843e8fa50c1c 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1443,7 +1443,7 @@ DJCi500.updateEffectStatus = function(midiChannel, channel) { /////////////////////////////////////////////////////////////// DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { var index = control - 0x20, - deck = parseInt(group.charAt(8)) - 1, + deck = script.deckFromGroup(deckData.currentDeck) - 1, domain = DJCi500.selectedSlicerDomain[deck], beatsToJump = 0, passedTime = engine.getValue(group, "beat_distance"), From 33f710135210039a0c7fb013df385d3cd3890b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 10 Feb 2025 17:29:40 +0100 Subject: [PATCH 26/40] fix: re-tabbed to 4 spaces --- .../Hercules-DJControl-Inpulse-500-script.js | 2623 ++++++++--------- 1 file changed, 1311 insertions(+), 1312 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 843e8fa50c1c..b055a2c5672d 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1,4 +1,3 @@ - // DJControl_Inpulse_500_script.js // // *************************************************************************** @@ -84,24 +83,24 @@ DJCi500.initialVinylMode = true; // Colors DJCi500.PadColorMapper = new ColorMapper({ - 0xFF0000: 0x60, - 0xFFFF00: 0x7C, - 0x00FF00: 0x1C, - 0x00FFFF: 0x1F, - 0x0000FF: 0x03, - 0xFF00FF: 0x42, - 0xFF88FF: 0x63, - 0xFFFFFF: 0x7F, - 0x000088: 0x02, - 0x008800: 0x10, - 0x008888: 0x12, - 0x228800: 0x30, - 0x880000: 0x40, - 0x882200: 0x4C, - 0x888800: 0x50, - 0x888888: 0x52, - 0x88FF00: 0x5C, - 0xFF8800: 0x74, + 0xFF0000: 0x60, + 0xFFFF00: 0x7C, + 0x00FF00: 0x1C, + 0x00FFFF: 0x1F, + 0x0000FF: 0x03, + 0xFF00FF: 0x42, + 0xFF88FF: 0x63, + 0xFFFFFF: 0x7F, + 0x000088: 0x02, + 0x008800: 0x10, + 0x008888: 0x12, + 0x228800: 0x30, + 0x880000: 0x40, + 0x882200: 0x4C, + 0x888800: 0x50, + 0x888888: 0x52, + 0x88FF00: 0x5C, + 0xFF8800: 0x74, }); // Constants @@ -126,873 +125,873 @@ DJCi500.slicerActive = [false, false, false, false]; DJCi500.slicerAlreadyJumped = [false, false, false, false]; DJCi500.slicerButton = [-1, -1, -1, -1]; DJCi500.slicerModes = { - 'contSlice': 0, - 'loopSlice': 1 + 'contSlice': 0, + 'loopSlice': 1 }; DJCi500.activeSlicerMode = [ - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice ]; DJCi500.slicerLoopBeat8 = [0, 0, 0, 0]; /////////////////////// // Master VU Meter callbacks DJCi500.vuMeterUpdateMaster = function(value, _group, control) { - // Reserve the red led for peak indicator, this will in turn, make - // the display more similar (I hope) to what Mixxx VU shows - value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); - var control = (control === "vu_meter_left") ? 0x40 : 0x41; - midi.sendShortMsg(0xB0, control, value); + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); + var control = (control === "vu_meter_left") ? 0x40 : 0x41; + midi.sendShortMsg(0xB0, control, value); }; DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { - if (value) { - midi.sendShortMsg(0x90, 0x0A, 0x7F); - } else { - midi.sendShortMsg(0x90, 0x0A, 0x00); - } + if (value) { + midi.sendShortMsg(0x90, 0x0A, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0A, 0x00); + } }; DJCi500.vuMeterPeakRightMaster = function(value, group, control, status) { - if (value) { - midi.sendShortMsg(0x90, 0x0F, 0x7F); - } else { - midi.sendShortMsg(0x90, 0x0F, 0x00); - } + if (value) { + midi.sendShortMsg(0x90, 0x0F, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0F, 0x00); + } }; // Deck VU Meter callbacks DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { - // Reserve the red led for peak indicator, this will in turn, make - // the display more similar (I hope) to what Mixxx VU shows - value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); - if (DJCi500.deckA.currentDeck === group) { - midi.sendShortMsg(0xB1, 0x40, value); - } else if (DJCi500.deckB.currentDeck === group) { - midi.sendShortMsg(0xB2, 0x40, value); - } + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0xB1, 0x40, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0xB2, 0x40, value); + } }; DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { - var channel = 0x00; - if (DJCi500.deckA.currentDeck === group) { - channel = 0x91; - } else if (DJCi500.deckB.currentDeck === group) { - channel = 0x92; - } - - if (channel > 0x00) { - if (value) { - midi.sendShortMsg(channel, 0x39, 0x7F); - } else { - midi.sendShortMsg(channel, 0x39, 0x00); + var channel = 0x00; + if (DJCi500.deckA.currentDeck === group) { + channel = 0x91; + } else if (DJCi500.deckB.currentDeck === group) { + channel = 0x92; + } + + if (channel > 0x00) { + if (value) { + midi.sendShortMsg(channel, 0x39, 0x7F); + } else { + midi.sendShortMsg(channel, 0x39, 0x00); + } } - } }; DJCi500.numberIndicator = function(value, group, _control, _status) { - if (DJCi500.deckA.currentDeck === group) { - midi.sendShortMsg(0x91, 0x30, value); - } else if (DJCi500.deckB.currentDeck === group) { - midi.sendShortMsg(0x92, 0x30, value); - } + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0x91, 0x30, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0x92, 0x30, value); + } } DJCi500.fxSelIndicator = function(_value, group, _control, _status) { - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - var active = false; - - if (group === "[EffectRack1_EffectUnit1]") { - active = engine.getValue(group, 'group_' + deckA + '_enable'); - if (active) { - midi.sendShortMsg(0x96, 0x63, 0x74); - } else { - midi.sendShortMsg(0x96, 0x63, 0x00); - } - active = engine.getValue(group, 'group_' + deckB + '_enable'); - if (active) { - midi.sendShortMsg(0x97, 0x63, 0x74); - } else { - midi.sendShortMsg(0x97, 0x63, 0x00); - } - } else if (group === "[EffectRack1_EffectUnit2]") { - active = engine.getValue(group, 'group_' + deckA + '_enable'); - if (active) { - midi.sendShortMsg(0x96, 0x67, 0x74); - } else { - midi.sendShortMsg(0x96, 0x67, 0x00); - } - active = engine.getValue(group, 'group_' + deckB + '_enable'); - if (active) { - midi.sendShortMsg(0x97, 0x67, 0x74); - } else { - midi.sendShortMsg(0x97, 0x67, 0x00); + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + var active = false; + + if (group === "[EffectRack1_EffectUnit1]") { + active = engine.getValue(group, 'group_' + deckA + '_enable'); + if (active) { + midi.sendShortMsg(0x96, 0x63, 0x74); + } else { + midi.sendShortMsg(0x96, 0x63, 0x00); + } + active = engine.getValue(group, 'group_' + deckB + '_enable'); + if (active) { + midi.sendShortMsg(0x97, 0x63, 0x74); + } else { + midi.sendShortMsg(0x97, 0x63, 0x00); + } + } else if (group === "[EffectRack1_EffectUnit2]") { + active = engine.getValue(group, 'group_' + deckA + '_enable'); + if (active) { + midi.sendShortMsg(0x96, 0x67, 0x74); + } else { + midi.sendShortMsg(0x96, 0x67, 0x00); + } + active = engine.getValue(group, 'group_' + deckB + '_enable'); + if (active) { + midi.sendShortMsg(0x97, 0x67, 0x74); + } else { + midi.sendShortMsg(0x97, 0x67, 0x00); + } } - } } DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - var active = engine.getValue(group, 'enabled'); - - if (group == "[QuickEffectRack1_" + deckA + "]") { - midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60) - } else if (group == "[QuickEffectRack1_" + deckB + "]") { - midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60) - } + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + var active = engine.getValue(group, 'enabled'); + + if (group == "[QuickEffectRack1_" + deckA + "]") { + midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60) + } else if (group == "[QuickEffectRack1_" + deckB + "]") { + midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60) + } } DJCi500.Deck = function (deckNumbers, midiChannel) { - components.Deck.call(this, deckNumbers); - // Allow components to access deck variables - var deckData = this; - - // For loop and looprolls - var fractions = ['0.125', '0.25', '0.5', '1', '2', '4', '8', '16']; - var shiftFractions = ['0.03125', '0.0625', '32', '64', '128', '256', '512', '512']; - - // For beatjumps - var jumpValues = ['1', '1', '2', '2', '4', '4', '8', '8']; - var jumpValuesShift = ['16', '16', '32', '32', '64', '64', '128', '128']; - - // Brake status for this deck - this.slowPauseSetState = [false, false, false, false]; - - // Vinyl button state - this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; - - // Pitch ranges and status - this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; // Select pitch range - this.pitchRangeId = 0; // id of the array, one for each deck - - // Effect section components - this.effectEnabled = false; - - // Make sure the shift button remaps the shift actions - this.shiftButton = new components.Button({ - midi: [0x90 + midiChannel, 0x04], - input: function(_channel, _control, value, _status, _group) { - if (value === 0x7F) { - deckData.shift(); - } else { - deckData.unshift(); - } - - }, - }); - - this.loadButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0D], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.inKey = 'LoadSelectedTrack'; - }, - shift: function () { - this.inKey = 'eject'; - }, - }); - - // Transport section - // Play button, for some reason the group is not correct on this one? - this.playButton = new components.PlayButton({ - midi: [0x90 + midiChannel, 0x07], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.input = function (channel, control, value, status, group) { - if (value === 0x7F) { - if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched - var deck = script.deckFromGroup(deckData.currentDeck); - if (deckData.slowPauseSetState[deck - 1]) { - engine.brake(deck, - 1,//((status & 0xF0) !=== 0x80 && value > 0), - 54); + components.Deck.call(this, deckNumbers); + // Allow components to access deck variables + var deckData = this; + + // For loop and looprolls + var fractions = ['0.125', '0.25', '0.5', '1', '2', '4', '8', '16']; + var shiftFractions = ['0.03125', '0.0625', '32', '64', '128', '256', '512', '512']; + + // For beatjumps + var jumpValues = ['1', '1', '2', '2', '4', '4', '8', '8']; + var jumpValuesShift = ['16', '16', '32', '32', '64', '64', '128', '128']; + + // Brake status for this deck + this.slowPauseSetState = [false, false, false, false]; + + // Vinyl button state + this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; + + // Pitch ranges and status + this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; // Select pitch range + this.pitchRangeId = 0; // id of the array, one for each deck + + // Effect section components + this.effectEnabled = false; + + // Make sure the shift button remaps the shift actions + this.shiftButton = new components.Button({ + midi: [0x90 + midiChannel, 0x04], + input: function(_channel, _control, value, _status, _group) { + if (value === 0x7F) { + deckData.shift(); } else { - script.toggleControl(deckData.currentDeck, "play"); + deckData.unshift(); } - } else { - script.toggleControl(deckData.currentDeck, "play"); - } - } - }; - }, - shift: function () { - this.input = function (_channel, _control, _value, _status, group) { - engine.setValue(deckData.currentDeck, "play_stutter", true); - }; - }, - }); - - this.cueButton = new components.CueButton({ - midi: [0x90 + midiChannel, 0x06], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - shift: function () { - this.inKey = "start_play"; - }, - }); - - this.syncButton = new components.SyncButton({ - midi: [0x90 + midiChannel, 0x05], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - shift: function () { - this.inKey = "sync_key"; - }, - }); - - this.pflButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0C], - type: components.Button.prototype.types.toggle, - key: 'pfl', - }); - - // Top controls - // Vinyl button - this.vinylButton = new components.Button({ - midi: [0x90 + midiChannel, 0x03], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.input = function(channel, _control, value, status, group) { - if (value === 0x7F) { - var deck = script.deckFromGroup(deckData.currentDeck); - var new_status = !deckData.vinylButtonState[deck - 1]; - deckData.jogWheel.vinylMode = new_status; - deckData.jogWheelShift.vinylMode = new_status; - deckData.vinylButtonState[deck] = new_status; - var new_message = new_status ? 0x7F : 0x00; - midi.sendShortMsg(this.midi[0], 0x03, new_message); - } - }; - }, - shift: function () { - this.input = function (channel, control, value, status, group) { - if (value === 0x7F){ - var deck = script.deckFromGroup(deckData.currentDeck); - deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; + }, + }); + + this.loadButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0D], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.inKey = 'LoadSelectedTrack'; + }, + shift: function () { + this.inKey = 'eject'; + }, + }); + + // Transport section + // Play button, for some reason the group is not correct on this one? + this.playButton = new components.PlayButton({ + midi: [0x90 + midiChannel, 0x07], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.input = function (channel, control, value, status, group) { + if (value === 0x7F) { + if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched + var deck = script.deckFromGroup(deckData.currentDeck); + if (deckData.slowPauseSetState[deck - 1]) { + engine.brake(deck, + 1,//((status & 0xF0) !=== 0x80 && value > 0), + 54); + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } + }; + }, + shift: function () { + this.input = function (_channel, _control, _value, _status, group) { + engine.setValue(deckData.currentDeck, "play_stutter", true); + }; + }, + }); + + this.cueButton = new components.CueButton({ + midi: [0x90 + midiChannel, 0x06], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function () { + this.inKey = "start_play"; + }, + }); + + this.syncButton = new components.SyncButton({ + midi: [0x90 + midiChannel, 0x05], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function () { + this.inKey = "sync_key"; + }, + }); + + this.pflButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0C], + type: components.Button.prototype.types.toggle, + key: 'pfl', + }); + + // Top controls + // Vinyl button + this.vinylButton = new components.Button({ + midi: [0x90 + midiChannel, 0x03], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.input = function(channel, _control, value, status, group) { + if (value === 0x7F) { + var deck = script.deckFromGroup(deckData.currentDeck); + var new_status = !deckData.vinylButtonState[deck - 1]; + deckData.jogWheel.vinylMode = new_status; + deckData.jogWheelShift.vinylMode = new_status; + deckData.vinylButtonState[deck] = new_status; + var new_message = new_status ? 0x7F : 0x00; + midi.sendShortMsg(this.midi[0], 0x03, new_message); + } + }; + }, + shift: function () { + this.input = function (channel, control, value, status, group) { + if (value === 0x7F){ + var deck = script.deckFromGroup(deckData.currentDeck); + deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; + + } + }; } - }; - } - }); - - // SLIP mode button - this.slipButton = new components.Button({ - midi: [0x90 + midiChannel, 0x01], - type: components.Button.prototype.types.toggle, - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - key: 'slip_enabled', - }); - - // Quant button - this.quantButton = new components.Button({ - midi: [0x90 + midiChannel, 0x02], - type: components.Button.prototype.types.toggle, - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'quantize', - unshift: function () { - this.inKey = 'quantize'; - }, - shift: function () { - this.inKey = 'keylock'; - }, - }); - - // Knobs - this.volume = new components.Pot({ - midi: [0xB0 + midiChannel, 0x00], - inKey: 'volume', - }); - - this.eqKnob = []; - for (var k = 1; k <= 3; k++) { - this.eqKnob[k] = new components.Pot({ - midi: [0xB0 + midiChannel, 0x01 + k], - group: '[EqualizerRack1_' + this.currentDeck + '_Effect1]', - inKey: 'parameter' + k, }); - } - - this.gainKnob = new components.Pot({ - midi: [0xB0 + midiChannel, 0x05], - key: 'pregain', - }); - - // Pitch-tempo fader - this.pitchFader = new components.Pot({ - midi: [0xB0 + midiChannel, 0x08], - key: 'rate', - }); - - // Jog Wheel - // TODO: Handle with less repeat the shift key for this - this.jogWheel = new components.JogWheelBasic({ - midi: [0xB0 + midiChannel, 0x0A], - deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it - wheelResolution: 720, // how many ticks per revolution the jogwheel has - alpha: 5/6, - beta: (5/6)/128, - rpm: 33 + 1/3, - group: "[Channel"+midiChannel+"]", - inputWheel: function(_channel, _control, value, _status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - value = this.inValueScale(value); - if (engine.isScratching(deck)) { - engine.scratchTick(deck, value); - } else { - engine.setValue(group, 'jog', value); - } - }, - inputTouch: function(channel, control, value, status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { - engine.scratchEnable(deck, - this.wheelResolution, - this.rpm, - this.alpha, - this.beta); - } else { - engine.scratchDisable(deck); - } - }, - }); - - this.jogWheelShift = new components.JogWheelBasic({ - midi: [0xB3 + midiChannel, 0x0A], - deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it - wheelResolution: 720, // how many ticks per revolution the jogwheel has - alpha: 5/6, - beta: (5/6)/128, - rpm: 33 + 1/3, - group: "[Channel"+midiChannel+"]", - inputWheel: function(_channel, _control, value, _status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - value = this.inValueScale(value) * 4; - if (engine.isScratching(deck)) { - engine.scratchTick(deck, value); - } else { - engine.setValue(group, 'jog', value); - } - }, - inputTouch: function(channel, control, value, status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if (this.isPress(channel, control, value, status) && this.vinylMode) { - engine.scratchEnable(deck, - this.wheelResolution, - this.rpm, - this.alpha, - this.beta); - } else { - engine.scratchDisable(deck); - } - }, - }); - - // Loop controls - this.loopInButton = new components.Button({ - midi: [0x90 + midiChannel, 0x09], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'loop_enabled', // TODO: Check with loop_in? - unshift: function () { - this.inKey = 'loop_in'; - }, - shift: function () { - this.inKey = 'loop_in_goto'; - }, - }); - - this.loopOutButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0A], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'loop_enabled', // TODO: Check with loop_in? - unshift: function () { - this.inKey = 'loop_out'; - }, - shift: function () { - this.inKey = 'loop_out_goto'; - }, - }); - - // Loop rotary encoder functions - // - // Push the rotary encoder - this.loopEncoderPush = new components.Button({ - midi: [0x90 + midiChannel, 0x2C], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.inKey = 'reloop_toggle'; - }, - shift: function () { - this.inKey = 'beatloop_4_activate'; - }, - }); - - // Loop encoder - this.loopEncoder = new components.Encoder({ - midi: [0xB0 + midiChannel, 0x0E], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - input: function (channel, control, value, status, group) { - // FIXME: Toggle for loop halve and double?? - var deckGroup = deckData.currentDeck; - if (value >= 0x40) { - engine.setValue(deckGroup, "loop_halve", true); - } else { - engine.setValue(deckGroup, "loop_double", true); - } + + // SLIP mode button + this.slipButton = new components.Button({ + midi: [0x90 + midiChannel, 0x01], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + key: 'slip_enabled', + }); + + // Quant button + this.quantButton = new components.Button({ + midi: [0x90 + midiChannel, 0x02], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'quantize', + unshift: function () { + this.inKey = 'quantize'; + }, + shift: function () { + this.inKey = 'keylock'; + }, + }); + + // Knobs + this.volume = new components.Pot({ + midi: [0xB0 + midiChannel, 0x00], + inKey: 'volume', + }); + + this.eqKnob = []; + for (var k = 1; k <= 3; k++) { + this.eqKnob[k] = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01 + k], + group: '[EqualizerRack1_' + this.currentDeck + '_Effect1]', + inKey: 'parameter' + k, + }); } - }); - - // We only check and attach for slicer mode, but we have all - // pad buttons here if we need something extra! - this.padSelectButtons = []; - for (var i = 1; i <= 8; i++) { - this.padSelectButtons[i] = new components.Button({ - midi: [0x90 + midiChannel, 0x0F + (i - 1)], - input: function(_channel, control, _value, _status, _group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if (control === 0x11) { - DJCi500.slicerActive[deck - 1] = true; - } else { - DJCi500.slicerActive[deck - 1] = false; + + this.gainKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x05], + key: 'pregain', + }); + + // Pitch-tempo fader + this.pitchFader = new components.Pot({ + midi: [0xB0 + midiChannel, 0x08], + key: 'rate', + }); + + // Jog Wheel + // TODO: Handle with less repeat the shift key for this + this.jogWheel = new components.JogWheelBasic({ + midi: [0xB0 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: "[Channel"+midiChannel+"]", + inputWheel: function(_channel, _control, value, _status, group) { + var deck = script.deckFromGroup(deckData.currentDeck); + value = this.inValueScale(value); + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, 'jog', value); + } + }, + inputTouch: function(channel, control, value, status, group) { + var deck = script.deckFromGroup(deckData.currentDeck); + if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + this.jogWheelShift = new components.JogWheelBasic({ + midi: [0xB3 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: "[Channel"+midiChannel+"]", + inputWheel: function(_channel, _control, value, _status, group) { + var deck = script.deckFromGroup(deckData.currentDeck); + value = this.inValueScale(value) * 4; + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, 'jog', value); + } + }, + inputTouch: function(channel, control, value, status, group) { + var deck = script.deckFromGroup(deckData.currentDeck); + if (this.isPress(channel, control, value, status) && this.vinylMode) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + // Loop controls + this.loopInButton = new components.Button({ + midi: [0x90 + midiChannel, 0x09], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'loop_enabled', // TODO: Check with loop_in? + unshift: function () { + this.inKey = 'loop_in'; + }, + shift: function () { + this.inKey = 'loop_in_goto'; + }, + }); + + this.loopOutButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0A], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: 'loop_enabled', // TODO: Check with loop_in? + unshift: function () { + this.inKey = 'loop_out'; + }, + shift: function () { + this.inKey = 'loop_out_goto'; + }, + }); + + // Loop rotary encoder functions + // + // Push the rotary encoder + this.loopEncoderPush = new components.Button({ + midi: [0x90 + midiChannel, 0x2C], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function () { + this.inKey = 'reloop_toggle'; + }, + shift: function () { + this.inKey = 'beatloop_4_activate'; + }, + }); + + // Loop encoder + this.loopEncoder = new components.Encoder({ + midi: [0xB0 + midiChannel, 0x0E], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + input: function (channel, control, value, status, group) { + // FIXME: Toggle for loop halve and double?? + var deckGroup = deckData.currentDeck; + if (value >= 0x40) { + engine.setValue(deckGroup, "loop_halve", true); + } else { + engine.setValue(deckGroup, "loop_double", true); + } } - }, }); - } - - // Hotcue buttons (PAD Mode 1) - this.hotcueButtons = []; - for (var i = 1; i <= 8; i++) { - this.hotcueButtons[i] = new components.HotcueButton({ - midi: [0x95 + midiChannel, 0x00 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - colorMapper: DJCi500.PadColorMapper, - off: 0x00, + + // We only check and attach for slicer mode, but we have all + // pad buttons here if we need something extra! + this.padSelectButtons = []; + for (var i = 1; i <= 8; i++) { + this.padSelectButtons[i] = new components.Button({ + midi: [0x90 + midiChannel, 0x0F + (i - 1)], + input: function(_channel, control, _value, _status, _group) { + var deck = script.deckFromGroup(deckData.currentDeck); + if (control === 0x11) { + DJCi500.slicerActive[deck - 1] = true; + } else { + DJCi500.slicerActive[deck - 1] = false; + } + }, + }); + } + + // Hotcue buttons (PAD Mode 1) + this.hotcueButtons = []; + for (var i = 1; i <= 8; i++) { + this.hotcueButtons[i] = new components.HotcueButton({ + midi: [0x95 + midiChannel, 0x00 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + colorMapper: DJCi500.PadColorMapper, + off: 0x00, + }); + }; + + // Loop buttons (PAD Mode 2) + this.loopButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1)], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: 'beatloop_' + fractions[i - 1] + '_enabled', + inKey: 'beatloop_' + fractions[i - 1] + '_toggle', + }); + }; + + // A bit repeated code, but I want the leds to react accordingly + this.loopShiftButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopShiftButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: 'beatloop_' + shiftFractions[i - 1] + '_enabled', + inKey: 'beatloop_' + shiftFractions[i - 1] + '_toggle', + }); + }; + + // Slicer buttons (PAD Mode 3) + this.slicerButtons = []; + for (var i = 1; i <= 8; i++) { + this.slicerButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x20 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + input: function(channel, control, value, status, group) { + // This is kind of a hack... somehow this is not getting the group correctly! + DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); + }, + }); + }; + + // Sampler buttons (PAD Mode 4) + this.samplerButtons = []; + for (var i = 1; i <= 8; i++) { + this.samplerButtons[i] = new components.SamplerButton({ + midi: [0x95 + midiChannel, 0x30 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + loaded: 0x42, + empty: 0x00, + playing: 0x63, + looping: 0x74, + }); + }; + + // Pitch buttons (PAD Mode 5) + this.pitchDownTone = new components.Button({ + midi: [0x95 + midiChannel, 0x40], + on: pairColorsOn[0], + off: pairColorsOff[0], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_down", 1); + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchDownSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x41], + on: pairColorsOn[1], + off: pairColorsOff[1], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchUpSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x42], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, }); - }; - - // Loop buttons (PAD Mode 2) - this.loopButtons = []; - for (var i = 1; i <= 8; i++) { - this.loopButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x10 + (i - 1)], - number: i, - shiftControl: false, - sendShifted: false, - on: 0x5C, - off: 0x30, - outKey: 'beatloop_' + fractions[i - 1] + '_enabled', - inKey: 'beatloop_' + fractions[i - 1] + '_toggle', + + this.pitchUpTone = new components.Button({ + midi: [0x95 + midiChannel, 0x43], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + engine.setValue(group, "pitch_up", 1); + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } + else { + midi.sendShortMsg(status, control, this.off); + } + }, }); - }; - - // A bit repeated code, but I want the leds to react accordingly - this.loopShiftButtons = []; - for (var i = 1; i <= 8; i++) { - this.loopShiftButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], - number: i, - shiftControl: false, - sendShifted: false, - on: 0x5C, - off: 0x30, - outKey: 'beatloop_' + shiftFractions[i - 1] + '_enabled', - inKey: 'beatloop_' + shiftFractions[i - 1] + '_toggle', + + this.pitchSliderIncrease = new components.Button({ + midi: [0x95 + midiChannel, 0x46], + on: 0x63, + off: 0x42, + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId++; + if (deckData.pitchRangeId > 6) + { + deckData.pitchRangeId = 6; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, }); - }; - - // Slicer buttons (PAD Mode 3) - this.slicerButtons = []; - for (var i = 1; i <= 8; i++) { - this.slicerButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x20 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - input: function(channel, control, value, status, group) { - // This is kind of a hack... somehow this is not getting the group correctly! - DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); - }, + + this.pitchSliderDecrease = new components.Button({ + midi: [0x95 + midiChannel, 0x45], + on: pairColorsOn[3], + off: pairColorsOff[3], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId = deckData.pitchRangeId - 1; + if (deckData.pitchRangeId < 0) + { + deckData.pitchRangeId = 0; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, }); - }; - - // Sampler buttons (PAD Mode 4) - this.samplerButtons = []; - for (var i = 1; i <= 8; i++) { - this.samplerButtons[i] = new components.SamplerButton({ - midi: [0x95 + midiChannel, 0x30 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - loaded: 0x42, - empty: 0x00, - playing: 0x63, - looping: 0x74, + + this.pitchSliderReset = new components.Button({ + midi: [0x95 + midiChannel, 0x44], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function (channel, control, value, status, group) { + if (value === 0x7F){ + deckData.pitchRangeId = 0; + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, }); - }; - - // Pitch buttons (PAD Mode 5) - this.pitchDownTone = new components.Button({ - midi: [0x95 + midiChannel, 0x40], - on: pairColorsOn[0], - off: pairColorsOff[0], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_down", 1); - engine.setValue(group, "pitch_down", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchDownSemiTone = new components.Button({ - midi: [0x95 + midiChannel, 0x41], - on: pairColorsOn[1], - off: pairColorsOff[1], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_down", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchUpSemiTone = new components.Button({ - midi: [0x95 + midiChannel, 0x42], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_up", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchUpTone = new components.Button({ - midi: [0x95 + midiChannel, 0x43], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_up", 1); - engine.setValue(group, "pitch_up", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchSliderIncrease = new components.Button({ - midi: [0x95 + midiChannel, 0x46], - on: 0x63, - off: 0x42, - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId++; - if (deckData.pitchRangeId > 6) - { - deckData.pitchRangeId = 6; + + // Beatloop rolls buttons (PAD Mode 6) + this.rollButtons = []; + for (var i = 1; i <= 8; i++) { + this.rollButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x50 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: 0x1F, + off: 0x12, + key: 'beatlooproll_' + fractions[i - 1] + '_activate', + }); + }; + + // Effect buttons (PAD Mode 7) + this.effectButtons = []; + for (var i = 1; i <= 3; i++) { + // First top row effects buttons, just the effect, disable HPF/LPF knob + this.effectButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x60 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", + outKey: "enabled", + output: function (value, group, control) { + if (value) { + this.send(0x7F); + } else { + this.send(0x7C); + } + }, + unshift: function() { + // Normal effect button operation, toggling the effect assigned to it + this.input = function (channel, control, value, status, group) { + var fxNo = control - 0x5F; + var unit = channel - 0x95; + if (value === 0x7F){ + script.toggleControl(this.group, "enabled"); + } + }; + }, + shift: function () { + // Shift button will change the effect to the next in the list + this.input = function (channel, control, value, status, group) { + var fxNo = control - 0x67; + var unit = channel - 0x95; + if (value === 0x7F){ + engine.setValue(this.group, 'effect_selector', +1); + } + }; + } + }); + }; + + // Effect chain selectors + this.effectButtons[5] = new components.Button({ + midi: [0x95 + midiChannel, 0x64], + number: 5, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + on: 0x5C, + off: 0x30, + input: function (channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, 'chain_preset_selector', -1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - this.pitchSliderDecrease = new components.Button({ - midi: [0x95 + midiChannel, 0x45], - on: pairColorsOn[3], - off: pairColorsOff[3], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId = deckData.pitchRangeId - 1; - if (deckData.pitchRangeId < 0) - { - deckData.pitchRangeId = 0; + }); + + this.effectButtons[6] = new components.Button({ + midi: [0x95 + midiChannel, 0x65], + number: 6, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + on: 0x5C, + off: 0x30, + input: function (channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, 'chain_preset_selector', 1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } + else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - this.pitchSliderReset = new components.Button({ - midi: [0x95 + midiChannel, 0x44], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId = 0; - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - // Beatloop rolls buttons (PAD Mode 6) - this.rollButtons = []; - for (var i = 1; i <= 8; i++) { - this.rollButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x50 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - on: 0x1F, - off: 0x12, - key: 'beatlooproll_' + fractions[i - 1] + '_activate', }); - }; - - // Effect buttons (PAD Mode 7) - this.effectButtons = []; - for (var i = 1; i <= 3; i++) { - // First top row effects buttons, just the effect, disable HPF/LPF knob - this.effectButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x60 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", - outKey: "enabled", - output: function (value, group, control) { - if (value) { - this.send(0x7F); - } else { - this.send(0x7C); + + // Filter kill switch + this.effectButtons[7] = new components.Button({ + midi: [0x95 + midiChannel, 0x66], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + input: function (_channel, _control, value, _status, _group) { + if (value === 0x7F) { + script.toggleControl(this.group, 'enabled'); + } } - }, - unshift: function() { - // Normal effect button operation, toggling the effect assigned to it - this.input = function (channel, control, value, status, group) { - var fxNo = control - 0x5F; - var unit = channel - 0x95; - if (value === 0x7F){ - script.toggleControl(this.group, "enabled"); - } - }; - }, - shift: function () { - // Shift button will change the effect to the next in the list - this.input = function (channel, control, value, status, group) { - var fxNo = control - 0x67; - var unit = channel - 0x95; - if (value === 0x7F){ - engine.setValue(this.group, 'effect_selector', +1); - } - }; - } }); - }; - - // Effect chain selectors - this.effectButtons[5] = new components.Button({ - midi: [0x95 + midiChannel, 0x64], - number: 5, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - on: 0x5C, - off: 0x30, - input: function (channel, control, value, status, group) { - if (value === 0x7F) { - engine.setValue(this.group, 'chain_preset_selector', -1); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - } - }); - - this.effectButtons[6] = new components.Button({ - midi: [0x95 + midiChannel, 0x65], - number: 6, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - on: 0x5C, - off: 0x30, - input: function (channel, control, value, status, group) { - if (value === 0x7F) { - engine.setValue(this.group, 'chain_preset_selector', 1); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - } - }); - - // Filter kill switch - this.effectButtons[7] = new components.Button({ - midi: [0x95 + midiChannel, 0x66], - number: 4, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - input: function (_channel, _control, value, _status, _group) { - if (value === 0x7F) { - script.toggleControl(this.group, 'enabled'); - } - } - }); - - // Set the current channel FX route with the two extra PADs - this.effectButtons[4] = new components.Button({ - midi: [0x95 + midiChannel, 0x63], - number: 4, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[EffectRack1_EffectUnit1]", - input: function (channel, _control, value, _status, group) { - if (value === 0x7F) { - var deckGroup = deckData.currentDeck; - script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); - } - } - }); - - this.effectButtons[8] = new components.Button({ - midi: [0x95 + midiChannel, 0x67], - number: 8, - shiftOffset: 8, - shiftControl: true, - sendShifted: false, - group: "[EffectRack1_EffectUnit2]", - input: function (_channel, _control, value, _status, _group) { - if (value === 0x7F) { - var deckGroup = deckData.currentDeck; - script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); - } - } - }); - - // Filter knob is here since it is affected by effects pads - this.filterKnob = new components.Pot({ - midi: [0xB0 + midiChannel, 0x01], - number: midiChannel, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - input: function (channel, control, value, status, group) { - if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { - // Move the effects knobs - engine.setValue("[EffectRack1_EffectUnit" + this.number + "]", "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2 ); - } else { - // Move the filter knob - engine.setValue("[QuickEffectRack1_" + deckData.currentDeck + "]", "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); - } - }, - }); - - // Beat jump (PAD Mode 8) - this.beatJumpButtons = []; - for (var i = 1; i <= 8; i++) { - var movement = (i % 2 === 0) ? '_forward' : '_backward'; - var jmpVal = jumpValues[i - 1]; - var jmpValShft = jumpValuesShift[i - 1]; - this.beatJumpButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x70 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - on: pairColorsOn[i - 1], - off: pairColorsOff[i - 1], - jump: 'beatjump_' + jmpVal + movement, - jumpShift: 'beatjump_' + jmpValShft + movement, - unshift: function () { - this.input = function(_channel, control, value, status, _group) { - if (value === 0x7F) { - engine.setValue(deckData.currentDeck, this.jump, true); - midi.sendShortMsg(status, control, this.on); - } else { - midi.sendShortMsg(status, control, this.off); - } + + // Set the current channel FX route with the two extra PADs + this.effectButtons[4] = new components.Button({ + midi: [0x95 + midiChannel, 0x63], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[EffectRack1_EffectUnit1]", + input: function (channel, _control, value, _status, group) { + if (value === 0x7F) { + var deckGroup = deckData.currentDeck; + script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); + } } - }, - shift: function () { - this.input = function(_channel, control, value, status, _group) { - if (value === 0x7F) { - engine.setValue(deckData.currentDeck, this.jumpShift, true); - midi.sendShortMsg(status, control, this.on); - } else { - midi.sendShortMsg(status, control, this.off); - } + }); + + this.effectButtons[8] = new components.Button({ + midi: [0x95 + midiChannel, 0x67], + number: 8, + shiftOffset: 8, + shiftControl: true, + sendShifted: false, + group: "[EffectRack1_EffectUnit2]", + input: function (_channel, _control, value, _status, _group) { + if (value === 0x7F) { + var deckGroup = deckData.currentDeck; + script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); + } } - }, }); - }; - // As per Mixxx wiki, set the group properties - this.reconnectComponents(function (c) { - if (c.group === undefined) { - c.group = this.currentDeck; - } - }); + // Filter knob is here since it is affected by effects pads + this.filterKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01], + number: midiChannel, + group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", + input: function (channel, control, value, status, group) { + if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { + // Move the effects knobs + engine.setValue("[EffectRack1_EffectUnit" + this.number + "]", "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2 ); + } else { + // Move the filter knob + engine.setValue("[QuickEffectRack1_" + deckData.currentDeck + "]", "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); + } + }, + }); + + // Beat jump (PAD Mode 8) + this.beatJumpButtons = []; + for (var i = 1; i <= 8; i++) { + var movement = (i % 2 === 0) ? '_forward' : '_backward'; + var jmpVal = jumpValues[i - 1]; + var jmpValShft = jumpValuesShift[i - 1]; + this.beatJumpButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x70 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: pairColorsOn[i - 1], + off: pairColorsOff[i - 1], + jump: 'beatjump_' + jmpVal + movement, + jumpShift: 'beatjump_' + jmpValShft + movement, + unshift: function () { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jump, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + } + }, + shift: function () { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jumpShift, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + } + }, + }); + }; + + // As per Mixxx wiki, set the group properties + this.reconnectComponents(function (c) { + if (c.group === undefined) { + c.group = this.currentDeck; + } + }); } // Give the custom Deck all the methods of the generic deck @@ -1000,561 +999,561 @@ DJCi500.Deck.prototype = new components.Deck(); // INIT for the controller and decks DJCi500.init = function() { - DJCi500.AutoHotcueColors = true; - - // Take care of the status of the crossfader status - DJCi500.crossfaderEnabled = true; - DJCi500.xFaderScratch = false; - - // Setup Vinyl buttons LED(one for each deck). - midi.sendShortMsg(0x91, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); - midi.sendShortMsg(0x92, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); - - //Turn On Browser button LED - midi.sendShortMsg(0x90, 0x05, 0x10); - - // Connect the VUMeters - engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); - - // Deck VU meters peak indicators - engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel2]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel3]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel4]", "peak_indicator", DJCi500.vuMeterPeakDeck); - - // Connect number leds - engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); - - // Connect Master VU meter - engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); - engine.makeConnection("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); - engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); - engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); - - engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); - engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); - - // Connect the FX selection leds - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); - - engine.makeConnection("[QuickEffectRack1_[Channel1]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel2]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel3]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel4]]", "enabled", DJCi500.fxEnabledIndicator); - - // Connect the slicer beats - DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); - //var controlsToFunctions = {'beat_active': 'DJCi500.slicerBeatActive'}; - //script.bindConnections('[Channel1]', controlsToFunctions, true); - - // Ask the controller to send all current knob/slider values over MIDI, which will update - // the corresponding GUI controls in MIXXX. - midi.sendShortMsg(0xB0, 0x7F, 0x7F); - - // Turn on lights: - for (var i = 0; i < 2; i++) { - // PAD 5 Key and tempo range controls - midi.sendShortMsg(0x96+i, 0x40, 0x12); - midi.sendShortMsg(0x96+i, 0x41, 0x12); - midi.sendShortMsg(0x96+i, 0x42, 0x40); - midi.sendShortMsg(0x96+i, 0x43, 0x40); - midi.sendShortMsg(0x96+i, 0x44, 0x40); - midi.sendShortMsg(0x96+i, 0x45, 0x02); - midi.sendShortMsg(0x96+i, 0x46, 0x42); - - // PAD 8 Beatjump leds - midi.sendShortMsg(0x96+i, 0x70, pairColorsOff[0]); - midi.sendShortMsg(0x96+i, 0x71, pairColorsOff[1]); - midi.sendShortMsg(0x96+i, 0x72, pairColorsOff[2]); - midi.sendShortMsg(0x96+i, 0x73, pairColorsOff[3]); - midi.sendShortMsg(0x96+i, 0x74, pairColorsOff[4]); - midi.sendShortMsg(0x96+i, 0x75, pairColorsOff[5]); - midi.sendShortMsg(0x96+i, 0x76, pairColorsOff[6]); - midi.sendShortMsg(0x96+i, 0x77, pairColorsOff[7]); - // PAD 8 shift - midi.sendShortMsg(0x96+i, 0x78, pairColorsOff[0]); - midi.sendShortMsg(0x96+i, 0x79, pairColorsOff[1]); - midi.sendShortMsg(0x96+i, 0x7A, pairColorsOff[2]); - midi.sendShortMsg(0x96+i, 0x7B, pairColorsOff[3]); - midi.sendShortMsg(0x96+i, 0x7C, pairColorsOff[4]); - midi.sendShortMsg(0x96+i, 0x7D, pairColorsOff[5]); - midi.sendShortMsg(0x96+i, 0x7E, pairColorsOff[6]); - midi.sendShortMsg(0x96+i, 0x7F, pairColorsOff[7]); - // Light up FX quick effect chain selector buttons - midi.sendShortMsg(0x96+i, 0x64, 0x30); - midi.sendShortMsg(0x96+i, 0x65, 0x30); - } - - DJCi500.tempoTimer = engine.beginTimer(250, DJCi500.tempoLEDs); - - // FX buttons, light them to signal the current deck 1 and 2 as active - midi.sendShortMsg(0x90, 0x14, 0x7F); - midi.sendShortMsg(0x90, 0x15, 0x7F); - - // Create the deck objects - DJCi500.deckA = new DJCi500.Deck([1, 3], 1); - DJCi500.deckB = new DJCi500.Deck([2, 4], 2); - DJCi500.deckA.setCurrentDeck("[Channel1]"); - DJCi500.deckB.setCurrentDeck("[Channel2]"); - - // Update the fx rack selection - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); - - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel1]]", 0, 0); - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel2]]", 0, 0); + DJCi500.AutoHotcueColors = true; + + // Take care of the status of the crossfader status + DJCi500.crossfaderEnabled = true; + DJCi500.xFaderScratch = false; + + // Setup Vinyl buttons LED(one for each deck). + midi.sendShortMsg(0x91, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + midi.sendShortMsg(0x92, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + + //Turn On Browser button LED + midi.sendShortMsg(0x90, 0x05, 0x10); + + // Connect the VUMeters + engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + + // Deck VU meters peak indicators + engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel2]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel3]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel4]", "peak_indicator", DJCi500.vuMeterPeakDeck); + + // Connect number leds + engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); + + // Connect Master VU meter + engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); + engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); + + engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + + // Connect the FX selection leds + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + + engine.makeConnection("[QuickEffectRack1_[Channel1]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel2]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel3]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel4]]", "enabled", DJCi500.fxEnabledIndicator); + + // Connect the slicer beats + DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); + //var controlsToFunctions = {'beat_active': 'DJCi500.slicerBeatActive'}; + //script.bindConnections('[Channel1]', controlsToFunctions, true); + + // Ask the controller to send all current knob/slider values over MIDI, which will update + // the corresponding GUI controls in MIXXX. + midi.sendShortMsg(0xB0, 0x7F, 0x7F); + + // Turn on lights: + for (var i = 0; i < 2; i++) { + // PAD 5 Key and tempo range controls + midi.sendShortMsg(0x96+i, 0x40, 0x12); + midi.sendShortMsg(0x96+i, 0x41, 0x12); + midi.sendShortMsg(0x96+i, 0x42, 0x40); + midi.sendShortMsg(0x96+i, 0x43, 0x40); + midi.sendShortMsg(0x96+i, 0x44, 0x40); + midi.sendShortMsg(0x96+i, 0x45, 0x02); + midi.sendShortMsg(0x96+i, 0x46, 0x42); + + // PAD 8 Beatjump leds + midi.sendShortMsg(0x96+i, 0x70, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x71, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x72, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x73, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x74, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x75, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x76, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x77, pairColorsOff[7]); + // PAD 8 shift + midi.sendShortMsg(0x96+i, 0x78, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x79, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x7A, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x7B, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x7C, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x7D, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x7E, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x7F, pairColorsOff[7]); + // Light up FX quick effect chain selector buttons + midi.sendShortMsg(0x96+i, 0x64, 0x30); + midi.sendShortMsg(0x96+i, 0x65, 0x30); + } + + DJCi500.tempoTimer = engine.beginTimer(250, DJCi500.tempoLEDs); + + // FX buttons, light them to signal the current deck 1 and 2 as active + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x15, 0x7F); + + // Create the deck objects + DJCi500.deckA = new DJCi500.Deck([1, 3], 1); + DJCi500.deckB = new DJCi500.Deck([2, 4], 2); + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.deckB.setCurrentDeck("[Channel2]"); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel1]]", 0, 0); + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel2]]", 0, 0); }; // Crossfader control, set the curve DJCi500.crossfaderSetCurve = function(channel, control, value, _status, _group) { - switch(value) { - case 0x00: - // Mix - script.crossfaderCurve(0,0,127); - DJCi500.xFaderScratch = false; - break; - case 0x7F: - // Scratch - script.crossfaderCurve(127,0,127); - DJCi500.xFaderScratch = true; - break; - } + switch(value) { + case 0x00: + // Mix + script.crossfaderCurve(0,0,127); + DJCi500.xFaderScratch = false; + break; + case 0x7F: + // Scratch + script.crossfaderCurve(127,0,127); + DJCi500.xFaderScratch = true; + break; + } } // Crossfader enable or disable DJCi500.crossfaderEnable = function(channel, control, value, _status, _group) { - if(value) { - DJCi500.crossfaderEnabled = true; - } else { - DJCi500.crossfaderEnabled = false; - engine.setValue("[Master]", "crossfader", 0); // Set the crossfader in the middle - } + if(value) { + DJCi500.crossfaderEnabled = true; + } else { + DJCi500.crossfaderEnabled = false; + engine.setValue("[Master]", "crossfader", 0); // Set the crossfader in the middle + } } // Crossfader function DJCi500.crossfader = function(channel, control, value, status, group) { - if (DJCi500.crossfaderEnabled) { - // Eventine's crossfader scratch mode - if (DJCi500.xFaderScratch) { - var result = 0; - if (value <= 0) { - result = -1; - } - else if (value >= 127) { - result = 1; - } - else { - result = Math.tan((value-64)*Math.PI/2/63)/32; - } - engine.setValue(group, "crossfader", result); - } - else { - engine.setValue(group, "crossfader", (value/64)-1); + if (DJCi500.crossfaderEnabled) { + // Eventine's crossfader scratch mode + if (DJCi500.xFaderScratch) { + var result = 0; + if (value <= 0) { + result = -1; + } + else if (value >= 127) { + result = 1; + } + else { + result = Math.tan((value-64)*Math.PI/2/63)/32; + } + engine.setValue(group, "crossfader", result); + } + else { + engine.setValue(group, "crossfader", (value/64)-1); + } } - } } // Browser button. We move it to a custom JS function to avoid having to focus the Mixxx window for it to respond DJCi500.moveLibrary = function(channel, control, value, status, group) { - if (value > 0x3F) { - if (DJCi500.browserOffFocusMode) { - engine.setValue('[Playlist]', 'SelectTrackKnob', -1); - } else { - engine.setValue('[Library]', 'MoveUp', 1); - } - } else { - if (DJCi500.browserOffFocusMode) { - engine.setValue('[Playlist]', 'SelectTrackKnob', 1); + if (value > 0x3F) { + if (DJCi500.browserOffFocusMode) { + engine.setValue('[Playlist]', 'SelectTrackKnob', -1); + } else { + engine.setValue('[Library]', 'MoveUp', 1); + } } else { - engine.setValue('[Library]', 'MoveDown', 1); + if (DJCi500.browserOffFocusMode) { + engine.setValue('[Playlist]', 'SelectTrackKnob', 1); + } else { + engine.setValue('[Library]', 'MoveDown', 1); + } } - } } DJCi500.spinback_button = function(channel, control, value, status, group) { var deck = script.deckFromGroup(group); - engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly + engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly } // Update the Tempo and phase sync leds DJCi500.tempoLEDs = function () { - // Current active decks - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - - // Tempo: - var tempo1 = engine.getValue(deckA, "bpm"); - var tempo2 = engine.getValue(deckB, "bpm"); - var diff = tempo1 - tempo2; - - //Check double tempo: - var doubleTempo = 0; - if (diff > 0){ - if ((tempo1 / tempo2) > 1.5) { - doubleTempo = 1; - diff = tempo1 / 2 - tempo2; - } - } else { - if ((tempo2 / tempo1) > 1.5) { - doubleTempo = 1; - diff = tempo1 - tempo2 / 2; - } - } - - if (diff < -0.25) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1E, 0x0); - midi.sendShortMsg(0x91, 0x1F, 0x7F); - midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1F, 0x0); - midi.sendShortMsg(0x92, 0x1E, 0x7F); - midi.sendShortMsg(0x92, 0x2C, 0x0); - - //clear beatalign leds - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - else if ( diff > 0.25) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1F, 0x0); - midi.sendShortMsg(0x91, 0x1E, 0x7F); - midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1E, 0x0); - midi.sendShortMsg(0x92, 0x1F, 0x7F); - midi.sendShortMsg(0x92, 0x2C, 0x0); - - //clear beatalign leds - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - else { - //Deck1 - midi.sendShortMsg(0x91, 0x1E, 0x0); - midi.sendShortMsg(0x91, 0x1F, 0x0); - midi.sendShortMsg(0x91, 0x2C, 0x7F); - //Deck2 - midi.sendShortMsg(0x92, 0x1E, 0x0); - midi.sendShortMsg(0x92, 0x1F, 0x0); - midi.sendShortMsg(0x92, 0x2C, 0x7F); - - //Do beat alignement only if the tracks are already on Tempo - // and only if they are playing - if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")){ - - - var beat1 = engine.getValue(deckA, "beat_distance"); - var beat2 = engine.getValue(deckB, "beat_distance"); - if (doubleTempo){ - if (tempo1 > tempo2){ - if (beat2 > 0.5){ - beat2 -= 0.5; - } - beat2 *= 2; + // Current active decks + var deckA = DJCi500.deckA.currentDeck; + var deckB = DJCi500.deckB.currentDeck; + + // Tempo: + var tempo1 = engine.getValue(deckA, "bpm"); + var tempo2 = engine.getValue(deckB, "bpm"); + var diff = tempo1 - tempo2; + + //Check double tempo: + var doubleTempo = 0; + if (diff > 0){ + if ((tempo1 / tempo2) > 1.5) { + doubleTempo = 1; + diff = tempo1 / 2 - tempo2; } - else{ //tempo2 >(=) tempo1 - if (beat1 > 0.5){ - beat1 -= 0.5; - } - beat1 *= 2; + } else { + if ((tempo2 / tempo1) > 1.5) { + doubleTempo = 1; + diff = tempo1 - tempo2 / 2; } - } - diff = beat1 - beat2; - if (diff < 0){ - diff = 1+diff; - } - if ((diff < 0.02) || (diff > 1-0.02)) - { + } + + if (diff < -0.25) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x1E, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds //Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); //Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x7F); - } - else if ( diff < 0.5) - { + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + else if ( diff > 0.25) + { //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x7F); - midi.sendShortMsg(0x91, 0x2D, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x1E, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); //Deck2 - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x1C, 0x7F); - midi.sendShortMsg(0x91, 0x2D, 0x0); - } - else { + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x1C, 0x7F); midi.sendShortMsg(0x91, 0x2D, 0x0); //Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x7F); + midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x2D, 0x0); - } - }//if playing - else { - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); } - }//else tempo + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x2C, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x2C, 0x7F); + + //Do beat alignement only if the tracks are already on Tempo + // and only if they are playing + if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")){ + + + var beat1 = engine.getValue(deckA, "beat_distance"); + var beat2 = engine.getValue(deckB, "beat_distance"); + if (doubleTempo){ + if (tempo1 > tempo2){ + if (beat2 > 0.5){ + beat2 -= 0.5; + } + beat2 *= 2; + } + else{ //tempo2 >(=) tempo1 + if (beat1 > 0.5){ + beat1 -= 0.5; + } + beat1 *= 2; + } + } + diff = beat1 - beat2; + if (diff < 0){ + diff = 1+diff; + } + if ((diff < 0.02) || (diff > 1-0.02)) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x7F); + } + else if ( diff < 0.5) + { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + } + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x7F); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//if playing + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//else tempo }; // After a channel change, make sure we read the current status DJCi500.updateDeckStatus = function(group) { - var playing = engine.getValue(group, "play_indicator"); - var volume = script.absoluteLinInverse(engine.getValue(group, "vu_meter"), 0.0, 1.0, 0, 127); - - // Update the vinyl button - var vinylState = false; - var deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; - var channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; - if (channel === 1) { - vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; - } else { - vinylState = DJCi500.deckB.vinylButtonState[deckIndex]; - } - midi.sendShortMsg(0x90 + channel, 0x03, (vinylState) ? 0x7F : 0x00); - midi.sendShortMsg(0xB0 + channel, 0x40, volume); - midi.sendShortMsg(0x90 + channel, 0x30, playing ? 0x7F : 0x00); - - // Update the fx rack selection - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); - - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_" + group + "]", 0, 0); - - // Slicer - switch(group) { - case "[Channel1]": - DJCi500.slicerBeat1.disconnect(); - DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat1.trigger(); - break; - case "[Channel2]": - DJCi500.slicerBeat2.disconnect(); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2.trigger(); - break; - case "[Channel3]": - DJCi500.slicerBeat1.disconnect(); - DJCi500.slicerBeat1 = engine.makeConnection('[Channel3]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat1.trigger(); - break; - case "[Channel4]": - DJCi500.slicerBeat2.disconnect(); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel4]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2.trigger(); - break; - }; + var playing = engine.getValue(group, "play_indicator"); + var volume = script.absoluteLinInverse(engine.getValue(group, "vu_meter"), 0.0, 1.0, 0, 127); + + // Update the vinyl button + var vinylState = false; + var deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; + var channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; + if (channel === 1) { + vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; + } else { + vinylState = DJCi500.deckB.vinylButtonState[deckIndex]; + } + midi.sendShortMsg(0x90 + channel, 0x03, (vinylState) ? 0x7F : 0x00); + midi.sendShortMsg(0xB0 + channel, 0x40, volume); + midi.sendShortMsg(0x90 + channel, 0x30, playing ? 0x7F : 0x00); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_" + group + "]", 0, 0); + + // Slicer + switch(group) { + case "[Channel1]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel2]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + case "[Channel3]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection('[Channel3]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel4]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection('[Channel4]', 'beat_active', DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + }; } // This is where we choose the channel using the FX buttons and light them // up correctly DJCi500.deckSelector = function(channel, control, value, status, group) { - if (value === 0x7F) { - var deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number - switch (deckChosen) { - case 1: - DJCi500.deckA.setCurrentDeck("[Channel1]"); - DJCi500.updateDeckStatus("[Channel1]"); - midi.sendShortMsg(0x90, 0x14, 0x7F); - midi.sendShortMsg(0x90, 0x16, 0x00); - break; - case 2: - DJCi500.deckB.setCurrentDeck("[Channel2]"); - DJCi500.updateDeckStatus("[Channel2]"); - midi.sendShortMsg(0x90, 0x15, 0x7F); - midi.sendShortMsg(0x90, 0x17, 0x00); - break; - case 3: - DJCi500.deckA.setCurrentDeck("[Channel3]"); - DJCi500.updateDeckStatus("[Channel3]"); - midi.sendShortMsg(0x90, 0x14, 0x00); - midi.sendShortMsg(0x90, 0x16, 0x7F); - break; - case 4: - DJCi500.deckB.setCurrentDeck("[Channel4]"); - DJCi500.updateDeckStatus("[Channel4]"); - midi.sendShortMsg(0x90, 0x15, 0x00); - midi.sendShortMsg(0x90, 0x17, 0x7F); - break; + if (value === 0x7F) { + var deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number + switch (deckChosen) { + case 1: + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.updateDeckStatus("[Channel1]"); + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x16, 0x00); + break; + case 2: + DJCi500.deckB.setCurrentDeck("[Channel2]"); + DJCi500.updateDeckStatus("[Channel2]"); + midi.sendShortMsg(0x90, 0x15, 0x7F); + midi.sendShortMsg(0x90, 0x17, 0x00); + break; + case 3: + DJCi500.deckA.setCurrentDeck("[Channel3]"); + DJCi500.updateDeckStatus("[Channel3]"); + midi.sendShortMsg(0x90, 0x14, 0x00); + midi.sendShortMsg(0x90, 0x16, 0x7F); + break; + case 4: + DJCi500.deckB.setCurrentDeck("[Channel4]"); + DJCi500.updateDeckStatus("[Channel4]"); + midi.sendShortMsg(0x90, 0x15, 0x00); + midi.sendShortMsg(0x90, 0x17, 0x7F); + break; + }; }; - }; }; DJCi500.updateEffectStatus = function(midiChannel, channel) { - let status = false; - for (var i = 1; i <= 3; i++) { - status = status || engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", "enabled"); - } - return status; - // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); + let status = false; + for (var i = 1; i <= 3; i++) { + status = status || engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", "enabled"); + } + return status; + // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); } /////////////////////////////////////////////////////////////// // SLICER // /////////////////////////////////////////////////////////////// DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { - var index = control - 0x20, - deck = script.deckFromGroup(deckData.currentDeck) - 1, - domain = DJCi500.selectedSlicerDomain[deck], - beatsToJump = 0, - passedTime = engine.getValue(group, "beat_distance"), - loopEnabled = engine.getValue(group, "loop_enabled"); - - if (value) { - DJCi500.slicerButton[deck] = index; - //Maybe I need to update this (seems sometimes it does not work.) - //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); - beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); - beatsToJump -= passedTime; - - //activate the one-shot timer for the slip end. - if (!DJCi500.slicerTimer[deck]){ - DJCi500.slicerTimer[deck] = true; - var timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; - - //quality of life fix for not-precise hands or beatgrid - // also good fix for really small timer_ms values. - if ( (passedTime >= 0.8) && - //this is because while looping doing this thing on beat 8 break the flow. - ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1)) ) { - timer_ms += 60.0/engine.getValue(group, "bpm")*1000; - } - - engine.beginTimer( timer_ms, - //"DJCi500.slicerTimerCallback("+group+")", true); - function() { - //need to do this otherwise loop does not work on beat 8 because of slip. - if ((engine.getValue(group, "loop_enabled") === true)){ - //on the wiki it says it returns an integer, but I tested and instead seems a Real value: - // But it does not work cuz the value does not relate to beat. they are samples. - //var endLoop = engine.getValue(group, "loop_end_position"); - engine.setValue(group, "reloop_toggle", true); //false - engine.setValue(group, "slip_enabled", false); - //Aleatory behavior, probably because the slip does not always have completed before "returning" - //so I need to introduce a timer waiting the slip function to be completely resolved - engine.beginTimer( 2, function () { - var bpm_file = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"); - engine.setValue(group, "reloop_toggle", true);}, - true); - } - else { - engine.setValue(group, "slip_enabled", false); - } - DJCi500.slicerTimer[deck] = false; - DJCi500.slicerButton[deck] = -1;}, - true); - } + var index = control - 0x20, + deck = script.deckFromGroup(deckData.currentDeck) - 1, + domain = DJCi500.selectedSlicerDomain[deck], + beatsToJump = 0, + passedTime = engine.getValue(group, "beat_distance"), + loopEnabled = engine.getValue(group, "loop_enabled"); - engine.setValue(group, "slip_enabled", true); + if (value) { + DJCi500.slicerButton[deck] = index; + //Maybe I need to update this (seems sometimes it does not work.) + //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); + beatsToJump -= passedTime; + + //activate the one-shot timer for the slip end. + if (!DJCi500.slicerTimer[deck]){ + DJCi500.slicerTimer[deck] = true; + var timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; + + //quality of life fix for not-precise hands or beatgrid + // also good fix for really small timer_ms values. + if ( (passedTime >= 0.8) && + //this is because while looping doing this thing on beat 8 break the flow. + ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1)) ) { + timer_ms += 60.0/engine.getValue(group, "bpm")*1000; + } - //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping - // also there is no "lopp_deactivate" and loop_activate false does not work. - if (loopEnabled) { - engine.setValue(group, "reloop_toggle", true); - } - engine.setValue(group, "beatjump", beatsToJump); - //This sadly does not work. - //engine.setValue(group, "loop_move", -beatsToJump); - if (loopEnabled){ - engine.setValue(group, "reloop_toggle", true); - } - midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); - } //if value + engine.beginTimer( timer_ms, + //"DJCi500.slicerTimerCallback("+group+")", true); + function() { + //need to do this otherwise loop does not work on beat 8 because of slip. + if ((engine.getValue(group, "loop_enabled") === true)){ + //on the wiki it says it returns an integer, but I tested and instead seems a Real value: + // But it does not work cuz the value does not relate to beat. they are samples. + //var endLoop = engine.getValue(group, "loop_end_position"); + engine.setValue(group, "reloop_toggle", true); //false + engine.setValue(group, "slip_enabled", false); + //Aleatory behavior, probably because the slip does not always have completed before "returning" + //so I need to introduce a timer waiting the slip function to be completely resolved + engine.beginTimer( 2, function () { + var bpm_file = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"); + engine.setValue(group, "reloop_toggle", true);}, + true); + } + else { + engine.setValue(group, "slip_enabled", false); + } + DJCi500.slicerTimer[deck] = false; + DJCi500.slicerButton[deck] = -1;}, + true); + } + + engine.setValue(group, "slip_enabled", true); + + //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping + // also there is no "lopp_deactivate" and loop_activate false does not work. + if (loopEnabled) { + engine.setValue(group, "reloop_toggle", true); + } + engine.setValue(group, "beatjump", beatsToJump); + //This sadly does not work. + //engine.setValue(group, "loop_move", -beatsToJump); + if (loopEnabled){ + engine.setValue(group, "reloop_toggle", true); + } + midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); + } //if value }; //this below is connected to beat_active DJCi500.slicerBeatActive = function(value, group, control) { - // This slicer implementation will work for constant beatgrids only! - var deck = script.deckFromGroup(deckData.currentDeck) - 1; - var channel = deck % 2; - - print("***** SLICER ACTIVE VALUE: " + DJCi500.slicerActive[deck]); - print("***** SLICER: deck " + deck + " channel " + channel); - - var bpm = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"), - slicerPosInSection = 0, - ledBeatState = false, - domain = DJCi500.selectedSlicerDomain[deck]; - - //this works. - if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { - return; - } - - DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); - - if (DJCi500.slicerActive[deck]){ - slicerPosInSection = Math.floor((DJCi500.slicerBeatsPassed[deck] % domain) / (domain / 8)); - // PAD Led control: - if (DJCi500.slicerButton[deck] !== slicerPosInSection) { - for (var i = 0; i < 8; i++) { - active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; - midi.sendShortMsg((0x96+channel), 0x20+i, active); - } + // This slicer implementation will work for constant beatgrids only! + var deck = script.deckFromGroup(deckData.currentDeck) - 1; + var channel = deck % 2; + + print("***** SLICER ACTIVE VALUE: " + DJCi500.slicerActive[deck]); + print("***** SLICER: deck " + deck + " channel " + channel); + + var bpm = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"), + slicerPosInSection = 0, + ledBeatState = false, + domain = DJCi500.selectedSlicerDomain[deck]; + + //this works. + if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { + return; + } + + DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + + if (DJCi500.slicerActive[deck]){ + slicerPosInSection = Math.floor((DJCi500.slicerBeatsPassed[deck] % domain) / (domain / 8)); + // PAD Led control: + if (DJCi500.slicerButton[deck] !== slicerPosInSection) { + for (var i = 0; i < 8; i++) { + active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; + midi.sendShortMsg((0x96+channel), 0x20+i, active); + } + } else { + midi.sendShortMsg((0x96+channel), 0x20+DJCi500.slicerButton[deck], 0x62); + } } else { - midi.sendShortMsg((0x96+channel), 0x20+DJCi500.slicerButton[deck], 0x62); + DJCi500.slicerAlreadyJumped[deck] = false; + DJCi500.slicerPreviousBeatsPassed[deck] = 0; } - } else { - DJCi500.slicerAlreadyJumped[deck] = false; - DJCi500.slicerPreviousBeatsPassed[deck] = 0; - } }; DJCi500.shutdown = function() { - //cleanup - midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off - midi.sendShortMsg(0xB0, 0x7F, 0x7E); + //cleanup + midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off + midi.sendShortMsg(0xB0, 0x7F, 0x7E); }; From de93cf0142961c4e4f73d5fa17b9b0d0b8cd6f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Tue, 11 Feb 2025 09:56:13 +0100 Subject: [PATCH 27/40] Fix pre-commit --- .../Hercules-DJControl-Inpulse-500-script.js | 3096 ++++++++--------- .../Hercules_DJControl_Inpulse_500.midi.xml | 2 +- 2 files changed, 1538 insertions(+), 1560 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index b055a2c5672d..a518cd063730 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -1,1559 +1,1537 @@ -// DJControl_Inpulse_500_script.js -// -// *************************************************************************** -// * Mixxx mapping script file for the Hercules DJControl Inpulse 500. -// * Authors: Ev3nt1ne, DJ Phatso, resetreboot -// * contributions by Kerrick Staley, Bentheshrubber, ThatOneRuffian -// -// Version 1.6c: (August 2023) resetreboot -// * Requires Mixxx >= 2.3.4 -// * Volume meters follow correctly the selected channel -// * Use the full 14 bits for knobs for more precission -// * Add effects to the PAD 7 mode -// * Create decks for four channel mode -// * Change the behavior of the FX buttons, use them as Channel selector, using the LEDs -// as indicators of current channel. -// -// -// * When enabling multichannel, ensure: -// - Beat matching guide follows correctly the selected channels -// -// * Move the sampler buttons to the Deck component as well as the new effect buttons -// * Made the filter knob have a function with filter, effect and filter + effect -// * Use the Hotcue component for hotcues -// * Use components and add for the rest of the controls: -// - Play -// - Cue -// - Sync -// - Volume fader -// - EQs -// - PFL -// - Pad Selectors -// - Loop PADs -// - Roll PADs -// - Beat jump PADs -// - Tone key PADs -// - Slicer -// - Loop pot -// - In and Out loop -// - Load button -// - Vinyl -// - Slip -// - Quant -// - Pitch fader -// - Jog wheels (Using the new JogWheelBasic component! -// - Also probably fixed the shift behavior not working properly -// -// * Added option so the browser knob can behave with out of focus window -// -// * Version 1.5c (Summer 2023) -// * Forum: https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 -// * Wiki: https://mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 -// -// Version 1.0c: -// * Hot Cue: implementation of the Color API (Work in progress) -// - Assigned color directly to pad (XML) -// * Added DECK LED number - On when playing -// * Moved Beatjump to Pad mode 3 (Slicer) -// * Set different color for upper (Sampler 1-4) and lower (Sampler 5-8) sampler pads -// -// Version 1.0 - Based upon Inpulse 300 v1.2 (official) -// -// TO DO: -// * Browser knob has a ton of colors to do things! -// * Vinyl + SHIFT led should reflect brake status -// * Quant + SHIFT led should reflect key lock status -// * Add beat jump + SHIFT jumps -// -// **************************************************************************** -var DJCi500 = {}; - -/////////////////////////////////////////////////////////////// -// USER OPTIONS // -/////////////////////////////////////////////////////////////// - -// If you are spinning your set list and you have your Mixxx window out -// of focus and you want to be able to use the browser knob to traverse -// the current crate or playlist, set to true. Especially useful to spin -// when using Twitch, VRChat or Second Life -DJCi500.browserOffFocusMode = false; - -// Set initial state for vinyl mode button -DJCi500.initialVinylMode = true; - -// Colors -DJCi500.PadColorMapper = new ColorMapper({ - 0xFF0000: 0x60, - 0xFFFF00: 0x7C, - 0x00FF00: 0x1C, - 0x00FFFF: 0x1F, - 0x0000FF: 0x03, - 0xFF00FF: 0x42, - 0xFF88FF: 0x63, - 0xFFFFFF: 0x7F, - 0x000088: 0x02, - 0x008800: 0x10, - 0x008888: 0x12, - 0x228800: 0x30, - 0x880000: 0x40, - 0x882200: 0x4C, - 0x888800: 0x50, - 0x888888: 0x52, - 0x88FF00: 0x5C, - 0xFF8800: 0x74, -}); - -// Constants -DJCi500.EFFECT_ONLY_MODE = 1; -DJCi500.FILTER_AND_EFFECT_MODE = 2; - -// For key shift pads and beat jump pads -const pairColorsOn = [0x1F, 0x1F, 0x03, 0x03, 0x74, 0x74, 0x60, 0x60]; -const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; - -/////////////////////////////////////////////////////////////// -// SLICER // -/////////////////////////////////////////////////////////////// -DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; // Length of the Slicer domain -//PioneerDDJSX.slicerDomains = [8, 16, 32, 64]; - -// slicer storage: -DJCi500.slicerBeatsPassed = [0, 0, 0, 0]; -DJCi500.slicerPreviousBeatsPassed = [0, 0, 0, 0]; -DJCi500.slicerTimer = [false, false, false, false]; -DJCi500.slicerActive = [false, false, false, false]; -DJCi500.slicerAlreadyJumped = [false, false, false, false]; -DJCi500.slicerButton = [-1, -1, -1, -1]; -DJCi500.slicerModes = { - 'contSlice': 0, - 'loopSlice': 1 -}; -DJCi500.activeSlicerMode = [ - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice, - DJCi500.slicerModes.contSlice -]; -DJCi500.slicerLoopBeat8 = [0, 0, 0, 0]; -/////////////////////// - -// Master VU Meter callbacks -DJCi500.vuMeterUpdateMaster = function(value, _group, control) { - // Reserve the red led for peak indicator, this will in turn, make - // the display more similar (I hope) to what Mixxx VU shows - value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); - var control = (control === "vu_meter_left") ? 0x40 : 0x41; - midi.sendShortMsg(0xB0, control, value); -}; - -DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { - if (value) { - midi.sendShortMsg(0x90, 0x0A, 0x7F); - } else { - midi.sendShortMsg(0x90, 0x0A, 0x00); - } -}; - -DJCi500.vuMeterPeakRightMaster = function(value, group, control, status) { - if (value) { - midi.sendShortMsg(0x90, 0x0F, 0x7F); - } else { - midi.sendShortMsg(0x90, 0x0F, 0x00); - } -}; - -// Deck VU Meter callbacks -DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { - // Reserve the red led for peak indicator, this will in turn, make - // the display more similar (I hope) to what Mixxx VU shows - value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); - if (DJCi500.deckA.currentDeck === group) { - midi.sendShortMsg(0xB1, 0x40, value); - } else if (DJCi500.deckB.currentDeck === group) { - midi.sendShortMsg(0xB2, 0x40, value); - } -}; - -DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { - var channel = 0x00; - if (DJCi500.deckA.currentDeck === group) { - channel = 0x91; - } else if (DJCi500.deckB.currentDeck === group) { - channel = 0x92; - } - - if (channel > 0x00) { - if (value) { - midi.sendShortMsg(channel, 0x39, 0x7F); - } else { - midi.sendShortMsg(channel, 0x39, 0x00); - } - } -}; - -DJCi500.numberIndicator = function(value, group, _control, _status) { - if (DJCi500.deckA.currentDeck === group) { - midi.sendShortMsg(0x91, 0x30, value); - } else if (DJCi500.deckB.currentDeck === group) { - midi.sendShortMsg(0x92, 0x30, value); - } -} - -DJCi500.fxSelIndicator = function(_value, group, _control, _status) { - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - var active = false; - - if (group === "[EffectRack1_EffectUnit1]") { - active = engine.getValue(group, 'group_' + deckA + '_enable'); - if (active) { - midi.sendShortMsg(0x96, 0x63, 0x74); - } else { - midi.sendShortMsg(0x96, 0x63, 0x00); - } - active = engine.getValue(group, 'group_' + deckB + '_enable'); - if (active) { - midi.sendShortMsg(0x97, 0x63, 0x74); - } else { - midi.sendShortMsg(0x97, 0x63, 0x00); - } - } else if (group === "[EffectRack1_EffectUnit2]") { - active = engine.getValue(group, 'group_' + deckA + '_enable'); - if (active) { - midi.sendShortMsg(0x96, 0x67, 0x74); - } else { - midi.sendShortMsg(0x96, 0x67, 0x00); - } - active = engine.getValue(group, 'group_' + deckB + '_enable'); - if (active) { - midi.sendShortMsg(0x97, 0x67, 0x74); - } else { - midi.sendShortMsg(0x97, 0x67, 0x00); - } - } -} - -DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - var active = engine.getValue(group, 'enabled'); - - if (group == "[QuickEffectRack1_" + deckA + "]") { - midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60) - } else if (group == "[QuickEffectRack1_" + deckB + "]") { - midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60) - } -} - -DJCi500.Deck = function (deckNumbers, midiChannel) { - components.Deck.call(this, deckNumbers); - // Allow components to access deck variables - var deckData = this; - - // For loop and looprolls - var fractions = ['0.125', '0.25', '0.5', '1', '2', '4', '8', '16']; - var shiftFractions = ['0.03125', '0.0625', '32', '64', '128', '256', '512', '512']; - - // For beatjumps - var jumpValues = ['1', '1', '2', '2', '4', '4', '8', '8']; - var jumpValuesShift = ['16', '16', '32', '32', '64', '64', '128', '128']; - - // Brake status for this deck - this.slowPauseSetState = [false, false, false, false]; - - // Vinyl button state - this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; - - // Pitch ranges and status - this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; // Select pitch range - this.pitchRangeId = 0; // id of the array, one for each deck - - // Effect section components - this.effectEnabled = false; - - // Make sure the shift button remaps the shift actions - this.shiftButton = new components.Button({ - midi: [0x90 + midiChannel, 0x04], - input: function(_channel, _control, value, _status, _group) { - if (value === 0x7F) { - deckData.shift(); - } else { - deckData.unshift(); - } - - }, - }); - - this.loadButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0D], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.inKey = 'LoadSelectedTrack'; - }, - shift: function () { - this.inKey = 'eject'; - }, - }); - - // Transport section - // Play button, for some reason the group is not correct on this one? - this.playButton = new components.PlayButton({ - midi: [0x90 + midiChannel, 0x07], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.input = function (channel, control, value, status, group) { - if (value === 0x7F) { - if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched - var deck = script.deckFromGroup(deckData.currentDeck); - if (deckData.slowPauseSetState[deck - 1]) { - engine.brake(deck, - 1,//((status & 0xF0) !=== 0x80 && value > 0), - 54); - } else { - script.toggleControl(deckData.currentDeck, "play"); - } - } else { - script.toggleControl(deckData.currentDeck, "play"); - } - } - }; - }, - shift: function () { - this.input = function (_channel, _control, _value, _status, group) { - engine.setValue(deckData.currentDeck, "play_stutter", true); - }; - }, - }); - - this.cueButton = new components.CueButton({ - midi: [0x90 + midiChannel, 0x06], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - shift: function () { - this.inKey = "start_play"; - }, - }); - - this.syncButton = new components.SyncButton({ - midi: [0x90 + midiChannel, 0x05], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - shift: function () { - this.inKey = "sync_key"; - }, - }); - - this.pflButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0C], - type: components.Button.prototype.types.toggle, - key: 'pfl', - }); - - // Top controls - // Vinyl button - this.vinylButton = new components.Button({ - midi: [0x90 + midiChannel, 0x03], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.input = function(channel, _control, value, status, group) { - if (value === 0x7F) { - var deck = script.deckFromGroup(deckData.currentDeck); - var new_status = !deckData.vinylButtonState[deck - 1]; - deckData.jogWheel.vinylMode = new_status; - deckData.jogWheelShift.vinylMode = new_status; - deckData.vinylButtonState[deck] = new_status; - var new_message = new_status ? 0x7F : 0x00; - midi.sendShortMsg(this.midi[0], 0x03, new_message); - } - }; - }, - shift: function () { - this.input = function (channel, control, value, status, group) { - if (value === 0x7F){ - var deck = script.deckFromGroup(deckData.currentDeck); - deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; - - } - }; - } - }); - - // SLIP mode button - this.slipButton = new components.Button({ - midi: [0x90 + midiChannel, 0x01], - type: components.Button.prototype.types.toggle, - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - key: 'slip_enabled', - }); - - // Quant button - this.quantButton = new components.Button({ - midi: [0x90 + midiChannel, 0x02], - type: components.Button.prototype.types.toggle, - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'quantize', - unshift: function () { - this.inKey = 'quantize'; - }, - shift: function () { - this.inKey = 'keylock'; - }, - }); - - // Knobs - this.volume = new components.Pot({ - midi: [0xB0 + midiChannel, 0x00], - inKey: 'volume', - }); - - this.eqKnob = []; - for (var k = 1; k <= 3; k++) { - this.eqKnob[k] = new components.Pot({ - midi: [0xB0 + midiChannel, 0x01 + k], - group: '[EqualizerRack1_' + this.currentDeck + '_Effect1]', - inKey: 'parameter' + k, - }); - } - - this.gainKnob = new components.Pot({ - midi: [0xB0 + midiChannel, 0x05], - key: 'pregain', - }); - - // Pitch-tempo fader - this.pitchFader = new components.Pot({ - midi: [0xB0 + midiChannel, 0x08], - key: 'rate', - }); - - // Jog Wheel - // TODO: Handle with less repeat the shift key for this - this.jogWheel = new components.JogWheelBasic({ - midi: [0xB0 + midiChannel, 0x0A], - deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it - wheelResolution: 720, // how many ticks per revolution the jogwheel has - alpha: 5/6, - beta: (5/6)/128, - rpm: 33 + 1/3, - group: "[Channel"+midiChannel+"]", - inputWheel: function(_channel, _control, value, _status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - value = this.inValueScale(value); - if (engine.isScratching(deck)) { - engine.scratchTick(deck, value); - } else { - engine.setValue(group, 'jog', value); - } - }, - inputTouch: function(channel, control, value, status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { - engine.scratchEnable(deck, - this.wheelResolution, - this.rpm, - this.alpha, - this.beta); - } else { - engine.scratchDisable(deck); - } - }, - }); - - this.jogWheelShift = new components.JogWheelBasic({ - midi: [0xB3 + midiChannel, 0x0A], - deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it - wheelResolution: 720, // how many ticks per revolution the jogwheel has - alpha: 5/6, - beta: (5/6)/128, - rpm: 33 + 1/3, - group: "[Channel"+midiChannel+"]", - inputWheel: function(_channel, _control, value, _status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - value = this.inValueScale(value) * 4; - if (engine.isScratching(deck)) { - engine.scratchTick(deck, value); - } else { - engine.setValue(group, 'jog', value); - } - }, - inputTouch: function(channel, control, value, status, group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if (this.isPress(channel, control, value, status) && this.vinylMode) { - engine.scratchEnable(deck, - this.wheelResolution, - this.rpm, - this.alpha, - this.beta); - } else { - engine.scratchDisable(deck); - } - }, - }); - - // Loop controls - this.loopInButton = new components.Button({ - midi: [0x90 + midiChannel, 0x09], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'loop_enabled', // TODO: Check with loop_in? - unshift: function () { - this.inKey = 'loop_in'; - }, - shift: function () { - this.inKey = 'loop_in_goto'; - }, - }); - - this.loopOutButton = new components.Button({ - midi: [0x90 + midiChannel, 0x0A], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - outKey: 'loop_enabled', // TODO: Check with loop_in? - unshift: function () { - this.inKey = 'loop_out'; - }, - shift: function () { - this.inKey = 'loop_out_goto'; - }, - }); - - // Loop rotary encoder functions - // - // Push the rotary encoder - this.loopEncoderPush = new components.Button({ - midi: [0x90 + midiChannel, 0x2C], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - unshift: function () { - this.inKey = 'reloop_toggle'; - }, - shift: function () { - this.inKey = 'beatloop_4_activate'; - }, - }); - - // Loop encoder - this.loopEncoder = new components.Encoder({ - midi: [0xB0 + midiChannel, 0x0E], - shiftOffset: 3, - shiftControl: false, - shiftChannel: true, - sendShifted: true, - input: function (channel, control, value, status, group) { - // FIXME: Toggle for loop halve and double?? - var deckGroup = deckData.currentDeck; - if (value >= 0x40) { - engine.setValue(deckGroup, "loop_halve", true); - } else { - engine.setValue(deckGroup, "loop_double", true); - } - } - }); - - // We only check and attach for slicer mode, but we have all - // pad buttons here if we need something extra! - this.padSelectButtons = []; - for (var i = 1; i <= 8; i++) { - this.padSelectButtons[i] = new components.Button({ - midi: [0x90 + midiChannel, 0x0F + (i - 1)], - input: function(_channel, control, _value, _status, _group) { - var deck = script.deckFromGroup(deckData.currentDeck); - if (control === 0x11) { - DJCi500.slicerActive[deck - 1] = true; - } else { - DJCi500.slicerActive[deck - 1] = false; - } - }, - }); - } - - // Hotcue buttons (PAD Mode 1) - this.hotcueButtons = []; - for (var i = 1; i <= 8; i++) { - this.hotcueButtons[i] = new components.HotcueButton({ - midi: [0x95 + midiChannel, 0x00 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - colorMapper: DJCi500.PadColorMapper, - off: 0x00, - }); - }; - - // Loop buttons (PAD Mode 2) - this.loopButtons = []; - for (var i = 1; i <= 8; i++) { - this.loopButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x10 + (i - 1)], - number: i, - shiftControl: false, - sendShifted: false, - on: 0x5C, - off: 0x30, - outKey: 'beatloop_' + fractions[i - 1] + '_enabled', - inKey: 'beatloop_' + fractions[i - 1] + '_toggle', - }); - }; - - // A bit repeated code, but I want the leds to react accordingly - this.loopShiftButtons = []; - for (var i = 1; i <= 8; i++) { - this.loopShiftButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], - number: i, - shiftControl: false, - sendShifted: false, - on: 0x5C, - off: 0x30, - outKey: 'beatloop_' + shiftFractions[i - 1] + '_enabled', - inKey: 'beatloop_' + shiftFractions[i - 1] + '_toggle', - }); - }; - - // Slicer buttons (PAD Mode 3) - this.slicerButtons = []; - for (var i = 1; i <= 8; i++) { - this.slicerButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x20 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - input: function(channel, control, value, status, group) { - // This is kind of a hack... somehow this is not getting the group correctly! - DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); - }, - }); - }; - - // Sampler buttons (PAD Mode 4) - this.samplerButtons = []; - for (var i = 1; i <= 8; i++) { - this.samplerButtons[i] = new components.SamplerButton({ - midi: [0x95 + midiChannel, 0x30 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - loaded: 0x42, - empty: 0x00, - playing: 0x63, - looping: 0x74, - }); - }; - - // Pitch buttons (PAD Mode 5) - this.pitchDownTone = new components.Button({ - midi: [0x95 + midiChannel, 0x40], - on: pairColorsOn[0], - off: pairColorsOff[0], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_down", 1); - engine.setValue(group, "pitch_down", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchDownSemiTone = new components.Button({ - midi: [0x95 + midiChannel, 0x41], - on: pairColorsOn[1], - off: pairColorsOff[1], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_down", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchUpSemiTone = new components.Button({ - midi: [0x95 + midiChannel, 0x42], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_up", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchUpTone = new components.Button({ - midi: [0x95 + midiChannel, 0x43], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - engine.setValue(group, "pitch_up", 1); - engine.setValue(group, "pitch_up", 1); - midi.sendShortMsg(status, control, this.on); - } - else { - midi.sendShortMsg(status, control, this.off); - } - }, - }); - - this.pitchSliderIncrease = new components.Button({ - midi: [0x95 + midiChannel, 0x46], - on: 0x63, - off: 0x42, - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId++; - if (deckData.pitchRangeId > 6) - { - deckData.pitchRangeId = 6; - } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - this.pitchSliderDecrease = new components.Button({ - midi: [0x95 + midiChannel, 0x45], - on: pairColorsOn[3], - off: pairColorsOff[3], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId = deckData.pitchRangeId - 1; - if (deckData.pitchRangeId < 0) - { - deckData.pitchRangeId = 0; - } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - this.pitchSliderReset = new components.Button({ - midi: [0x95 + midiChannel, 0x44], - on: pairColorsOn[6], - off: pairColorsOff[6], - input: function (channel, control, value, status, group) { - if (value === 0x7F){ - deckData.pitchRangeId = 0; - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - }, - }); - - // Beatloop rolls buttons (PAD Mode 6) - this.rollButtons = []; - for (var i = 1; i <= 8; i++) { - this.rollButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x50 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - on: 0x1F, - off: 0x12, - key: 'beatlooproll_' + fractions[i - 1] + '_activate', - }); - }; - - // Effect buttons (PAD Mode 7) - this.effectButtons = []; - for (var i = 1; i <= 3; i++) { - // First top row effects buttons, just the effect, disable HPF/LPF knob - this.effectButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x60 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", - outKey: "enabled", - output: function (value, group, control) { - if (value) { - this.send(0x7F); - } else { - this.send(0x7C); - } - }, - unshift: function() { - // Normal effect button operation, toggling the effect assigned to it - this.input = function (channel, control, value, status, group) { - var fxNo = control - 0x5F; - var unit = channel - 0x95; - if (value === 0x7F){ - script.toggleControl(this.group, "enabled"); - } - }; - }, - shift: function () { - // Shift button will change the effect to the next in the list - this.input = function (channel, control, value, status, group) { - var fxNo = control - 0x67; - var unit = channel - 0x95; - if (value === 0x7F){ - engine.setValue(this.group, 'effect_selector', +1); - } - }; - } - }); - }; - - // Effect chain selectors - this.effectButtons[5] = new components.Button({ - midi: [0x95 + midiChannel, 0x64], - number: 5, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - on: 0x5C, - off: 0x30, - input: function (channel, control, value, status, group) { - if (value === 0x7F) { - engine.setValue(this.group, 'chain_preset_selector', -1); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - } - }); - - this.effectButtons[6] = new components.Button({ - midi: [0x95 + midiChannel, 0x65], - number: 6, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - on: 0x5C, - off: 0x30, - input: function (channel, control, value, status, group) { - if (value === 0x7F) { - engine.setValue(this.group, 'chain_preset_selector', 1); - midi.sendShortMsg(status, control, this.on); //17 -- 3B - } - else { - midi.sendShortMsg(status, control, this.off); //3B -- 33 - } - } - }); - - // Filter kill switch - this.effectButtons[7] = new components.Button({ - midi: [0x95 + midiChannel, 0x66], - number: 4, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - input: function (_channel, _control, value, _status, _group) { - if (value === 0x7F) { - script.toggleControl(this.group, 'enabled'); - } - } - }); - - // Set the current channel FX route with the two extra PADs - this.effectButtons[4] = new components.Button({ - midi: [0x95 + midiChannel, 0x63], - number: 4, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - group: "[EffectRack1_EffectUnit1]", - input: function (channel, _control, value, _status, group) { - if (value === 0x7F) { - var deckGroup = deckData.currentDeck; - script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); - } - } - }); - - this.effectButtons[8] = new components.Button({ - midi: [0x95 + midiChannel, 0x67], - number: 8, - shiftOffset: 8, - shiftControl: true, - sendShifted: false, - group: "[EffectRack1_EffectUnit2]", - input: function (_channel, _control, value, _status, _group) { - if (value === 0x7F) { - var deckGroup = deckData.currentDeck; - script.toggleControl(this.group, 'group_' + deckGroup + '_enable'); - } - } - }); - - // Filter knob is here since it is affected by effects pads - this.filterKnob = new components.Pot({ - midi: [0xB0 + midiChannel, 0x01], - number: midiChannel, - group: "[QuickEffectRack1_[Channel" + midiChannel + "]]", - input: function (channel, control, value, status, group) { - if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { - // Move the effects knobs - engine.setValue("[EffectRack1_EffectUnit" + this.number + "]", "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2 ); - } else { - // Move the filter knob - engine.setValue("[QuickEffectRack1_" + deckData.currentDeck + "]", "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); - } - }, - }); - - // Beat jump (PAD Mode 8) - this.beatJumpButtons = []; - for (var i = 1; i <= 8; i++) { - var movement = (i % 2 === 0) ? '_forward' : '_backward'; - var jmpVal = jumpValues[i - 1]; - var jmpValShft = jumpValuesShift[i - 1]; - this.beatJumpButtons[i] = new components.Button({ - midi: [0x95 + midiChannel, 0x70 + (i - 1)], - number: i, - shiftOffset: 8, - shiftControl: true, - sendShifted: true, - on: pairColorsOn[i - 1], - off: pairColorsOff[i - 1], - jump: 'beatjump_' + jmpVal + movement, - jumpShift: 'beatjump_' + jmpValShft + movement, - unshift: function () { - this.input = function(_channel, control, value, status, _group) { - if (value === 0x7F) { - engine.setValue(deckData.currentDeck, this.jump, true); - midi.sendShortMsg(status, control, this.on); - } else { - midi.sendShortMsg(status, control, this.off); - } - } - }, - shift: function () { - this.input = function(_channel, control, value, status, _group) { - if (value === 0x7F) { - engine.setValue(deckData.currentDeck, this.jumpShift, true); - midi.sendShortMsg(status, control, this.on); - } else { - midi.sendShortMsg(status, control, this.off); - } - } - }, - }); - }; - - // As per Mixxx wiki, set the group properties - this.reconnectComponents(function (c) { - if (c.group === undefined) { - c.group = this.currentDeck; - } - }); -} - -// Give the custom Deck all the methods of the generic deck -DJCi500.Deck.prototype = new components.Deck(); - -// INIT for the controller and decks -DJCi500.init = function() { - DJCi500.AutoHotcueColors = true; - - // Take care of the status of the crossfader status - DJCi500.crossfaderEnabled = true; - DJCi500.xFaderScratch = false; - - // Setup Vinyl buttons LED(one for each deck). - midi.sendShortMsg(0x91, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); - midi.sendShortMsg(0x92, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); - - //Turn On Browser button LED - midi.sendShortMsg(0x90, 0x05, 0x10); - - // Connect the VUMeters - engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); - - // Deck VU meters peak indicators - engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel2]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel3]", "peak_indicator", DJCi500.vuMeterPeakDeck); - engine.makeConnection("[Channel4]", "peak_indicator", DJCi500.vuMeterPeakDeck); - - // Connect number leds - engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); - engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); - - // Connect Master VU meter - engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); - engine.makeConnection("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); - engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); - engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); - - engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); - engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); - - // Connect the FX selection leds - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); - engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); - - engine.makeConnection("[QuickEffectRack1_[Channel1]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel2]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel3]]", "enabled", DJCi500.fxEnabledIndicator); - engine.makeConnection("[QuickEffectRack1_[Channel4]]", "enabled", DJCi500.fxEnabledIndicator); - - // Connect the slicer beats - DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); - //var controlsToFunctions = {'beat_active': 'DJCi500.slicerBeatActive'}; - //script.bindConnections('[Channel1]', controlsToFunctions, true); - - // Ask the controller to send all current knob/slider values over MIDI, which will update - // the corresponding GUI controls in MIXXX. - midi.sendShortMsg(0xB0, 0x7F, 0x7F); - - // Turn on lights: - for (var i = 0; i < 2; i++) { - // PAD 5 Key and tempo range controls - midi.sendShortMsg(0x96+i, 0x40, 0x12); - midi.sendShortMsg(0x96+i, 0x41, 0x12); - midi.sendShortMsg(0x96+i, 0x42, 0x40); - midi.sendShortMsg(0x96+i, 0x43, 0x40); - midi.sendShortMsg(0x96+i, 0x44, 0x40); - midi.sendShortMsg(0x96+i, 0x45, 0x02); - midi.sendShortMsg(0x96+i, 0x46, 0x42); - - // PAD 8 Beatjump leds - midi.sendShortMsg(0x96+i, 0x70, pairColorsOff[0]); - midi.sendShortMsg(0x96+i, 0x71, pairColorsOff[1]); - midi.sendShortMsg(0x96+i, 0x72, pairColorsOff[2]); - midi.sendShortMsg(0x96+i, 0x73, pairColorsOff[3]); - midi.sendShortMsg(0x96+i, 0x74, pairColorsOff[4]); - midi.sendShortMsg(0x96+i, 0x75, pairColorsOff[5]); - midi.sendShortMsg(0x96+i, 0x76, pairColorsOff[6]); - midi.sendShortMsg(0x96+i, 0x77, pairColorsOff[7]); - // PAD 8 shift - midi.sendShortMsg(0x96+i, 0x78, pairColorsOff[0]); - midi.sendShortMsg(0x96+i, 0x79, pairColorsOff[1]); - midi.sendShortMsg(0x96+i, 0x7A, pairColorsOff[2]); - midi.sendShortMsg(0x96+i, 0x7B, pairColorsOff[3]); - midi.sendShortMsg(0x96+i, 0x7C, pairColorsOff[4]); - midi.sendShortMsg(0x96+i, 0x7D, pairColorsOff[5]); - midi.sendShortMsg(0x96+i, 0x7E, pairColorsOff[6]); - midi.sendShortMsg(0x96+i, 0x7F, pairColorsOff[7]); - // Light up FX quick effect chain selector buttons - midi.sendShortMsg(0x96+i, 0x64, 0x30); - midi.sendShortMsg(0x96+i, 0x65, 0x30); - } - - DJCi500.tempoTimer = engine.beginTimer(250, DJCi500.tempoLEDs); - - // FX buttons, light them to signal the current deck 1 and 2 as active - midi.sendShortMsg(0x90, 0x14, 0x7F); - midi.sendShortMsg(0x90, 0x15, 0x7F); - - // Create the deck objects - DJCi500.deckA = new DJCi500.Deck([1, 3], 1); - DJCi500.deckB = new DJCi500.Deck([2, 4], 2); - DJCi500.deckA.setCurrentDeck("[Channel1]"); - DJCi500.deckB.setCurrentDeck("[Channel2]"); - - // Update the fx rack selection - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); - - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel1]]", 0, 0); - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel2]]", 0, 0); -}; - -// Crossfader control, set the curve -DJCi500.crossfaderSetCurve = function(channel, control, value, _status, _group) { - switch(value) { - case 0x00: - // Mix - script.crossfaderCurve(0,0,127); - DJCi500.xFaderScratch = false; - break; - case 0x7F: - // Scratch - script.crossfaderCurve(127,0,127); - DJCi500.xFaderScratch = true; - break; - } -} - -// Crossfader enable or disable -DJCi500.crossfaderEnable = function(channel, control, value, _status, _group) { - if(value) { - DJCi500.crossfaderEnabled = true; - } else { - DJCi500.crossfaderEnabled = false; - engine.setValue("[Master]", "crossfader", 0); // Set the crossfader in the middle - } -} - -// Crossfader function -DJCi500.crossfader = function(channel, control, value, status, group) { - if (DJCi500.crossfaderEnabled) { - // Eventine's crossfader scratch mode - if (DJCi500.xFaderScratch) { - var result = 0; - if (value <= 0) { - result = -1; - } - else if (value >= 127) { - result = 1; - } - else { - result = Math.tan((value-64)*Math.PI/2/63)/32; - } - engine.setValue(group, "crossfader", result); - } - else { - engine.setValue(group, "crossfader", (value/64)-1); - } - } -} - -// Browser button. We move it to a custom JS function to avoid having to focus the Mixxx window for it to respond -DJCi500.moveLibrary = function(channel, control, value, status, group) { - if (value > 0x3F) { - if (DJCi500.browserOffFocusMode) { - engine.setValue('[Playlist]', 'SelectTrackKnob', -1); - } else { - engine.setValue('[Library]', 'MoveUp', 1); - } - } else { - if (DJCi500.browserOffFocusMode) { - engine.setValue('[Playlist]', 'SelectTrackKnob', 1); - } else { - engine.setValue('[Library]', 'MoveDown', 1); - } - } -} - -DJCi500.spinback_button = function(channel, control, value, status, group) { - var deck = script.deckFromGroup(group); - engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly -} - -// Update the Tempo and phase sync leds -DJCi500.tempoLEDs = function () { - // Current active decks - var deckA = DJCi500.deckA.currentDeck; - var deckB = DJCi500.deckB.currentDeck; - - // Tempo: - var tempo1 = engine.getValue(deckA, "bpm"); - var tempo2 = engine.getValue(deckB, "bpm"); - var diff = tempo1 - tempo2; - - //Check double tempo: - var doubleTempo = 0; - if (diff > 0){ - if ((tempo1 / tempo2) > 1.5) { - doubleTempo = 1; - diff = tempo1 / 2 - tempo2; - } - } else { - if ((tempo2 / tempo1) > 1.5) { - doubleTempo = 1; - diff = tempo1 - tempo2 / 2; - } - } - - if (diff < -0.25) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1E, 0x0); - midi.sendShortMsg(0x91, 0x1F, 0x7F); - midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1F, 0x0); - midi.sendShortMsg(0x92, 0x1E, 0x7F); - midi.sendShortMsg(0x92, 0x2C, 0x0); - - //clear beatalign leds - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - else if ( diff > 0.25) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1F, 0x0); - midi.sendShortMsg(0x91, 0x1E, 0x7F); - midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1E, 0x0); - midi.sendShortMsg(0x92, 0x1F, 0x7F); - midi.sendShortMsg(0x92, 0x2C, 0x0); - - //clear beatalign leds - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - else { - //Deck1 - midi.sendShortMsg(0x91, 0x1E, 0x0); - midi.sendShortMsg(0x91, 0x1F, 0x0); - midi.sendShortMsg(0x91, 0x2C, 0x7F); - //Deck2 - midi.sendShortMsg(0x92, 0x1E, 0x0); - midi.sendShortMsg(0x92, 0x1F, 0x0); - midi.sendShortMsg(0x92, 0x2C, 0x7F); - - //Do beat alignement only if the tracks are already on Tempo - // and only if they are playing - if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")){ - - - var beat1 = engine.getValue(deckA, "beat_distance"); - var beat2 = engine.getValue(deckB, "beat_distance"); - if (doubleTempo){ - if (tempo1 > tempo2){ - if (beat2 > 0.5){ - beat2 -= 0.5; - } - beat2 *= 2; - } - else{ //tempo2 >(=) tempo1 - if (beat1 > 0.5){ - beat1 -= 0.5; - } - beat1 *= 2; - } - } - diff = beat1 - beat2; - if (diff < 0){ - diff = 1+diff; - } - if ((diff < 0.02) || (diff > 1-0.02)) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x7F); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x7F); - } - else if ( diff < 0.5) - { - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x7F); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x1C, 0x7F); - midi.sendShortMsg(0x91, 0x2D, 0x0); - } - else { - //Deck1 - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x1C, 0x7F); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x7F); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - }//if playing - else { - //Deck1 - midi.sendShortMsg(0x91, 0x1C, 0x0); - midi.sendShortMsg(0x91, 0x1D, 0x0); - midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 - midi.sendShortMsg(0x92, 0x1C, 0x0); - midi.sendShortMsg(0x92, 0x1D, 0x0); - midi.sendShortMsg(0x92, 0x2D, 0x0); - } - }//else tempo -}; - -// After a channel change, make sure we read the current status -DJCi500.updateDeckStatus = function(group) { - var playing = engine.getValue(group, "play_indicator"); - var volume = script.absoluteLinInverse(engine.getValue(group, "vu_meter"), 0.0, 1.0, 0, 127); - - // Update the vinyl button - var vinylState = false; - var deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; - var channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; - if (channel === 1) { - vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; - } else { - vinylState = DJCi500.deckB.vinylButtonState[deckIndex]; - } - midi.sendShortMsg(0x90 + channel, 0x03, (vinylState) ? 0x7F : 0x00); - midi.sendShortMsg(0xB0 + channel, 0x40, volume); - midi.sendShortMsg(0x90 + channel, 0x30, playing ? 0x7F : 0x00); - - // Update the fx rack selection - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); - DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); - - DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_" + group + "]", 0, 0); - - // Slicer - switch(group) { - case "[Channel1]": - DJCi500.slicerBeat1.disconnect(); - DJCi500.slicerBeat1 = engine.makeConnection('[Channel1]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat1.trigger(); - break; - case "[Channel2]": - DJCi500.slicerBeat2.disconnect(); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel2]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2.trigger(); - break; - case "[Channel3]": - DJCi500.slicerBeat1.disconnect(); - DJCi500.slicerBeat1 = engine.makeConnection('[Channel3]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat1.trigger(); - break; - case "[Channel4]": - DJCi500.slicerBeat2.disconnect(); - DJCi500.slicerBeat2 = engine.makeConnection('[Channel4]', 'beat_active', DJCi500.slicerBeatActive); - DJCi500.slicerBeat2.trigger(); - break; - }; -} - -// This is where we choose the channel using the FX buttons and light them -// up correctly -DJCi500.deckSelector = function(channel, control, value, status, group) { - if (value === 0x7F) { - var deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number - switch (deckChosen) { - case 1: - DJCi500.deckA.setCurrentDeck("[Channel1]"); - DJCi500.updateDeckStatus("[Channel1]"); - midi.sendShortMsg(0x90, 0x14, 0x7F); - midi.sendShortMsg(0x90, 0x16, 0x00); - break; - case 2: - DJCi500.deckB.setCurrentDeck("[Channel2]"); - DJCi500.updateDeckStatus("[Channel2]"); - midi.sendShortMsg(0x90, 0x15, 0x7F); - midi.sendShortMsg(0x90, 0x17, 0x00); - break; - case 3: - DJCi500.deckA.setCurrentDeck("[Channel3]"); - DJCi500.updateDeckStatus("[Channel3]"); - midi.sendShortMsg(0x90, 0x14, 0x00); - midi.sendShortMsg(0x90, 0x16, 0x7F); - break; - case 4: - DJCi500.deckB.setCurrentDeck("[Channel4]"); - DJCi500.updateDeckStatus("[Channel4]"); - midi.sendShortMsg(0x90, 0x15, 0x00); - midi.sendShortMsg(0x90, 0x17, 0x7F); - break; - }; - }; -}; - -DJCi500.updateEffectStatus = function(midiChannel, channel) { - let status = false; - for (var i = 1; i <= 3; i++) { - status = status || engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "_Effect" + i + "]", "enabled"); - } - return status; - // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); -} - -/////////////////////////////////////////////////////////////// -// SLICER // -/////////////////////////////////////////////////////////////// -DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { - var index = control - 0x20, - deck = script.deckFromGroup(deckData.currentDeck) - 1, - domain = DJCi500.selectedSlicerDomain[deck], - beatsToJump = 0, - passedTime = engine.getValue(group, "beat_distance"), - loopEnabled = engine.getValue(group, "loop_enabled"); - - if (value) { - DJCi500.slicerButton[deck] = index; - //Maybe I need to update this (seems sometimes it does not work.) - //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); - beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); - beatsToJump -= passedTime; - - //activate the one-shot timer for the slip end. - if (!DJCi500.slicerTimer[deck]){ - DJCi500.slicerTimer[deck] = true; - var timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; - - //quality of life fix for not-precise hands or beatgrid - // also good fix for really small timer_ms values. - if ( (passedTime >= 0.8) && - //this is because while looping doing this thing on beat 8 break the flow. - ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1)) ) { - timer_ms += 60.0/engine.getValue(group, "bpm")*1000; - } - - engine.beginTimer( timer_ms, - //"DJCi500.slicerTimerCallback("+group+")", true); - function() { - //need to do this otherwise loop does not work on beat 8 because of slip. - if ((engine.getValue(group, "loop_enabled") === true)){ - //on the wiki it says it returns an integer, but I tested and instead seems a Real value: - // But it does not work cuz the value does not relate to beat. they are samples. - //var endLoop = engine.getValue(group, "loop_end_position"); - engine.setValue(group, "reloop_toggle", true); //false - engine.setValue(group, "slip_enabled", false); - //Aleatory behavior, probably because the slip does not always have completed before "returning" - //so I need to introduce a timer waiting the slip function to be completely resolved - engine.beginTimer( 2, function () { - var bpm_file = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"); - engine.setValue(group, "reloop_toggle", true);}, - true); - } - else { - engine.setValue(group, "slip_enabled", false); - } - DJCi500.slicerTimer[deck] = false; - DJCi500.slicerButton[deck] = -1;}, - true); - } - - engine.setValue(group, "slip_enabled", true); - - //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping - // also there is no "lopp_deactivate" and loop_activate false does not work. - if (loopEnabled) { - engine.setValue(group, "reloop_toggle", true); - } - engine.setValue(group, "beatjump", beatsToJump); - //This sadly does not work. - //engine.setValue(group, "loop_move", -beatsToJump); - if (loopEnabled){ - engine.setValue(group, "reloop_toggle", true); - } - midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); - } //if value -}; - -//this below is connected to beat_active -DJCi500.slicerBeatActive = function(value, group, control) { - // This slicer implementation will work for constant beatgrids only! - var deck = script.deckFromGroup(deckData.currentDeck) - 1; - var channel = deck % 2; - - print("***** SLICER ACTIVE VALUE: " + DJCi500.slicerActive[deck]); - print("***** SLICER: deck " + deck + " channel " + channel); - - var bpm = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"), - slicerPosInSection = 0, - ledBeatState = false, - domain = DJCi500.selectedSlicerDomain[deck]; - - //this works. - if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { - return; - } - - DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); - - if (DJCi500.slicerActive[deck]){ - slicerPosInSection = Math.floor((DJCi500.slicerBeatsPassed[deck] % domain) / (domain / 8)); - // PAD Led control: - if (DJCi500.slicerButton[deck] !== slicerPosInSection) { - for (var i = 0; i < 8; i++) { - active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; - midi.sendShortMsg((0x96+channel), 0x20+i, active); - } - } else { - midi.sendShortMsg((0x96+channel), 0x20+DJCi500.slicerButton[deck], 0x62); - } - } else { - DJCi500.slicerAlreadyJumped[deck] = false; - DJCi500.slicerPreviousBeatsPassed[deck] = 0; - } -}; - -DJCi500.shutdown = function() { - //cleanup - midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off - midi.sendShortMsg(0xB0, 0x7F, 0x7E); -}; +// DJControl_Inpulse_500_script.js +// +// *************************************************************************** +// * Mixxx mapping script file for the Hercules DJControl Inpulse 500. +// * Authors: Ev3nt1ne, DJ Phatso, resetreboot +// * contributions by Kerrick Staley, Bentheshrubber, ThatOneRuffian +// +// Version 1.6c: (August 2023) resetreboot +// * Requires Mixxx >= 2.3.4 +// * Volume meters follow correctly the selected channel +// * Use the full 14 bits for knobs for more precission +// * Add effects to the PAD 7 mode +// * Create decks for four channel mode +// * Change the behavior of the FX buttons, use them as Channel selector, using the LEDs +// as indicators of current channel. +// +// +// * When enabling multichannel, ensure: +// - Beat matching guide follows correctly the selected channels +// +// * Move the sampler buttons to the Deck component as well as the new effect buttons +// * Made the filter knob have a function with filter, effect and filter + effect +// * Use the Hotcue component for hotcues +// * Use components and add for the rest of the controls: +// - Play +// - Cue +// - Sync +// - Volume fader +// - EQs +// - PFL +// - Pad Selectors +// - Loop PADs +// - Roll PADs +// - Beat jump PADs +// - Tone key PADs +// - Slicer +// - Loop pot +// - In and Out loop +// - Load button +// - Vinyl +// - Slip +// - Quant +// - Pitch fader +// - Jog wheels (Using the new JogWheelBasic component! +// - Also probably fixed the shift behavior not working properly +// +// * Added option so the browser knob can behave with out of focus window +// +// * Version 1.5c (Summer 2023) +// * Forum: https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 +// * Wiki: https://mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 +// +// Version 1.0c: +// * Hot Cue: implementation of the Color API (Work in progress) +// - Assigned color directly to pad (XML) +// * Added DECK LED number - On when playing +// * Moved Beatjump to Pad mode 3 (Slicer) +// * Set different color for upper (Sampler 1-4) and lower (Sampler 5-8) sampler pads +// +// Version 1.0 - Based upon Inpulse 300 v1.2 (official) +// +// TO DO: +// * Browser knob has a ton of colors to do things! +// * Vinyl + SHIFT led should reflect brake status +// * Quant + SHIFT led should reflect key lock status +// * Add beat jump + SHIFT jumps +// +// **************************************************************************** +const DJCi500 = {}; + +/////////////////////////////////////////////////////////////// +// USER OPTIONS // +/////////////////////////////////////////////////////////////// + +// If you are spinning your set list and you have your Mixxx window out +// of focus and you want to be able to use the browser knob to traverse +// the current crate or playlist, set to true. Especially useful to spin +// when using Twitch, VRChat or Second Life +DJCi500.browserOffFocusMode = false; + +// Set initial state for vinyl mode button +DJCi500.initialVinylMode = true; + +// Colors +DJCi500.PadColorMapper = new ColorMapper({ + 0xFF0000: 0x60, + 0xFFFF00: 0x7C, + 0x00FF00: 0x1C, + 0x00FFFF: 0x1F, + 0x0000FF: 0x03, + 0xFF00FF: 0x42, + 0xFF88FF: 0x63, + 0xFFFFFF: 0x7F, + 0x000088: 0x02, + 0x008800: 0x10, + 0x008888: 0x12, + 0x228800: 0x30, + 0x880000: 0x40, + 0x882200: 0x4C, + 0x888800: 0x50, + 0x888888: 0x52, + 0x88FF00: 0x5C, + 0xFF8800: 0x74, +}); + +// Constants +DJCi500.EFFECT_ONLY_MODE = 1; +DJCi500.FILTER_AND_EFFECT_MODE = 2; + +// For key shift pads and beat jump pads +const pairColorsOn = [0x1F, 0x1F, 0x03, 0x03, 0x74, 0x74, 0x60, 0x60]; +const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; + +/////////////////////////////////////////////////////////////// +// SLICER // +/////////////////////////////////////////////////////////////// +DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; // Length of the Slicer domain +//PioneerDDJSX.slicerDomains = [8, 16, 32, 64]; + +// slicer storage: +DJCi500.slicerBeatsPassed = [0, 0, 0, 0]; +DJCi500.slicerPreviousBeatsPassed = [0, 0, 0, 0]; +DJCi500.slicerTimer = [false, false, false, false]; +DJCi500.slicerActive = [false, false, false, false]; +DJCi500.slicerAlreadyJumped = [false, false, false, false]; +DJCi500.slicerButton = [-1, -1, -1, -1]; +DJCi500.slicerModes = { + "contSlice": 0, + "loopSlice": 1 +}; +DJCi500.activeSlicerMode = [ + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice, + DJCi500.slicerModes.contSlice +]; +DJCi500.slicerLoopBeat8 = [0, 0, 0, 0]; +/////////////////////// + +// Master VU Meter callbacks +DJCi500.vuMeterUpdateMaster = function(value, _group, control) { + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); + var control = (control === "vu_meter_left") ? 0x40 : 0x41; + midi.sendShortMsg(0xB0, control, value); +}; + +DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { + if (value) { + midi.sendShortMsg(0x90, 0x0A, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0A, 0x00); + } +}; + +DJCi500.vuMeterPeakRightMaster = function(value, group, control, status) { + if (value) { + midi.sendShortMsg(0x90, 0x0F, 0x7F); + } else { + midi.sendShortMsg(0x90, 0x0F, 0x00); + } +}; + +// Deck VU Meter callbacks +DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { + // Reserve the red led for peak indicator, this will in turn, make + // the display more similar (I hope) to what Mixxx VU shows + value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0xB1, 0x40, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0xB2, 0x40, value); + } +}; + +DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { + let channel = 0x00; + if (DJCi500.deckA.currentDeck === group) { + channel = 0x91; + } else if (DJCi500.deckB.currentDeck === group) { + channel = 0x92; + } + + if (channel > 0x00) { + if (value) { + midi.sendShortMsg(channel, 0x39, 0x7F); + } else { + midi.sendShortMsg(channel, 0x39, 0x00); + } + } +}; + +DJCi500.numberIndicator = function(value, group, _control, _status) { + if (DJCi500.deckA.currentDeck === group) { + midi.sendShortMsg(0x91, 0x30, value); + } else if (DJCi500.deckB.currentDeck === group) { + midi.sendShortMsg(0x92, 0x30, value); + } +}; + +DJCi500.fxSelIndicator = function(_value, group, _control, _status) { + const deckA = DJCi500.deckA.currentDeck; + const deckB = DJCi500.deckB.currentDeck; + let active = false; + + if (group === "[EffectRack1_EffectUnit1]") { + active = engine.getValue(group, `group_${ deckA }_enable`); + if (active) { + midi.sendShortMsg(0x96, 0x63, 0x74); + } else { + midi.sendShortMsg(0x96, 0x63, 0x00); + } + active = engine.getValue(group, `group_${ deckB }_enable`); + if (active) { + midi.sendShortMsg(0x97, 0x63, 0x74); + } else { + midi.sendShortMsg(0x97, 0x63, 0x00); + } + } else if (group === "[EffectRack1_EffectUnit2]") { + active = engine.getValue(group, `group_${ deckA }_enable`); + if (active) { + midi.sendShortMsg(0x96, 0x67, 0x74); + } else { + midi.sendShortMsg(0x96, 0x67, 0x00); + } + active = engine.getValue(group, `group_${ deckB }_enable`); + if (active) { + midi.sendShortMsg(0x97, 0x67, 0x74); + } else { + midi.sendShortMsg(0x97, 0x67, 0x00); + } + } +}; + +DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { + const deckA = DJCi500.deckA.currentDeck; + const deckB = DJCi500.deckB.currentDeck; + const active = engine.getValue(group, "enabled"); + + if (group == `[QuickEffectRack1_${ deckA }]`) { + midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60); + } else if (group == `[QuickEffectRack1_${ deckB }]`) { + midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60); + } +}; + +DJCi500.Deck = function(deckNumbers, midiChannel) { + components.Deck.call(this, deckNumbers); + // Allow components to access deck variables + const deckData = this; + + // For loop and looprolls + const fractions = ["0.125", "0.25", "0.5", "1", "2", "4", "8", "16"]; + const shiftFractions = ["0.03125", "0.0625", "32", "64", "128", "256", "512", "512"]; + + // For beatjumps + const jumpValues = ["1", "1", "2", "2", "4", "4", "8", "8"]; + const jumpValuesShift = ["16", "16", "32", "32", "64", "64", "128", "128"]; + + // Brake status for this deck + this.slowPauseSetState = [false, false, false, false]; + + // Vinyl button state + this.vinylButtonState = [DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode, DJCi500.initialVinylMode]; + + // Pitch ranges and status + this.pitchRanges = [0.08, 0.10, 0.15, 0.16, 0.24, 0.50, 0.90]; // Select pitch range + this.pitchRangeId = 0; // id of the array, one for each deck + + // Effect section components + this.effectEnabled = false; + + // Make sure the shift button remaps the shift actions + this.shiftButton = new components.Button({ + midi: [0x90 + midiChannel, 0x04], + input: function(_channel, _control, value, _status, _group) { + if (value === 0x7F) { + deckData.shift(); + } else { + deckData.unshift(); + } + + }, + }); + + this.loadButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0D], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function() { + this.inKey = "LoadSelectedTrack"; + }, + shift: function() { + this.inKey = "eject"; + }, + }); + + // Transport section + // Play button, for some reason the group is not correct on this one? + this.playButton = new components.PlayButton({ + midi: [0x90 + midiChannel, 0x07], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function() { + this.input = function(channel, control, value, status, group) { + if (value === 0x7F) { + if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched + const deck = script.deckFromGroup(deckData.currentDeck); + if (deckData.slowPauseSetState[deck - 1]) { + engine.brake(deck, + 1, //((status & 0xF0) !=== 0x80 && value > 0), + 54); + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } else { + script.toggleControl(deckData.currentDeck, "play"); + } + } + }; + }, + shift: function() { + this.input = function(_channel, _control, _value, _status, group) { + engine.setValue(deckData.currentDeck, "play_stutter", true); + }; + }, + }); + + this.cueButton = new components.CueButton({ + midi: [0x90 + midiChannel, 0x06], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function() { + this.inKey = "start_play"; + }, + }); + + this.syncButton = new components.SyncButton({ + midi: [0x90 + midiChannel, 0x05], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + shift: function() { + this.inKey = "sync_key"; + }, + }); + + this.pflButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0C], + type: components.Button.prototype.types.toggle, + key: "pfl", + }); + + // Top controls + // Vinyl button + this.vinylButton = new components.Button({ + midi: [0x90 + midiChannel, 0x03], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function() { + this.input = function(channel, _control, value, status, group) { + if (value === 0x7F) { + const deck = script.deckFromGroup(deckData.currentDeck); + const new_status = !deckData.vinylButtonState[deck - 1]; + deckData.jogWheel.vinylMode = new_status; + deckData.jogWheelShift.vinylMode = new_status; + deckData.vinylButtonState[deck] = new_status; + const new_message = new_status ? 0x7F : 0x00; + midi.sendShortMsg(this.midi[0], 0x03, new_message); + } + }; + }, + shift: function() { + this.input = function(channel, control, value, status, group) { + if (value === 0x7F) { + const deck = script.deckFromGroup(deckData.currentDeck); + deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; + + } + }; + } + }); + + // SLIP mode button + this.slipButton = new components.Button({ + midi: [0x90 + midiChannel, 0x01], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + key: "slip_enabled", + }); + + // Quant button + this.quantButton = new components.Button({ + midi: [0x90 + midiChannel, 0x02], + type: components.Button.prototype.types.toggle, + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: "quantize", + unshift: function() { + this.inKey = "quantize"; + }, + shift: function() { + this.inKey = "keylock"; + }, + }); + + // Knobs + this.volume = new components.Pot({ + midi: [0xB0 + midiChannel, 0x00], + inKey: "volume", + }); + + this.eqKnob = []; + for (let k = 1; k <= 3; k++) { + this.eqKnob[k] = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01 + k], + group: `[EqualizerRack1_${ this.currentDeck }_Effect1]`, + inKey: `parameter${ k}`, + }); + } + + this.gainKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x05], + key: "pregain", + }); + + // Pitch-tempo fader + this.pitchFader = new components.Pot({ + midi: [0xB0 + midiChannel, 0x08], + key: "rate", + }); + + // Jog Wheel + // TODO: Handle with less repeat the shift key for this + this.jogWheel = new components.JogWheelBasic({ + midi: [0xB0 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: `[Channel${midiChannel}]`, + inputWheel: function(_channel, _control, value, _status, group) { + const deck = script.deckFromGroup(deckData.currentDeck); + value = this.inValueScale(value); + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, "jog", value); + } + }, + inputTouch: function(channel, control, value, status, group) { + const deck = script.deckFromGroup(deckData.currentDeck); + if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + this.jogWheelShift = new components.JogWheelBasic({ + midi: [0xB3 + midiChannel, 0x0A], + deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // how many ticks per revolution the jogwheel has + alpha: 5/6, + beta: (5/6)/128, + rpm: 33 + 1/3, + group: `[Channel${midiChannel}]`, + inputWheel: function(_channel, _control, value, _status, group) { + const deck = script.deckFromGroup(deckData.currentDeck); + value = this.inValueScale(value) * 4; + if (engine.isScratching(deck)) { + engine.scratchTick(deck, value); + } else { + engine.setValue(group, "jog", value); + } + }, + inputTouch: function(channel, control, value, status, group) { + const deck = script.deckFromGroup(deckData.currentDeck); + if (this.isPress(channel, control, value, status) && this.vinylMode) { + engine.scratchEnable(deck, + this.wheelResolution, + this.rpm, + this.alpha, + this.beta); + } else { + engine.scratchDisable(deck); + } + }, + }); + + // Loop controls + this.loopInButton = new components.Button({ + midi: [0x90 + midiChannel, 0x09], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: "loop_enabled", // TODO: Check with loop_in? + unshift: function() { + this.inKey = "loop_in"; + }, + shift: function() { + this.inKey = "loop_in_goto"; + }, + }); + + this.loopOutButton = new components.Button({ + midi: [0x90 + midiChannel, 0x0A], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + outKey: "loop_enabled", // TODO: Check with loop_in? + unshift: function() { + this.inKey = "loop_out"; + }, + shift: function() { + this.inKey = "loop_out_goto"; + }, + }); + + // Loop rotary encoder functions + // + // Push the rotary encoder + this.loopEncoderPush = new components.Button({ + midi: [0x90 + midiChannel, 0x2C], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + unshift: function() { + this.inKey = "reloop_toggle"; + }, + shift: function() { + this.inKey = "beatloop_4_activate"; + }, + }); + + // Loop encoder + this.loopEncoder = new components.Encoder({ + midi: [0xB0 + midiChannel, 0x0E], + shiftOffset: 3, + shiftControl: false, + shiftChannel: true, + sendShifted: true, + input: function(channel, control, value, status, group) { + // FIXME: Toggle for loop halve and double?? + const deckGroup = deckData.currentDeck; + if (value >= 0x40) { + engine.setValue(deckGroup, "loop_halve", true); + } else { + engine.setValue(deckGroup, "loop_double", true); + } + } + }); + + // We only check and attach for slicer mode, but we have all + // pad buttons here if we need something extra! + this.padSelectButtons = []; + for (var i = 1; i <= 8; i++) { + this.padSelectButtons[i] = new components.Button({ + midi: [0x90 + midiChannel, 0x0F + (i - 1)], + input: function(_channel, control, _value, _status, _group) { + const deck = script.deckFromGroup(deckData.currentDeck); + if (control === 0x11) { + DJCi500.slicerActive[deck - 1] = true; + } else { + DJCi500.slicerActive[deck - 1] = false; + } + }, + }); + } + + // Hotcue buttons (PAD Mode 1) + this.hotcueButtons = []; + for (var i = 1; i <= 8; i++) { + this.hotcueButtons[i] = new components.HotcueButton({ + midi: [0x95 + midiChannel, 0x00 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + colorMapper: DJCi500.PadColorMapper, + off: 0x00, + }); + }; + + // Loop buttons (PAD Mode 2) + this.loopButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1)], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: `beatloop_${ fractions[i - 1] }_enabled`, + inKey: `beatloop_${ fractions[i - 1] }_toggle`, + }); + }; + + // A bit repeated code, but I want the leds to react accordingly + this.loopShiftButtons = []; + for (var i = 1; i <= 8; i++) { + this.loopShiftButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], + number: i, + shiftControl: false, + sendShifted: false, + on: 0x5C, + off: 0x30, + outKey: `beatloop_${ shiftFractions[i - 1] }_enabled`, + inKey: `beatloop_${ shiftFractions[i - 1] }_toggle`, + }); + }; + + // Slicer buttons (PAD Mode 3) + this.slicerButtons = []; + for (var i = 1; i <= 8; i++) { + this.slicerButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x20 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + input: function(channel, control, value, status, group) { + // This is kind of a hack... somehow this is not getting the group correctly! + DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); + }, + }); + }; + + // Sampler buttons (PAD Mode 4) + this.samplerButtons = []; + for (var i = 1; i <= 8; i++) { + this.samplerButtons[i] = new components.SamplerButton({ + midi: [0x95 + midiChannel, 0x30 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + loaded: 0x42, + empty: 0x00, + playing: 0x63, + looping: 0x74, + }); + }; + + // Pitch buttons (PAD Mode 5) + this.pitchDownTone = new components.Button({ + midi: [0x95 + midiChannel, 0x40], + on: pairColorsOn[0], + off: pairColorsOff[0], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(group, "pitch_down", 1); + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchDownSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x41], + on: pairColorsOn[1], + off: pairColorsOff[1], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(group, "pitch_down", 1); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchUpSemiTone = new components.Button({ + midi: [0x95 + midiChannel, 0x42], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchUpTone = new components.Button({ + midi: [0x95 + midiChannel, 0x43], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(group, "pitch_up", 1); + engine.setValue(group, "pitch_up", 1); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }, + }); + + this.pitchSliderIncrease = new components.Button({ + midi: [0x95 + midiChannel, 0x46], + on: 0x63, + off: 0x42, + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + deckData.pitchRangeId++; + if (deckData.pitchRangeId > 6) { + deckData.pitchRangeId = 6; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + this.pitchSliderDecrease = new components.Button({ + midi: [0x95 + midiChannel, 0x45], + on: pairColorsOn[3], + off: pairColorsOff[3], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + deckData.pitchRangeId = deckData.pitchRangeId - 1; + if (deckData.pitchRangeId < 0) { + deckData.pitchRangeId = 0; + } + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + this.pitchSliderReset = new components.Button({ + midi: [0x95 + midiChannel, 0x44], + on: pairColorsOn[6], + off: pairColorsOff[6], + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + deckData.pitchRangeId = 0; + engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + }, + }); + + // Beatloop rolls buttons (PAD Mode 6) + this.rollButtons = []; + for (var i = 1; i <= 8; i++) { + this.rollButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x50 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: 0x1F, + off: 0x12, + key: `beatlooproll_${ fractions[i - 1] }_activate`, + }); + }; + + // Effect buttons (PAD Mode 7) + this.effectButtons = []; + for (var i = 1; i <= 3; i++) { + // First top row effects buttons, just the effect, disable HPF/LPF knob + this.effectButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x60 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: `[EffectRack1_EffectUnit${ midiChannel }_Effect${ i }]`, + outKey: "enabled", + output: function(value, group, control) { + if (value) { + this.send(0x7F); + } else { + this.send(0x7C); + } + }, + unshift: function() { + // Normal effect button operation, toggling the effect assigned to it + this.input = function(channel, control, value, status, group) { + const fxNo = control - 0x5F; + const unit = channel - 0x95; + if (value === 0x7F) { + script.toggleControl(this.group, "enabled"); + } + }; + }, + shift: function() { + // Shift button will change the effect to the next in the list + this.input = function(channel, control, value, status, group) { + const fxNo = control - 0x67; + const unit = channel - 0x95; + if (value === 0x7F) { + engine.setValue(this.group, "effect_selector", +1); + } + }; + } + }); + }; + + // Effect chain selectors + this.effectButtons[5] = new components.Button({ + midi: [0x95 + midiChannel, 0x64], + number: 5, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + on: 0x5C, + off: 0x30, + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, "chain_preset_selector", -1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + } + }); + + this.effectButtons[6] = new components.Button({ + midi: [0x95 + midiChannel, 0x65], + number: 6, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + on: 0x5C, + off: 0x30, + input: function(channel, control, value, status, group) { + if (value === 0x7F) { + engine.setValue(this.group, "chain_preset_selector", 1); + midi.sendShortMsg(status, control, this.on); //17 -- 3B + } else { + midi.sendShortMsg(status, control, this.off); //3B -- 33 + } + } + }); + + // Filter kill switch + this.effectButtons[7] = new components.Button({ + midi: [0x95 + midiChannel, 0x66], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + input: function(_channel, _control, value, _status, _group) { + if (value === 0x7F) { + script.toggleControl(this.group, "enabled"); + } + } + }); + + // Set the current channel FX route with the two extra PADs + this.effectButtons[4] = new components.Button({ + midi: [0x95 + midiChannel, 0x63], + number: 4, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + group: "[EffectRack1_EffectUnit1]", + input: function(channel, _control, value, _status, group) { + if (value === 0x7F) { + const deckGroup = deckData.currentDeck; + script.toggleControl(this.group, `group_${ deckGroup }_enable`); + } + } + }); + + this.effectButtons[8] = new components.Button({ + midi: [0x95 + midiChannel, 0x67], + number: 8, + shiftOffset: 8, + shiftControl: true, + sendShifted: false, + group: "[EffectRack1_EffectUnit2]", + input: function(_channel, _control, value, _status, _group) { + if (value === 0x7F) { + const deckGroup = deckData.currentDeck; + script.toggleControl(this.group, `group_${ deckGroup }_enable`); + } + } + }); + + // Filter knob is here since it is affected by effects pads + this.filterKnob = new components.Pot({ + midi: [0xB0 + midiChannel, 0x01], + number: midiChannel, + group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + input: function(channel, control, value, status, group) { + if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { + // Move the effects knobs + engine.setValue(`[EffectRack1_EffectUnit${ this.number }]`, "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2); + } else { + // Move the filter knob + engine.setValue(`[QuickEffectRack1_${ deckData.currentDeck }]`, "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); + } + }, + }); + + // Beat jump (PAD Mode 8) + this.beatJumpButtons = []; + for (var i = 1; i <= 8; i++) { + const movement = (i % 2 === 0) ? "_forward" : "_backward"; + const jmpVal = jumpValues[i - 1]; + const jmpValShft = jumpValuesShift[i - 1]; + this.beatJumpButtons[i] = new components.Button({ + midi: [0x95 + midiChannel, 0x70 + (i - 1)], + number: i, + shiftOffset: 8, + shiftControl: true, + sendShifted: true, + on: pairColorsOn[i - 1], + off: pairColorsOff[i - 1], + jump: `beatjump_${ jmpVal }${movement}`, + jumpShift: `beatjump_${ jmpValShft }${movement}`, + unshift: function() { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jump, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }; + }, + shift: function() { + this.input = function(_channel, control, value, status, _group) { + if (value === 0x7F) { + engine.setValue(deckData.currentDeck, this.jumpShift, true); + midi.sendShortMsg(status, control, this.on); + } else { + midi.sendShortMsg(status, control, this.off); + } + }; + }, + }); + }; + + // As per Mixxx wiki, set the group properties + this.reconnectComponents(function(c) { + if (c.group === undefined) { + c.group = this.currentDeck; + } + }); +}; + +// Give the custom Deck all the methods of the generic deck +DJCi500.Deck.prototype = new components.Deck(); + +// INIT for the controller and decks +DJCi500.init = function() { + DJCi500.AutoHotcueColors = true; + + // Take care of the status of the crossfader status + DJCi500.crossfaderEnabled = true; + DJCi500.xFaderScratch = false; + + // Setup Vinyl buttons LED(one for each deck). + midi.sendShortMsg(0x91, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + midi.sendShortMsg(0x92, 0x03, DJCi500.initialVinylMode ? 0x7F : 0x00); + + //Turn On Browser button LED + midi.sendShortMsg(0x90, 0x05, 0x10); + + // Connect the VUMeters + engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + + // Deck VU meters peak indicators + engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel2]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel3]", "peak_indicator", DJCi500.vuMeterPeakDeck); + engine.makeConnection("[Channel4]", "peak_indicator", DJCi500.vuMeterPeakDeck); + + // Connect number leds + engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); + + // Connect Master VU meter + engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); + engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); + + engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); + engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + + // Connect the FX selection leds + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel2]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel3]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + engine.makeConnection("[EffectRack1_EffectUnit2]", "group_[Channel4]_enable", DJCi500.fxSelIndicator); + + engine.makeConnection("[QuickEffectRack1_[Channel1]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel2]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel3]]", "enabled", DJCi500.fxEnabledIndicator); + engine.makeConnection("[QuickEffectRack1_[Channel4]]", "enabled", DJCi500.fxEnabledIndicator); + + // Connect the slicer beats + DJCi500.slicerBeat1 = engine.makeConnection("[Channel1]", "beat_active", DJCi500.slicerBeatActive); + DJCi500.slicerBeat2 = engine.makeConnection("[Channel2]", "beat_active", DJCi500.slicerBeatActive); + //var controlsToFunctions = {'beat_active': 'DJCi500.slicerBeatActive'}; + //script.bindConnections('[Channel1]', controlsToFunctions, true); + + // Ask the controller to send all current knob/slider values over MIDI, which will update + // the corresponding GUI controls in MIXXX. + midi.sendShortMsg(0xB0, 0x7F, 0x7F); + + // Turn on lights: + for (let i = 0; i < 2; i++) { + // PAD 5 Key and tempo range controls + midi.sendShortMsg(0x96+i, 0x40, 0x12); + midi.sendShortMsg(0x96+i, 0x41, 0x12); + midi.sendShortMsg(0x96+i, 0x42, 0x40); + midi.sendShortMsg(0x96+i, 0x43, 0x40); + midi.sendShortMsg(0x96+i, 0x44, 0x40); + midi.sendShortMsg(0x96+i, 0x45, 0x02); + midi.sendShortMsg(0x96+i, 0x46, 0x42); + + // PAD 8 Beatjump leds + midi.sendShortMsg(0x96+i, 0x70, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x71, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x72, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x73, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x74, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x75, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x76, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x77, pairColorsOff[7]); + // PAD 8 shift + midi.sendShortMsg(0x96+i, 0x78, pairColorsOff[0]); + midi.sendShortMsg(0x96+i, 0x79, pairColorsOff[1]); + midi.sendShortMsg(0x96+i, 0x7A, pairColorsOff[2]); + midi.sendShortMsg(0x96+i, 0x7B, pairColorsOff[3]); + midi.sendShortMsg(0x96+i, 0x7C, pairColorsOff[4]); + midi.sendShortMsg(0x96+i, 0x7D, pairColorsOff[5]); + midi.sendShortMsg(0x96+i, 0x7E, pairColorsOff[6]); + midi.sendShortMsg(0x96+i, 0x7F, pairColorsOff[7]); + // Light up FX quick effect chain selector buttons + midi.sendShortMsg(0x96+i, 0x64, 0x30); + midi.sendShortMsg(0x96+i, 0x65, 0x30); + } + + DJCi500.tempoTimer = engine.beginTimer(250, DJCi500.tempoLEDs); + + // FX buttons, light them to signal the current deck 1 and 2 as active + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x15, 0x7F); + + // Create the deck objects + DJCi500.deckA = new DJCi500.Deck([1, 3], 1); + DJCi500.deckB = new DJCi500.Deck([2, 4], 2); + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.deckB.setCurrentDeck("[Channel2]"); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel1]]", 0, 0); + DJCi500.fxEnabledIndicator(0, "[QuickEffectRack1_[Channel2]]", 0, 0); +}; + +// Crossfader control, set the curve +DJCi500.crossfaderSetCurve = function(channel, control, value, _status, _group) { + switch (value) { + case 0x00: + // Mix + script.crossfaderCurve(0, 0, 127); + DJCi500.xFaderScratch = false; + break; + case 0x7F: + // Scratch + script.crossfaderCurve(127, 0, 127); + DJCi500.xFaderScratch = true; + break; + } +}; + +// Crossfader enable or disable +DJCi500.crossfaderEnable = function(channel, control, value, _status, _group) { + if (value) { + DJCi500.crossfaderEnabled = true; + } else { + DJCi500.crossfaderEnabled = false; + engine.setValue("[Master]", "crossfader", 0); // Set the crossfader in the middle + } +}; + +// Crossfader function +DJCi500.crossfader = function(channel, control, value, status, group) { + if (DJCi500.crossfaderEnabled) { + // Eventine's crossfader scratch mode + if (DJCi500.xFaderScratch) { + let result = 0; + if (value <= 0) { + result = -1; + } else if (value >= 127) { + result = 1; + } else { + result = Math.tan((value-64)*Math.PI/2/63)/32; + } + engine.setValue(group, "crossfader", result); + } else { + engine.setValue(group, "crossfader", (value/64)-1); + } + } +}; + +// Browser button. We move it to a custom JS function to avoid having to focus the Mixxx window for it to respond +DJCi500.moveLibrary = function(channel, control, value, status, group) { + if (value > 0x3F) { + if (DJCi500.browserOffFocusMode) { + engine.setValue("[Playlist]", "SelectTrackKnob", -1); + } else { + engine.setValue("[Library]", "MoveUp", 1); + } + } else { + if (DJCi500.browserOffFocusMode) { + engine.setValue("[Playlist]", "SelectTrackKnob", 1); + } else { + engine.setValue("[Library]", "MoveDown", 1); + } + } +}; + +DJCi500.spinback_button = function(channel, control, value, status, group) { + const deck = script.deckFromGroup(group); + engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly +}; + +// Update the Tempo and phase sync leds +DJCi500.tempoLEDs = function() { + // Current active decks + const deckA = DJCi500.deckA.currentDeck; + const deckB = DJCi500.deckB.currentDeck; + + // Tempo: + const tempo1 = engine.getValue(deckA, "bpm"); + const tempo2 = engine.getValue(deckB, "bpm"); + let diff = tempo1 - tempo2; + + //Check double tempo: + let doubleTempo = 0; + if (diff > 0) { + if ((tempo1 / tempo2) > 1.5) { + doubleTempo = 1; + diff = tempo1 / 2 - tempo2; + } + } else { + if ((tempo2 / tempo1) > 1.5) { + doubleTempo = 1; + diff = tempo1 - tempo2 / 2; + } + } + + if (diff < -0.25) { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x1E, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } else if (diff > 0.25) { + //Deck1 + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x1E, 0x7F); + midi.sendShortMsg(0x91, 0x2C, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x7F); + midi.sendShortMsg(0x92, 0x2C, 0x0); + + //clear beatalign leds + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } else { + //Deck1 + midi.sendShortMsg(0x91, 0x1E, 0x0); + midi.sendShortMsg(0x91, 0x1F, 0x0); + midi.sendShortMsg(0x91, 0x2C, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1E, 0x0); + midi.sendShortMsg(0x92, 0x1F, 0x0); + midi.sendShortMsg(0x92, 0x2C, 0x7F); + + //Do beat alignment only if the tracks are already on Tempo + // and only if they are playing + if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")) { + + + let beat1 = engine.getValue(deckA, "beat_distance"); + let beat2 = engine.getValue(deckB, "beat_distance"); + if (doubleTempo) { + if (tempo1 > tempo2) { + if (beat2 > 0.5) { + beat2 -= 0.5; + } + beat2 *= 2; + } else { //tempo2 >(=) tempo1 + if (beat1 > 0.5) { + beat1 -= 0.5; + } + beat1 *= 2; + } + } + diff = beat1 - beat2; + if (diff < 0) { + diff = 1+diff; + } + if ((diff < 0.02) || (diff > 1-0.02)) { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x7F); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x7F); + } else if (diff < 0.5) { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + } else { + //Deck1 + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x1C, 0x7F); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x7F); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//if playing + else { + //Deck1 + midi.sendShortMsg(0x91, 0x1C, 0x0); + midi.sendShortMsg(0x91, 0x1D, 0x0); + midi.sendShortMsg(0x91, 0x2D, 0x0); + //Deck2 + midi.sendShortMsg(0x92, 0x1C, 0x0); + midi.sendShortMsg(0x92, 0x1D, 0x0); + midi.sendShortMsg(0x92, 0x2D, 0x0); + } + }//else tempo +}; + +// After a channel change, make sure we read the current status +DJCi500.updateDeckStatus = function(group) { + const playing = engine.getValue(group, "play_indicator"); + const volume = script.absoluteLinInverse(engine.getValue(group, "vu_meter"), 0.0, 1.0, 0, 127); + + // Update the vinyl button + let vinylState = false; + const deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; + const channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; + if (channel === 1) { + vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; + } else { + vinylState = DJCi500.deckB.vinylButtonState[deckIndex]; + } + midi.sendShortMsg(0x90 + channel, 0x03, (vinylState) ? 0x7F : 0x00); + midi.sendShortMsg(0xB0 + channel, 0x40, volume); + midi.sendShortMsg(0x90 + channel, 0x30, playing ? 0x7F : 0x00); + + // Update the fx rack selection + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); + DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); + + DJCi500.fxEnabledIndicator(0, `[QuickEffectRack1_${ group }]`, 0, 0); + + // Slicer + switch (group) { + case "[Channel1]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection("[Channel1]", "beat_active", DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel2]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection("[Channel2]", "beat_active", DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + case "[Channel3]": + DJCi500.slicerBeat1.disconnect(); + DJCi500.slicerBeat1 = engine.makeConnection("[Channel3]", "beat_active", DJCi500.slicerBeatActive); + DJCi500.slicerBeat1.trigger(); + break; + case "[Channel4]": + DJCi500.slicerBeat2.disconnect(); + DJCi500.slicerBeat2 = engine.makeConnection("[Channel4]", "beat_active", DJCi500.slicerBeatActive); + DJCi500.slicerBeat2.trigger(); + break; + }; +}; + +// This is where we choose the channel using the FX buttons and light them +// up correctly +DJCi500.deckSelector = function(channel, control, value, status, group) { + if (value === 0x7F) { + const deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number + switch (deckChosen) { + case 1: + DJCi500.deckA.setCurrentDeck("[Channel1]"); + DJCi500.updateDeckStatus("[Channel1]"); + midi.sendShortMsg(0x90, 0x14, 0x7F); + midi.sendShortMsg(0x90, 0x16, 0x00); + break; + case 2: + DJCi500.deckB.setCurrentDeck("[Channel2]"); + DJCi500.updateDeckStatus("[Channel2]"); + midi.sendShortMsg(0x90, 0x15, 0x7F); + midi.sendShortMsg(0x90, 0x17, 0x00); + break; + case 3: + DJCi500.deckA.setCurrentDeck("[Channel3]"); + DJCi500.updateDeckStatus("[Channel3]"); + midi.sendShortMsg(0x90, 0x14, 0x00); + midi.sendShortMsg(0x90, 0x16, 0x7F); + break; + case 4: + DJCi500.deckB.setCurrentDeck("[Channel4]"); + DJCi500.updateDeckStatus("[Channel4]"); + midi.sendShortMsg(0x90, 0x15, 0x00); + midi.sendShortMsg(0x90, 0x17, 0x7F); + break; + }; + }; +}; + +DJCi500.updateEffectStatus = function(midiChannel, channel) { + let status = false; + for (let i = 1; i <= 3; i++) { + status = status || engine.getValue(`[EffectRack1_EffectUnit${ midiChannel }_Effect${ i }]`, "enabled"); + } + return status; + // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); +}; + +/////////////////////////////////////////////////////////////// +// SLICER // +/////////////////////////////////////////////////////////////// +DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { + let index = control - 0x20, + deck = script.deckFromGroup(deckData.currentDeck) - 1, + domain = DJCi500.selectedSlicerDomain[deck], + beatsToJump = 0, + passedTime = engine.getValue(group, "beat_distance"), + loopEnabled = engine.getValue(group, "loop_enabled"); + + if (value) { + DJCi500.slicerButton[deck] = index; + //Maybe I need to update this (seems sometimes it does not work.) + //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); + beatsToJump -= passedTime; + + //activate the one-shot timer for the slip end. + if (!DJCi500.slicerTimer[deck]) { + DJCi500.slicerTimer[deck] = true; + let timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; + + //quality of life fix for not-precise hands or beatgrid + // also good fix for really small timer_ms values. + if ((passedTime >= 0.8) && + //this is because while looping doing this thing on beat 8 break the flow. + ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1))) { + timer_ms += 60.0/engine.getValue(group, "bpm")*1000; + } + + engine.beginTimer(timer_ms, + //"DJCi500.slicerTimerCallback("+group+")", true); + function() { + //need to do this otherwise loop does not work on beat 8 because of slip. + if ((engine.getValue(group, "loop_enabled") === true)) { + //on the wiki it says it returns an integer, but I tested and instead seems a Real value: + // But it does not work cuz the value does not relate to beat. they are samples. + //var endLoop = engine.getValue(group, "loop_end_position"); + engine.setValue(group, "reloop_toggle", true); //false + engine.setValue(group, "slip_enabled", false); + //Aleatory behavior, probably because the slip does not always have completed before "returning" + //so I need to introduce a timer waiting the slip function to be completely resolved + engine.beginTimer(2, function() { + const bpm_file = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"); + engine.setValue(group, "reloop_toggle", true); + }, + true); + } else { + engine.setValue(group, "slip_enabled", false); + } + DJCi500.slicerTimer[deck] = false; + DJCi500.slicerButton[deck] = -1; + }, + true); + } + + engine.setValue(group, "slip_enabled", true); + + //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping + // also there is no "lopp_deactivate" and loop_activate false does not work. + if (loopEnabled) { + engine.setValue(group, "reloop_toggle", true); + } + engine.setValue(group, "beatjump", beatsToJump); + //This sadly does not work. + //engine.setValue(group, "loop_move", -beatsToJump); + if (loopEnabled) { + engine.setValue(group, "reloop_toggle", true); + } + midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); + } //if value +}; + +//this below is connected to beat_active +DJCi500.slicerBeatActive = function(value, group, control) { + // This slicer implementation will work for constant beatgrids only! + const deck = script.deckFromGroup(deckData.currentDeck) - 1; + const channel = deck % 2; + + print(`***** SLICER ACTIVE VALUE: ${ DJCi500.slicerActive[deck]}`); + print(`***** SLICER: deck ${ deck } channel ${ channel}`); + + let bpm = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"), + slicerPosInSection = 0, + ledBeatState = false, + domain = DJCi500.selectedSlicerDomain[deck]; + + //this works. + if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { + return; + } + + DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + + if (DJCi500.slicerActive[deck]) { + slicerPosInSection = Math.floor((DJCi500.slicerBeatsPassed[deck] % domain) / (domain / 8)); + // PAD Led control: + if (DJCi500.slicerButton[deck] !== slicerPosInSection) { + for (let i = 0; i < 8; i++) { + active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; + midi.sendShortMsg((0x96+channel), 0x20+i, active); + } + } else { + midi.sendShortMsg((0x96+channel), 0x20+DJCi500.slicerButton[deck], 0x62); + } + } else { + DJCi500.slicerAlreadyJumped[deck] = false; + DJCi500.slicerPreviousBeatsPassed[deck] = 0; + } +}; + +DJCi500.shutdown = function() { + //cleanup + midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off + midi.sendShortMsg(0xB0, 0x7F, 0x7E); +}; diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index 7bf3703a82bb..120756c6841e 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -2445,7 +2445,7 @@ - + [Channel2] From 62ebe56a89f595e50a11bd279e0fcea718127c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 17 Feb 2025 17:42:54 +0100 Subject: [PATCH 28/40] Apply suggestions from code review Co-authored-by: Lukas Waslowski --- .../Hercules-DJControl-Inpulse-500-script.js | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index a518cd063730..e372466ec49a 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -205,26 +205,26 @@ DJCi500.fxSelIndicator = function(_value, group, _control, _status) { let active = false; if (group === "[EffectRack1_EffectUnit1]") { - active = engine.getValue(group, `group_${ deckA }_enable`); + active = engine.getValue(group, `group_${deckA}_enable`); if (active) { midi.sendShortMsg(0x96, 0x63, 0x74); } else { midi.sendShortMsg(0x96, 0x63, 0x00); } - active = engine.getValue(group, `group_${ deckB }_enable`); + active = engine.getValue(group, `group_${deckB}_enable`); if (active) { midi.sendShortMsg(0x97, 0x63, 0x74); } else { midi.sendShortMsg(0x97, 0x63, 0x00); } } else if (group === "[EffectRack1_EffectUnit2]") { - active = engine.getValue(group, `group_${ deckA }_enable`); + active = engine.getValue(group, `group_${deckA}_enable`); if (active) { midi.sendShortMsg(0x96, 0x67, 0x74); } else { midi.sendShortMsg(0x96, 0x67, 0x00); } - active = engine.getValue(group, `group_${ deckB }_enable`); + active = engine.getValue(group, `group_${deckB}_enable`); if (active) { midi.sendShortMsg(0x97, 0x67, 0x74); } else { @@ -238,9 +238,9 @@ DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { const deckB = DJCi500.deckB.currentDeck; const active = engine.getValue(group, "enabled"); - if (group == `[QuickEffectRack1_${ deckA }]`) { + if (group == `[QuickEffectRack1_${deckA}]`) { midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60); - } else if (group == `[QuickEffectRack1_${ deckB }]`) { + } else if (group == `[QuickEffectRack1_${deckB}]`) { midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60); } }; @@ -307,7 +307,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftChannel: true, sendShifted: true, unshift: function() { - this.input = function(channel, control, value, status, group) { + this.input = function(_channel, _control, value, _status, _group) { if (value === 0x7F) { if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched const deck = script.deckFromGroup(deckData.currentDeck); @@ -368,7 +368,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftChannel: true, sendShifted: true, unshift: function() { - this.input = function(channel, _control, value, status, group) { + this.input = function(_channel, _control, value, _status, _group) { if (value === 0x7F) { const deck = script.deckFromGroup(deckData.currentDeck); const new_status = !deckData.vinylButtonState[deck - 1]; @@ -429,8 +429,8 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { for (let k = 1; k <= 3; k++) { this.eqKnob[k] = new components.Pot({ midi: [0xB0 + midiChannel, 0x01 + k], - group: `[EqualizerRack1_${ this.currentDeck }_Effect1]`, - inKey: `parameter${ k}`, + group: `[EqualizerRack1_${this.currentDeck}_Effect1]`, + inKey: `parameter${k}`, }); } @@ -464,7 +464,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { engine.setValue(group, "jog", value); } }, - inputTouch: function(channel, control, value, status, group) { + inputTouch: function(_channel, _control, value, _status, _group) { const deck = script.deckFromGroup(deckData.currentDeck); if ((value === 0x7F) && deckData.vinylButtonState[deck - 1]) { engine.scratchEnable(deck, @@ -495,7 +495,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { engine.setValue(group, "jog", value); } }, - inputTouch: function(channel, control, value, status, group) { + inputTouch: function(channel, control, value, status, _group) { const deck = script.deckFromGroup(deckData.currentDeck); if (this.isPress(channel, control, value, status) && this.vinylMode) { engine.scratchEnable(deck, @@ -616,8 +616,8 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { sendShifted: false, on: 0x5C, off: 0x30, - outKey: `beatloop_${ fractions[i - 1] }_enabled`, - inKey: `beatloop_${ fractions[i - 1] }_toggle`, + outKey: `beatloop_${fractions[i - 1]}_enabled`, + inKey: `beatloop_${fractions[i - 1]}_toggle`, }); }; @@ -631,8 +631,8 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { sendShifted: false, on: 0x5C, off: 0x30, - outKey: `beatloop_${ shiftFractions[i - 1] }_enabled`, - inKey: `beatloop_${ shiftFractions[i - 1] }_toggle`, + outKey: `beatloop_${shiftFractions[i - 1]}_enabled`, + inKey: `beatloop_${shiftFractions[i - 1]}_toggle`, }); }; @@ -789,7 +789,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { sendShifted: true, on: 0x1F, off: 0x12, - key: `beatlooproll_${ fractions[i - 1] }_activate`, + key: `beatlooproll_${fractions[i - 1]}_activate`, }); }; @@ -803,7 +803,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftOffset: 8, shiftControl: true, sendShifted: true, - group: `[EffectRack1_EffectUnit${ midiChannel }_Effect${ i }]`, + group: `[EffectRack1_EffectUnit${midiChannel}_Effect${i}]`, outKey: "enabled", output: function(value, group, control) { if (value) { @@ -842,7 +842,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftOffset: 8, shiftControl: true, sendShifted: true, - group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + group: `[QuickEffectRack1_[Channel${midiChannel}]]`, on: 0x5C, off: 0x30, input: function(channel, control, value, status, group) { @@ -861,7 +861,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftOffset: 8, shiftControl: true, sendShifted: true, - group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + group: `[QuickEffectRack1_[Channel${midiChannel}]]`, on: 0x5C, off: 0x30, input: function(channel, control, value, status, group) { @@ -881,7 +881,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftOffset: 8, shiftControl: true, sendShifted: true, - group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + group: `[QuickEffectRack1_[Channel${midiChannel}]]`, input: function(_channel, _control, value, _status, _group) { if (value === 0x7F) { script.toggleControl(this.group, "enabled"); @@ -900,7 +900,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { input: function(channel, _control, value, _status, group) { if (value === 0x7F) { const deckGroup = deckData.currentDeck; - script.toggleControl(this.group, `group_${ deckGroup }_enable`); + script.toggleControl(this.group, `group_${deckGroup}_enable`); } } }); @@ -915,7 +915,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { input: function(_channel, _control, value, _status, _group) { if (value === 0x7F) { const deckGroup = deckData.currentDeck; - script.toggleControl(this.group, `group_${ deckGroup }_enable`); + script.toggleControl(this.group, `group_${deckGroup}_enable`); } } }); @@ -924,14 +924,14 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { this.filterKnob = new components.Pot({ midi: [0xB0 + midiChannel, 0x01], number: midiChannel, - group: `[QuickEffectRack1_[Channel${ midiChannel }]]`, + group: `[QuickEffectRack1_[Channel${midiChannel}]]`, input: function(channel, control, value, status, group) { if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { // Move the effects knobs - engine.setValue(`[EffectRack1_EffectUnit${ this.number }]`, "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2); + engine.setValue(`[EffectRack1_EffectUnit${this.number}]`, "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2); } else { // Move the filter knob - engine.setValue(`[QuickEffectRack1_${ deckData.currentDeck }]`, "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); + engine.setValue(`[QuickEffectRack1_${deckData.currentDeck}]`, "super1", script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127)); } }, }); @@ -950,8 +950,8 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { sendShifted: true, on: pairColorsOn[i - 1], off: pairColorsOff[i - 1], - jump: `beatjump_${ jmpVal }${movement}`, - jumpShift: `beatjump_${ jmpValShft }${movement}`, + jump: `beatjump_${jmpVal}${movement}`, + jumpShift: `beatjump_${jmpValShft}${movement}`, unshift: function() { this.input = function(_channel, control, value, status, _group) { if (value === 0x7F) { @@ -1344,7 +1344,7 @@ DJCi500.updateDeckStatus = function(group) { DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit1]", 0, 0); DJCi500.fxSelIndicator(0, "[EffectRack1_EffectUnit2]", 0, 0); - DJCi500.fxEnabledIndicator(0, `[QuickEffectRack1_${ group }]`, 0, 0); + DJCi500.fxEnabledIndicator(0, `[QuickEffectRack1_${group}]`, 0, 0); // Slicer switch (group) { @@ -1408,7 +1408,7 @@ DJCi500.deckSelector = function(channel, control, value, status, group) { DJCi500.updateEffectStatus = function(midiChannel, channel) { let status = false; for (let i = 1; i <= 3; i++) { - status = status || engine.getValue(`[EffectRack1_EffectUnit${ midiChannel }_Effect${ i }]`, "enabled"); + status = status || engine.getValue(`[EffectRack1_EffectUnit${midiChannel}_Effect${i}]`, "enabled"); } return status; // return engine.getValue("[EffectRack1_EffectUnit" + midiChannel + "]", "group_[Channel" + channel + "]_enable"); @@ -1496,8 +1496,8 @@ DJCi500.slicerBeatActive = function(value, group, control) { const deck = script.deckFromGroup(deckData.currentDeck) - 1; const channel = deck % 2; - print(`***** SLICER ACTIVE VALUE: ${ DJCi500.slicerActive[deck]}`); - print(`***** SLICER: deck ${ deck } channel ${ channel}`); + print(`***** SLICER ACTIVE VALUE: ${DJCi500.slicerActive[deck]}`); + print(`***** SLICER: deck ${deck} channel ${channel}`); let bpm = engine.getValue(group, "file_bpm"), playposition = engine.getValue(group, "playposition"), From 28406a20fa0050ab7789322e44bc7c78749c0a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 17 Feb 2025 18:33:02 +0100 Subject: [PATCH 29/40] Clean up and linting --- .../Hercules-DJControl-Inpulse-500-script.js | 196 +++++++++--------- 1 file changed, 95 insertions(+), 101 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index e372466ec49a..aa1a33a87adb 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -142,11 +142,11 @@ DJCi500.vuMeterUpdateMaster = function(value, _group, control) { // Reserve the red led for peak indicator, this will in turn, make // the display more similar (I hope) to what Mixxx VU shows value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); - var control = (control === "vu_meter_left") ? 0x40 : 0x41; - midi.sendShortMsg(0xB0, control, value); + let ctrl = (control === "vu_meter_left") ? 0x40 : 0x41; + midi.sendShortMsg(0xB0, ctrl, value); }; -DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { +DJCi500.vuMeterPeakLeftMaster = function(value, _group, _control, _status) { if (value) { midi.sendShortMsg(0x90, 0x0A, 0x7F); } else { @@ -154,7 +154,7 @@ DJCi500.vuMeterPeakLeftMaster = function(value, group, control, status) { } }; -DJCi500.vuMeterPeakRightMaster = function(value, group, control, status) { +DJCi500.vuMeterPeakRightMaster = function(value, _group, _control, _status) { if (value) { midi.sendShortMsg(0x90, 0x0F, 0x7F); } else { @@ -238,9 +238,9 @@ DJCi500.fxEnabledIndicator = function(_value, group, _control, _status) { const deckB = DJCi500.deckB.currentDeck; const active = engine.getValue(group, "enabled"); - if (group == `[QuickEffectRack1_${deckA}]`) { + if (group === `[QuickEffectRack1_${deckA}]`) { midi.sendShortMsg(0x96, 0x66, active ? 0x1C : 0x60); - } else if (group == `[QuickEffectRack1_${deckB}]`) { + } else if (group === `[QuickEffectRack1_${deckB}]`) { midi.sendShortMsg(0x97, 0x66, active ? 0x1C : 0x60); } }; @@ -325,7 +325,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { }; }, shift: function() { - this.input = function(_channel, _control, _value, _status, group) { + this.input = function(_channel, _control, _value, _status, _group) { engine.setValue(deckData.currentDeck, "play_stutter", true); }; }, @@ -371,17 +371,17 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { this.input = function(_channel, _control, value, _status, _group) { if (value === 0x7F) { const deck = script.deckFromGroup(deckData.currentDeck); - const new_status = !deckData.vinylButtonState[deck - 1]; - deckData.jogWheel.vinylMode = new_status; - deckData.jogWheelShift.vinylMode = new_status; - deckData.vinylButtonState[deck] = new_status; - const new_message = new_status ? 0x7F : 0x00; - midi.sendShortMsg(this.midi[0], 0x03, new_message); + const newStatus = !deckData.vinylButtonState[deck - 1]; + deckData.jogWheel.vinylMode = newStatus; + deckData.jogWheelShift.vinylMode = newStatus; + deckData.vinylButtonState[deck] = newStatus; + const newMessage = newStatus ? 0x7F : 0x00; + midi.sendShortMsg(this.midi[0], 0x03, newMessage); } }; }, shift: function() { - this.input = function(channel, control, value, status, group) { + this.input = function(channel, control, value, _status, _group) { if (value === 0x7F) { const deck = script.deckFromGroup(deckData.currentDeck); deckData.slowPauseSetState[deck - 1] = !deckData.slowPauseSetState[deck - 1]; @@ -564,7 +564,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftControl: false, shiftChannel: true, sendShifted: true, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, _status, _group) { // FIXME: Toggle for loop halve and double?? const deckGroup = deckData.currentDeck; if (value >= 0x40) { @@ -578,7 +578,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // We only check and attach for slicer mode, but we have all // pad buttons here if we need something extra! this.padSelectButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.padSelectButtons[i] = new components.Button({ midi: [0x90 + midiChannel, 0x0F + (i - 1)], input: function(_channel, control, _value, _status, _group) { @@ -594,7 +594,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Hotcue buttons (PAD Mode 1) this.hotcueButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.hotcueButtons[i] = new components.HotcueButton({ midi: [0x95 + midiChannel, 0x00 + (i - 1)], number: i, @@ -608,7 +608,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Loop buttons (PAD Mode 2) this.loopButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.loopButtons[i] = new components.Button({ midi: [0x95 + midiChannel, 0x10 + (i - 1)], number: i, @@ -623,7 +623,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // A bit repeated code, but I want the leds to react accordingly this.loopShiftButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.loopShiftButtons[i] = new components.Button({ midi: [0x95 + midiChannel, 0x10 + (i - 1) + 8], number: i, @@ -638,14 +638,14 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Slicer buttons (PAD Mode 3) this.slicerButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.slicerButtons[i] = new components.Button({ midi: [0x95 + midiChannel, 0x20 + (i - 1)], number: i, shiftOffset: 8, shiftControl: true, sendShifted: true, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { // This is kind of a hack... somehow this is not getting the group correctly! DJCi500.slicerButtonFunc(channel, control, value, status, deckData.currentDeck); }, @@ -654,7 +654,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Sampler buttons (PAD Mode 4) this.samplerButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.samplerButtons[i] = new components.SamplerButton({ midi: [0x95 + midiChannel, 0x30 + (i - 1)], number: i, @@ -780,7 +780,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Beatloop rolls buttons (PAD Mode 6) this.rollButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { this.rollButtons[i] = new components.Button({ midi: [0x95 + midiChannel, 0x50 + (i - 1)], number: i, @@ -795,7 +795,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Effect buttons (PAD Mode 7) this.effectButtons = []; - for (var i = 1; i <= 3; i++) { + for (let i = 1; i <= 3; i++) { // First top row effects buttons, just the effect, disable HPF/LPF knob this.effectButtons[i] = new components.Button({ midi: [0x95 + midiChannel, 0x60 + (i - 1)], @@ -805,7 +805,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { sendShifted: true, group: `[EffectRack1_EffectUnit${midiChannel}_Effect${i}]`, outKey: "enabled", - output: function(value, group, control) { + output: function(value, _group, _control) { if (value) { this.send(0x7F); } else { @@ -814,9 +814,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { }, unshift: function() { // Normal effect button operation, toggling the effect assigned to it - this.input = function(channel, control, value, status, group) { - const fxNo = control - 0x5F; - const unit = channel - 0x95; + this.input = function(channel, control, value, _status, _group) { if (value === 0x7F) { script.toggleControl(this.group, "enabled"); } @@ -845,7 +843,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { group: `[QuickEffectRack1_[Channel${midiChannel}]]`, on: 0x5C, off: 0x30, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { engine.setValue(this.group, "chain_preset_selector", -1); midi.sendShortMsg(status, control, this.on); //17 -- 3B @@ -864,7 +862,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { group: `[QuickEffectRack1_[Channel${midiChannel}]]`, on: 0x5C, off: 0x30, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { engine.setValue(this.group, "chain_preset_selector", 1); midi.sendShortMsg(status, control, this.on); //17 -- 3B @@ -897,7 +895,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { shiftControl: true, sendShifted: true, group: "[EffectRack1_EffectUnit1]", - input: function(channel, _control, value, _status, group) { + input: function(channel, _control, value, _status, _group) { if (value === 0x7F) { const deckGroup = deckData.currentDeck; script.toggleControl(this.group, `group_${deckGroup}_enable`); @@ -925,7 +923,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0xB0 + midiChannel, 0x01], number: midiChannel, group: `[QuickEffectRack1_[Channel${midiChannel}]]`, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { // Move the effects knobs engine.setValue(`[EffectRack1_EffectUnit${this.number}]`, "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2); @@ -938,7 +936,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // Beat jump (PAD Mode 8) this.beatJumpButtons = []; - for (var i = 1; i <= 8; i++) { + for (let i = 1; i <= 8; i++) { const movement = (i % 2 === 0) ? "_forward" : "_backward"; const jmpVal = jumpValues[i - 1]; const jmpValShft = jumpValuesShift[i - 1]; @@ -1162,7 +1160,7 @@ DJCi500.crossfader = function(channel, control, value, status, group) { }; // Browser button. We move it to a custom JS function to avoid having to focus the Mixxx window for it to respond -DJCi500.moveLibrary = function(channel, control, value, status, group) { +DJCi500.moveLibrary = function(channel, control, value, _status, _group) { if (value > 0x3F) { if (DJCi500.browserOffFocusMode) { engine.setValue("[Playlist]", "SelectTrackKnob", -1); @@ -1178,7 +1176,7 @@ DJCi500.moveLibrary = function(channel, control, value, status, group) { } }; -DJCi500.spinback_button = function(channel, control, value, status, group) { +DJCi500.spinbackButton = function(channel, control, value, status, group) { const deck = script.deckFromGroup(group); engine.spinback(deck, value > 0, 2.5); // use default starting rate of -10 but decrease speed more quickly }; @@ -1194,7 +1192,7 @@ DJCi500.tempoLEDs = function() { const tempo2 = engine.getValue(deckB, "bpm"); let diff = tempo1 - tempo2; - //Check double tempo: + // Check double tempo: let doubleTempo = 0; if (diff > 0) { if ((tempo1 / tempo2) > 1.5) { @@ -1209,58 +1207,56 @@ DJCi500.tempoLEDs = function() { } if (diff < -0.25) { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1E, 0x0); midi.sendShortMsg(0x91, 0x1F, 0x7F); midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1F, 0x0); midi.sendShortMsg(0x92, 0x1E, 0x7F); midi.sendShortMsg(0x92, 0x2C, 0x0); - //clear beatalign leds - //Deck1 + // clear beatalign leds + // Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x2D, 0x0); } else if (diff > 0.25) { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1F, 0x0); midi.sendShortMsg(0x91, 0x1E, 0x7F); midi.sendShortMsg(0x91, 0x2C, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1E, 0x0); midi.sendShortMsg(0x92, 0x1F, 0x7F); midi.sendShortMsg(0x92, 0x2C, 0x0); - //clear beatalign leds - //Deck1 + // clear beatalign leds + // Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x2D, 0x0); } else { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1E, 0x0); midi.sendShortMsg(0x91, 0x1F, 0x0); midi.sendShortMsg(0x91, 0x2C, 0x7F); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1E, 0x0); midi.sendShortMsg(0x92, 0x1F, 0x0); midi.sendShortMsg(0x92, 0x2C, 0x7F); - //Do beat alignment only if the tracks are already on Tempo + // Do beat alignment only if the tracks are already on Tempo // and only if they are playing if (engine.getValue(deckA, "play_latched") && engine.getValue(deckB, "play_latched")) { - - let beat1 = engine.getValue(deckA, "beat_distance"); let beat2 = engine.getValue(deckB, "beat_distance"); if (doubleTempo) { @@ -1281,7 +1277,7 @@ DJCi500.tempoLEDs = function() { diff = 1+diff; } if ((diff < 0.02) || (diff > 1-0.02)) { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); midi.sendShortMsg(0x91, 0x2D, 0x7F); @@ -1290,36 +1286,36 @@ DJCi500.tempoLEDs = function() { midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x2D, 0x7F); } else if (diff < 0.5) { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x7F); midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x1C, 0x7F); midi.sendShortMsg(0x91, 0x2D, 0x0); } else { - //Deck1 + // Deck1 midi.sendShortMsg(0x91, 0x1D, 0x0); midi.sendShortMsg(0x91, 0x1C, 0x7F); midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); midi.sendShortMsg(0x92, 0x1D, 0x7F); midi.sendShortMsg(0x92, 0x2D, 0x0); } - }//if playing - else { - //Deck1 + // if playing + } else { + // Deck1 midi.sendShortMsg(0x91, 0x1C, 0x0); midi.sendShortMsg(0x91, 0x1D, 0x0); midi.sendShortMsg(0x91, 0x2D, 0x0); - //Deck2 + // Deck2 midi.sendShortMsg(0x92, 0x1C, 0x0); midi.sendShortMsg(0x92, 0x1D, 0x0); midi.sendShortMsg(0x92, 0x2D, 0x0); } - }//else tempo + }// else tempo }; // After a channel change, make sure we read the current status @@ -1329,7 +1325,7 @@ DJCi500.updateDeckStatus = function(group) { // Update the vinyl button let vinylState = false; - const deckIndex = script.deckFromGroup(deckData.currentDeck) - 1; + const deckIndex = script.deckFromGroup(group) - 1; const channel = ((group === "[Channel1]") || (group === "[Channel3]")) ? 1 : 2; if (channel === 1) { vinylState = DJCi500.deckA.vinylButtonState[deckIndex]; @@ -1373,7 +1369,7 @@ DJCi500.updateDeckStatus = function(group) { // This is where we choose the channel using the FX buttons and light them // up correctly -DJCi500.deckSelector = function(channel, control, value, status, group) { +DJCi500.deckSelector = function(channel, control, value, _status, _group) { if (value === 0x7F) { const deckChosen = control - 0x13; // FX1 is 0x14, so this will yield the number switch (deckChosen) { @@ -1405,7 +1401,7 @@ DJCi500.deckSelector = function(channel, control, value, status, group) { }; }; -DJCi500.updateEffectStatus = function(midiChannel, channel) { +DJCi500.updateEffectStatus = function(midiChannel, _channel) { let status = false; for (let i = 1; i <= 3; i++) { status = status || engine.getValue(`[EffectRack1_EffectUnit${midiChannel}_Effect${i}]`, "enabled"); @@ -1418,49 +1414,47 @@ DJCi500.updateEffectStatus = function(midiChannel, channel) { // SLICER // /////////////////////////////////////////////////////////////// DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { - let index = control - 0x20, - deck = script.deckFromGroup(deckData.currentDeck) - 1, - domain = DJCi500.selectedSlicerDomain[deck], - beatsToJump = 0, - passedTime = engine.getValue(group, "beat_distance"), - loopEnabled = engine.getValue(group, "loop_enabled"); + const index = control - 0x20; + const deck = script.deckFromGroup(group) - 1; + const domain = DJCi500.selectedSlicerDomain[deck]; + const passedTime = engine.getValue(group, "beat_distance"); + const loopEnabled = engine.getValue(group, "loop_enabled"); + + let beatsToJump = 0; if (value) { DJCi500.slicerButton[deck] = index; - //Maybe I need to update this (seems sometimes it does not work.) - //DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); + // Maybe I need to update this (seems sometimes it does not work.) + // DJCi500.slicerBeatsPassed[deck] = Math.floor((playposition * duration) * (bpm / 60.0)); beatsToJump = (index * (domain / 8)) - ((DJCi500.slicerBeatsPassed[deck] % domain)); beatsToJump -= passedTime; - //activate the one-shot timer for the slip end. + // activate the one-shot timer for the slip end. if (!DJCi500.slicerTimer[deck]) { DJCi500.slicerTimer[deck] = true; - let timer_ms = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; + let timerMs = (1-passedTime)*60.0/engine.getValue(group, "bpm")*1000; - //quality of life fix for not-precise hands or beatgrid - // also good fix for really small timer_ms values. + // quality of life fix for not-precise hands or beatgrid + // also good fix for really small timerMs values. if ((passedTime >= 0.8) && //this is because while looping doing this thing on beat 8 break the flow. ((!loopEnabled) || (DJCi500.slicerBeatsPassed[deck] % domain) !== (domain-1))) { - timer_ms += 60.0/engine.getValue(group, "bpm")*1000; + timerMs += 60.0/engine.getValue(group, "bpm")*1000; } - engine.beginTimer(timer_ms, - //"DJCi500.slicerTimerCallback("+group+")", true); + engine.beginTimer(timerMs, + // "DJCi500.slicerTimerCallback("+group+")", true); function() { - //need to do this otherwise loop does not work on beat 8 because of slip. + // need to do this otherwise loop does not work on beat 8 because of slip. if ((engine.getValue(group, "loop_enabled") === true)) { - //on the wiki it says it returns an integer, but I tested and instead seems a Real value: + // on the wiki it says it returns an integer, but I tested and instead seems a Real value: // But it does not work cuz the value does not relate to beat. they are samples. - //var endLoop = engine.getValue(group, "loop_end_position"); + // var endLoop = engine.getValue(group, "loop_end_position"); engine.setValue(group, "reloop_toggle", true); //false engine.setValue(group, "slip_enabled", false); - //Aleatory behavior, probably because the slip does not always have completed before "returning" - //so I need to introduce a timer waiting the slip function to be completely resolved + // Aleatory behavior, probably because the slip does not always have completed before "returning" + // so I need to introduce a timer waiting the slip function to be completely resolved engine.beginTimer(2, function() { - const bpm_file = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"); engine.setValue(group, "reloop_toggle", true); }, true); @@ -1475,38 +1469,38 @@ DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { engine.setValue(group, "slip_enabled", true); - //Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping + // Because of Mixxx beatjump implementation, we need to deactivate the loop before jumping // also there is no "lopp_deactivate" and loop_activate false does not work. if (loopEnabled) { engine.setValue(group, "reloop_toggle", true); } engine.setValue(group, "beatjump", beatsToJump); - //This sadly does not work. - //engine.setValue(group, "loop_move", -beatsToJump); + // This sadly does not work. + // engine.setValue(group, "loop_move", -beatsToJump); if (loopEnabled) { engine.setValue(group, "reloop_toggle", true); } midi.sendShortMsg((0x96+(deck % 2)), 0x20+index, 0x62); - } //if value + } // if value }; -//this below is connected to beat_active +// this below is connected to beat_active DJCi500.slicerBeatActive = function(value, group, control) { // This slicer implementation will work for constant beatgrids only! - const deck = script.deckFromGroup(deckData.currentDeck) - 1; + const deck = script.deckFromGroup(group) - 1; const channel = deck % 2; print(`***** SLICER ACTIVE VALUE: ${DJCi500.slicerActive[deck]}`); print(`***** SLICER: deck ${deck} channel ${channel}`); - let bpm = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"), - slicerPosInSection = 0, - ledBeatState = false, - domain = DJCi500.selectedSlicerDomain[deck]; + const bpm = engine.getValue(group, "file_bpm"), + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"), + slicerPosInSection = 0, + ledBeatState = false, + domain = DJCi500.selectedSlicerDomain[deck]; - //this works. + // this works. if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { return; } @@ -1518,7 +1512,7 @@ DJCi500.slicerBeatActive = function(value, group, control) { // PAD Led control: if (DJCi500.slicerButton[deck] !== slicerPosInSection) { for (let i = 0; i < 8; i++) { - active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; + const active = ((slicerPosInSection === i) ? ledBeatState : !ledBeatState) ? 0x03 : 0x7F; midi.sendShortMsg((0x96+channel), 0x20+i, active); } } else { From 56fc4fbca154d9aa889bf26e55ca22b8d1eceb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Mon, 17 Feb 2025 19:02:18 +0100 Subject: [PATCH 30/40] fix: more linting (pre-commit doesn't work in local, sorry folks!) --- .../Hercules-DJControl-Inpulse-500-script.js | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index aa1a33a87adb..f479209231bb 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -142,7 +142,7 @@ DJCi500.vuMeterUpdateMaster = function(value, _group, control) { // Reserve the red led for peak indicator, this will in turn, make // the display more similar (I hope) to what Mixxx VU shows value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 124); - let ctrl = (control === "vu_meter_left") ? 0x40 : 0x41; + const ctrl = (control === "vu_meter_left") ? 0x40 : 0x41; midi.sendShortMsg(0xB0, ctrl, value); }; @@ -822,9 +822,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { }, shift: function() { // Shift button will change the effect to the next in the list - this.input = function(channel, control, value, status, group) { - const fxNo = control - 0x67; - const unit = channel - 0x95; + this.input = function(channel, control, value, _status, _group) { if (value === 0x7F) { engine.setValue(this.group, "effect_selector", +1); } @@ -923,7 +921,7 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0xB0 + midiChannel, 0x01], number: midiChannel, group: `[QuickEffectRack1_[Channel${midiChannel}]]`, - input: function(channel, control, value, status, _group) { + input: function(channel, control, value, _status, _group) { if (DJCi500.updateEffectStatus(midiChannel, deckData.currentDeck)) { // Move the effects knobs engine.setValue(`[EffectRack1_EffectUnit${this.number}]`, "super1", Math.abs(script.absoluteNonLin(value, 0.0, 0.5, 1.0, 0, 127) - 0.5)*2); @@ -1485,20 +1483,18 @@ DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { }; // this below is connected to beat_active -DJCi500.slicerBeatActive = function(value, group, control) { +DJCi500.slicerBeatActive = function(value, group, _control) { // This slicer implementation will work for constant beatgrids only! const deck = script.deckFromGroup(group) - 1; const channel = deck % 2; - print(`***** SLICER ACTIVE VALUE: ${DJCi500.slicerActive[deck]}`); - print(`***** SLICER: deck ${deck} channel ${channel}`); - const bpm = engine.getValue(group, "file_bpm"), - playposition = engine.getValue(group, "playposition"), - duration = engine.getValue(group, "duration"), - slicerPosInSection = 0, - ledBeatState = false, - domain = DJCi500.selectedSlicerDomain[deck]; + playposition = engine.getValue(group, "playposition"), + duration = engine.getValue(group, "duration"), + ledBeatState = false, + domain = DJCi500.selectedSlicerDomain[deck]; + + let slicerPosInSection = 0; // this works. if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { From 6a44a6941a258400213bb1b643fa5bdd0f5be124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Sat, 22 Feb 2025 15:36:08 +0100 Subject: [PATCH 31/40] Fix for main deck variable not working --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index f479209231bb..b43c0de74afc 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -8,7 +8,7 @@ // Version 1.6c: (August 2023) resetreboot // * Requires Mixxx >= 2.3.4 // * Volume meters follow correctly the selected channel -// * Use the full 14 bits for knobs for more precission +// * Use the full 14 bits for knobs for more precision // * Add effects to the PAD 7 mode // * Create decks for four channel mode // * Change the behavior of the FX buttons, use them as Channel selector, using the LEDs @@ -66,7 +66,9 @@ // * Add beat jump + SHIFT jumps // // **************************************************************************** -const DJCi500 = {}; + +// For some reason, if this is not var, the script errs +var DJCi500 = {}; /////////////////////////////////////////////////////////////// // USER OPTIONS // From cc33865c88eec4678532956f22e6084664e26ec1 Mon Sep 17 00:00:00 2001 From: m0dB Date: Sat, 22 Feb 2025 17:55:43 +0100 Subject: [PATCH 32/40] corrected wiki link, sanitized line-ends and tabs --- .../Hercules-DJControl-Inpulse-500-script.js | 9 +- .../Hercules_DJControl_Inpulse_500.midi.xml | 6848 ++++++++--------- 2 files changed, 3429 insertions(+), 3428 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index b43c0de74afc..cb2a45a821bf 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -51,11 +51,11 @@ // * Wiki: https://mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 // // Version 1.0c: -// * Hot Cue: implementation of the Color API (Work in progress) -// - Assigned color directly to pad (XML) -// * Added DECK LED number - On when playing +// * Hot Cue: implementation of the Color API (Work in progress) +// - Assigned color directly to pad (XML) +// * Added DECK LED number - On when playing // * Moved Beatjump to Pad mode 3 (Slicer) -// * Set different color for upper (Sampler 1-4) and lower (Sampler 5-8) sampler pads +// * Set different color for upper (Sampler 1-4) and lower (Sampler 5-8) sampler pads // // Version 1.0 - Based upon Inpulse 300 v1.2 (official) // @@ -1526,4 +1526,5 @@ DJCi500.shutdown = function() { //cleanup midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off midi.sendShortMsg(0xB0, 0x7F, 0x7E); + }; diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index 120756c6841e..771a83862319 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -1,3424 +1,3424 @@ - - - - Hercules DJControl Inpulse 500 1d - DJ Phatso for Hercules Technical Support - MIDI Preset for Hercules DJControl Inpulse 500 - https://www.mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 - https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 - - - - - - - - - - - - - - [Library] - MoveFocus - Browser button - 0x90 - 0x00 - - - - - - - - [AutoDJ] - enabled - AutoDJ On/Off - 0x90 - 0x03 - - - - - - [Mixer Profile] - DJCi500.crossfaderEnable - CROSS FADER ENABLE - 0x90 - 0x18 - - - - - - - [Mixer Profile] - DJCi500.crossfaderSetCurve - CROSS FADER SET CURVE - 0xB0 - 0x0B - - - - - - - - - - [Channel1] - DJCi500.deckA.playButton.input - Play button - 0x91 - 0x07 - - - - - - - [Channel1] - DJCi500.deckA.cueButton.input - Cue button - 0x91 - 0x06 - - - - - - - [Channel1] - DJCi500.deckA.syncButton.input - Sync button - 0x91 - 0x05 - - - - - - - [Channel1] - DJCi500.deckA.pflButton.input - PFL button - 0x91 - 0x0C - - - - - - - [Channel1] - DJCi500.deckA.loadButton.input - LOAD A button - 0x91 - 0x0D - - - - - - - [Channel1] - DJCi500.deckA.loadButton.input - LOAD A button - 0x94 - 0x0D - - - - - - - [Channel1] - DJCi500.deckA.shiftButton.input - Shift Deck A button - 0x91 - 0x04 - - - - - - - [Channel1] - DJCi500.deckA.slipButton.input - SLIP button - 0x91 - 0x01 - - - - - - - [Channel1] - DJCi500.deckA.quantButton.input - Quantize button - Deck 1 - 0x91 - 0x02 - - - - - - - [Channel1] - DJCi500.deckA.quantButton.input - Keylock button (shift+quant) - Deck 1 - 0x94 - 0x02 - - - - - - - - [Master] - DJCi500.deckA.vinylButton.input - Vinyl Deck A - 0x91 - 0x03 - - - - - - - - [Channel1] - DJCi500.deckA.vinylButton.input - Shift + Vinyl Deck A - 0x94 - 0x03 - - - - - - - - [Channel1] - DJCi500.deckA.loopInButton.input - Loop In button - 0x91 - 0x09 - - - - - - [Channel1] - DJCi500.deckA.loopOutButton.input - Loop Out button - 0x91 - 0x0A - - - - - - - [Channel1] - DJCi500.deckA.loopInButton.input - S+Loop In button (loop in goto) - 0x94 - 0x09 - - - - - - [Channel1] - DJCi500.deckA.loopOutButton.input - S+Loop Out button (loop out goto) - 0x94 - 0x0A - - - - - - - - [Channel1] - DJCi500.deckA.loopEncoderPush.input - Loop Encoder Push button Deck A Reloop toggle - 0x91 - 0x2C - - - - - - - [Channel1] - DJCi500.deckA.loopEncoderPush.input - Loop Encoder Push button Deck A 4 Beat loop activate - 0x94 - 0x2C - - - - - - - - [Channel1] - DJCi500.deckA.loopEncoder.input - Loop Halve/Double (Loop Knob Deck A) - 0xB1 - 0x0E - - - - - - - - - - [Channel2] - DJCi500.deckB.playButton.input - Play button - 0x92 - 0x07 - - - - - - - [Channel2] - DJCi500.deckB.cueButton.input - Cue button - 0x92 - 0x06 - - - - - - - [Channel2] - DJCi500.deckB.syncButton.input - Sync button - 0x92 - 0x05 - - - - - - - [Channel2] - DJCi500.deckB.pflButton.input - PFL button - 0x92 - 0x0C - - - - - - - [Channel2] - DJCi500.deckB.loadButton.input - LOAD B button - 0x92 - 0x0D - - - - - - - [Channel2] - DJCi500.deckB.loadButton.input - LOAD B button - 0x95 - 0x0D - - - - - - - [Channel1] - DJCi500.deckB.shiftButton.input - Shift Deck A button - 0x92 - 0x04 - - - - - - - [Channel2] - DJCi500.deckB.slipButton.input - SLIP button - 0x92 - 0x01 - - - - - - - [Channel2] - DJCi500.deckB.quantButton.input - Quantize button - Deck 2 - 0x92 - 0x02 - - - - - - - [Channel2] - DJCi500.deckB.quantButton.input - Keylock button (shift+quant) - Deck 2 - 0x95 - 0x02 - - - - - - - - [Master] - DJCi500.deckB.vinylButton.input - Vinyl Deck B - 0x92 - 0x03 - - - - - - - - [Channel2] - DJCi500.deckB.vinylButton.input - Shift + Vinyl Deck B - 0x95 - 0x03 - - - - - - - - [Channel2] - DJCi500.deckB.loopInButton.input - Loop In button - 0x92 - 0x09 - - - - - - [Channel2] - DJCi500.deckB.loopOutButton.input - Loop Out button - 0x92 - 0x0A - - - - - - - [Channel2] - DJCi500.deckB.loopInButton.input - Loop In button (Loop In Goto) - 0x95 - 0x09 - - - - - - [Channel2] - DJCi500.deckB.loopOutButton.input - Loop Out button (loop out goto) - 0x95 - 0x0A - - - - - - - - [Channel2] - DJCi500.deckB.loopEncoderPush.input - Loop Encoder Push button Deck B (reloop toggle) - 0x92 - 0x2C - - - - - - - [Channel2] - DJCi500.deckB.loopEncoderPush.input - Loop Encoder Push button Deck B (beatloop 4 activated) - 0x95 - 0x2C - - - - - - - - - [Channel2] - DJCi500.deckB.loopEncoder.input - Loop Halve/Double (Loop Knob Deck B) - 0xB2 - 0x0E - - - - - - - - - - [Skin] - show_maximized_library - Browser button - Maximize Library view - 0x93 - 0x00 - - - - - - - - - - [Channel1] - DJCi500.deckA.playButton.input - SHIFT + Play: Play Stutter - 0x94 - 0x07 - - - - - - - [Channel1] - DJCi500.deckA.cueButton.input - SHIFT + Cue: REWIND to beginning - 0x94 - 0x06 - - - - - - - [Channel1] - DJCi500.deckA.syncButton.input - SHIFT + Sync: Match key - 0x94 - 0x05 - - - - - - - - - [Channel2] - DJCi500.deckB.playButton.input - SHIFT + Play: Play Stutter - 0x95 - 0x07 - - - - - - - [Channel2] - DJCi500.deckB.cueButton.input - SHIFT + Cue: REWIND to beginning - 0x95 - 0x06 - - - - - - - [Channel2] - DJCi500.deckB.syncButton.input - SHIFT + Sync: Sync key - 0x95 - 0x05 - - - - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[1].input - PAD select - 0x91 - 0x0F - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[2].input - PAD select - 0x91 - 0x10 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[3].input - PAD select - 0x91 - 0x11 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[4].input - PAD select - 0x91 - 0x12 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[5].input - PAD select - 0x91 - 0x13 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[6].input - PAD select - 0x91 - 0x14 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[7].input - PAD select - 0x91 - 0x15 - - - - - - [Channel1] - DJCi500.deckA.padSelectButtons[8].input - PAD select - 0x91 - 0x16 - - - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[1].input - PAD 1 - 0x96 - 0x00 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[2].input - PAD 2 - 0x96 - 0x01 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[3].input - PAD 3 - 0x96 - 0x02 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[4].input - PAD 4 - 0x96 - 0x03 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[5].input - PAD 5 - 0x96 - 0x04 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[6].input - PAD 6 - 0x96 - 0x05 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[7].input - PAD 7 - 0x96 - 0x06 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[8].input - PAD 8 - 0x96 - 0x07 - - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[1].input - PAD 1 + L-Shift - 0x96 - 0x08 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[2].input - PAD 2 + L-Shift - 0x96 - 0x09 - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[3].input - PAD 3 + L-Shift - 0x96 - 0x0A - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[4].input - PAD 4 + L-Shift - 0x96 - 0x0B - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[5].input - PAD 5 + L-Shift - 0x96 - 0x0C - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[6].input - PAD 6 + L-Shift - 0x96 - 0x0D - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[7].input - PAD 7 + L-Shift - 0x96 - 0x0E - - - - - - [Channel1] - DJCi500.deckA.hotcueButtons[8].input - PAD 8 + L-Shift - 0x96 - 0x0F - - - - - - - - [Channel1] - DJCi500.deckA.loopButtons[1].input - Loop 1/8 Beat (Pad 1) - 0x96 - 0x10 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[2].input - Loop 1/4 Beat (Pad 2) - 0x96 - 0x11 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[3].input - Loop 1/2 Beat (Pad 3) - 0x96 - 0x12 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[4].input - Loop 1 Beat (Pad 4) - 0x96 - 0x13 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[5].input - Loop 2 Beat (Pad 5) - 0x96 - 0x14 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[6].input - Loop 4 Beat (Pad 6) - 0x96 - 0x15 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[7].input - Loop 8 Beat (Pad 7) - 0x96 - 0x16 - - - - - - [Channel1] - DJCi500.deckA.loopButtons[8].input - Loop 16 Beat (Pad 8) - 0x96 - 0x17 - - - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[1].input - Loop 3/4 Beat (Pad 1) - 0x96 - 0x18 - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[2].input - Loop 5/4 Beat (Pad 2) - 0x96 - 0x19 - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[3].input - Loop 6/4 Beat (Pad 3) - 0x96 - 0x1A - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[4].input - Loop 7/4 Beat (Pad 4) - 0x96 - 0x1B - - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[5].input - Loop 32 Beat (Pad 5) - 0x96 - 0x1C - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[6].input - Loop 64 Beat (Pad 6) - 0x96 - 0x1D - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[7].input - Loop 128 Beat (Pad 7) - 0x96 - 0x1E - - - - - - [Channel1] - DJCi500.deckA.loopShiftButtons[8].input - Loop 256 Beat (Pad 8) - 0x96 - 0x1F - - - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[1].input - PAD 1 - 0x96 - 0x20 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[2].input - PAD 2 - 0x96 - 0x21 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[3].input - PAD 3 - 0x96 - 0x22 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[4].input - PAD 4 - 0x96 - 0x23 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[5].input - PAD 5 - 0x96 - 0x24 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[6].input - PAD 6 - 0x96 - 0x25 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[7].input - PAD 7 - 0x96 - 0x26 - - - - - - [Channel1] - DJCi500.deckA.slicerButtons[8].input - PAD 8 - 0x96 - 0x27 - - - - - - - - [Sampler1] - DJCi500.deckA.samplerButtons[1].input - PAD 1 - 0x96 - 0x30 - - - - - - [Sampler2] - DJCi500.deckA.samplerButtons[2].input - PAD 2 - 0x96 - 0x31 - - - - - - [Sampler3] - DJCi500.deckA.samplerButtons[3].input - PAD 3 - 0x96 - 0x32 - - - - - - [Sampler4] - DJCi500.deckA.samplerButtons[4].input - PAD 4 - 0x96 - 0x33 - - - - - - [Sampler5] - DJCi500.deckA.samplerButtons[5].input - PAD 5 - 0x96 - 0x34 - - - - - - [Sampler6] - DJCi500.deckA.samplerButtons[6].input - PAD 6 - 0x96 - 0x35 - - - - - - [Sampler7] - DJCi500.deckA.samplerButtons[7].input - PAD 7 - 0x96 - 0x36 - - - - - - [Sampler8] - DJCi500.deckA.samplerButtons[8].input - PAD 8 - 0x96 - 0x37 - - - - - - - - [Sampler1] - DJCi500.deckA.samplerButtons[1].input - PAD 1 - 0x96 - 0x38 - - - - - - [Sampler2] - DJCi500.deckA.samplerButtons[2].input - PAD 2 - 0x96 - 0x39 - - - - - - [Sampler3] - DJCi500.deckA.samplerButtons[3].input - PAD 3 - 0x96 - 0x3A - - - - - - [Sampler4] - DJCi500.deckA.samplerButtons[4].input - PAD 4 - 0x96 - 0x3B - - - - - - [Sampler5] - DJCi500.deckA.samplerButtons[5].input - PAD 5 - 0x96 - 0x3C - - - - - - [Sampler6] - DJCi500.deckA.samplerButtons[6].input - PAD 6 - 0x96 - 0x3D - - - - - - [Sampler7] - DJCi500.deckA.samplerButtons[7].input - PAD 7 - 0x96 - 0x3E - - - - - - [Sampler8] - DJCi500.deckA.samplerButtons[8].input - PAD 8 - 0x96 - 0x3F - - - - - - - - [Channel1] - DJCi500.deckA.pitchDownTone.input - Pitch down - tone - 0x96 - 0x40 - - - - - - [Channel1] - DJCi500.deckA.pitchDownSemiTone.input - Pitch down - semitone - 0x96 - 0x41 - - - - - - [Channel1] - DJCi500.deckA.pitchUpSemiTone.input - Pitch up - semitone - 0x96 - 0x42 - - - - - - [Channel1] - DJCi500.deckA.pitchUpTone.input - Pitch up - tone - 0x96 - 0x43 - - - - - - [Channel1] - DJCi500.deckA.pitchSliderIncrease.input - Pitch slider increase resolution - 0x96 - 0x46 - - - - - - [Channel1] - DJCi500.deckA.pitchSliderDecrease.input - Pitch slider Decrease resolution - 0x96 - 0x45 - - - - - - [Channel1] - DJCi500.deckA.pitchSliderReset.input - Pitch slider Reset resolution - 0x96 - 0x44 - - - - - - - - [Channel1] - DJCi500.deckA.rollButtons[1].input - Loop 1/8 Beat (Pad 1) - 0x96 - 0x50 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[2].input - Loop 1/4 Beat (Pad 2) - 0x96 - 0x51 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[3].input - Loop 1/2 Beat (Pad 3) - 0x96 - 0x52 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[4].input - Loop 1 Beat (Pad 4) - 0x96 - 0x53 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[5].input - Loop 2 Beat (Pad 5) - 0x96 - 0x54 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[6].input - Loop 2 Beat (Pad 6) - 0x96 - 0x55 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[7].input - Loop 8 Beat (Pad 7) - 0x96 - 0x56 - - - - - - [Channel1] - DJCi500.deckA.rollButtons[8].input - Loop 2 Beat (Pad 8) - 0x96 - 0x57 - - - - - - - - [Channel1] - DJCi500.deckA.effectButtons[1].input - PAD 1 - 0x96 - 0x60 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[2].input - PAD 2 - 0x96 - 0x61 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[3].input - PAD 3 - 0x96 - 0x62 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[4].input - PAD 4 - 0x96 - 0x63 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[5].input - PAD 5 - 0x96 - 0x64 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[6].input - PAD 6 - 0x96 - 0x65 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[7].input - PAD 7 - 0x96 - 0x66 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[8].input - PAD 8 - 0x96 - 0x67 - - - - - - - - [Channel1] - DJCi500.deckA.effectButtons[1].input - PAD 1 - 0x96 - 0x68 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[2].input - PAD 2 - 0x96 - 0x69 - - - - - - [Channel1] - DJCi500.deckA.effectButtons[3].input - PAD 3 - 0x96 - 0x6A - - - - - - [Channel1] - DJCi500.deckA.effectButtons[4].input - PAD 4 - 0x96 - 0x6B - - - - - - [Channel1] - DJCi500.deckA.effectButtons[5].input - PAD 5 - 0x96 - 0x6C - - - - - - [Channel1] - DJCi500.deckA.effectButtons[6].input - PAD 6 - 0x96 - 0x6D - - - - - - [Channel1] - DJCi500.deckA.effectButtons[7].input - PAD 7 - 0x96 - 0x6E - - - - - - [Channel1] - DJCi500.deckA.effectButtons[8].input - PAD 8 - 0x96 - 0x6F - - - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[1].input - Beat jump 1 backward - 0x96 - 0x70 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[2].input - Beat jump 1 forward - 0x96 - 0x71 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[3].input - Beat jump 2 backward - 0x96 - 0x72 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[4].input - Beat jump 2 forward - 0x96 - 0x73 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[5].input - Beat jump 4 backward - 0x96 - 0x74 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[6].input - Beat jump 4 forward - 0x96 - 0x75 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[7].input - Beat jump 8 backward - 0x96 - 0x76 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[8].input - Beat jump 8 forward - 0x96 - 0x77 - - - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[1].input - Beat jump 16 backward - 0x96 - 0x78 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[2].input - Beat jump 16 forward - 0x96 - 0x79 - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[3].input - Beat jump 32 backward - 0x96 - 0x7A - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[4].input - Beat jump 32 forward - 0x96 - 0x7B - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[5].input - Beat jump 64 backward - 0x96 - 0x7C - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[6].input - Beat jump 64 forward - 0x96 - 0x7D - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[7].input - Beat jump 128 backward - 0x96 - 0x7E - - - - - - [Channel1] - DJCi500.deckA.beatJumpButtons[8].input - Beat jump 128 forward - 0x96 - 0x7F - - - - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[1].input - PAD select - 0x92 - 0x0F - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[2].input - PAD select - 0x92 - 0x10 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[3].input - PAD select - 0x92 - 0x11 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[4].input - PAD select - 0x92 - 0x12 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[5].input - PAD select - 0x92 - 0x13 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[6].input - PAD select - 0x92 - 0x14 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[7].input - PAD select - 0x92 - 0x15 - - - - - - [Channel2] - DJCi500.deckB.padSelectButtons[8].input - PAD select - 0x92 - 0x16 - - - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[1].input - PAD 1 - 0x97 - 0x00 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[2].input - PAD 2 - 0x97 - 0x01 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[3].input - PAD 3 - 0x97 - 0x02 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[4].input - PAD 4 - 0x97 - 0x03 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[5].input - PAD 5 - 0x97 - 0x04 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[6].input - PAD 6 - 0x97 - 0x05 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[7].input - PAD 7 - 0x97 - 0x06 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[8].input - PAD 8 - 0x97 - 0x07 - - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[1].input - PAD 1 + R-Shift - 0x97 - 0x08 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[2].input - PAD 2 + R-Shift - 0x97 - 0x09 - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[3].input - PAD 3 + R-Shift - 0x97 - 0x0A - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[4].input - PAD 4 + R-Shift - 0x97 - 0x0B - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[5].input - PAD 5 + R-Shift - 0x97 - 0x0C - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[6].input - PAD 6 + R-Shift - 0x97 - 0x0D - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[7].input - PAD 7 + R-Shift - 0x97 - 0x0E - - - - - - [Channel2] - DJCi500.deckB.hotcueButtons[8].input - PAD 8 + R-Shift - 0x97 - 0x0F - - - - - - - [Channel2] - DJCi500.deckB.loopButtons[1].input - Loop 1/8 Beat (Pad 1) - 0x97 - 0x10 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[2].input - Loop 1/4 Beat (Pad 2) - 0x97 - 0x11 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[3].input - Loop 1/2 Beat (Pad 3) - 0x97 - 0x12 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[4].input - Loop 1 Beat (Pad 4) - 0x97 - 0x13 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[5].input - Loop 2 Beat (Pad 5) - 0x97 - 0x14 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[6].input - Loop 4 Beat (Pad 6) - 0x97 - 0x15 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[7].input - Loop 8 Beat (Pad 7) - 0x97 - 0x16 - - - - - - [Channel2] - DJCi500.deckB.loopButtons[8].input - Loop 16 Beat (Pad 8) - 0x97 - 0x17 - - - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[1].input - Loop 3/4 Beat (Pad 1) - 0x97 - 0x18 - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[2].input - Loop 5/4 Beat (Pad 2) - 0x97 - 0x19 - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[3].input - Loop 6/4 Beat (Pad 3) - 0x97 - 0x1A - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[4].input - Loop 7/4 Beat (Pad 4) - 0x97 - 0x1B - - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[5].input - Loop 32 Beat (Pad 5) - 0x97 - 0x1C - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[6].input - Loop 64 Beat (Pad 6) - 0x97 - 0x1D - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[7].input - Loop 128 Beat (Pad 7) - 0x97 - 0x1E - - - - - - [Channel2] - DJCi500.deckB.loopShiftButtons[8].input - Loop 256 Beat (Pad 8) - 0x97 - 0x1F - - - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[1].input - PAD 1 - 0x97 - 0x20 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[2].input - PAD 2 - 0x97 - 0x21 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[3].input - PAD 3 - 0x97 - 0x22 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[4].input - PAD 4 - 0x97 - 0x23 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[5].input - PAD 5 - 0x97 - 0x24 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[6].input - PAD 6 - 0x97 - 0x25 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[7].input - PAD 7 - 0x97 - 0x26 - - - - - - [Channel2] - DJCi500.deckB.slicerButtons[8].input - PAD 8 - 0x97 - 0x27 - - - - - - - - [Sampler1] - DJCi500.deckB.samplerButtons[1].input - PAD 1 - 0x97 - 0x30 - - - - - - [Sampler2] - DJCi500.deckB.samplerButtons[2].input - PAD 2 - 0x97 - 0x31 - - - - - - [Sampler3] - DJCi500.deckB.samplerButtons[3].input - PAD 3 - 0x97 - 0x32 - - - - - - [Sampler4] - DJCi500.deckB.samplerButtons[4].input - PAD 4 - 0x97 - 0x33 - - - - - - [Sampler5] - DJCi500.deckB.samplerButtons[5].input - PAD 5 - 0x97 - 0x34 - - - - - - [Sampler6] - DJCi500.deckB.samplerButtons[6].input - PAD 6 - 0x97 - 0x35 - - - - - - [Sampler7] - DJCi500.deckB.samplerButtons[7].input - PAD 7 - 0x97 - 0x36 - - - - - - [Sampler8] - DJCi500.deckB.samplerButtons[8].input - PAD 8 - 0x97 - 0x37 - - - - - - - - [Sampler1] - DJCi500.deckB.samplerButtons[1].input - PAD 1 - 0x97 - 0x38 - - - - - - [Sampler2] - DJCi500.deckB.samplerButtons[2].input - PAD 2 - 0x97 - 0x39 - - - - - - [Sampler3] - DJCi500.deckB.samplerButtons[3].input - PAD 3 - 0x97 - 0x3A - - - - - - [Sampler4] - DJCi500.deckB.samplerButtons[4].input - PAD 4 - 0x97 - 0x3B - - - - - - [Sampler5] - DJCi500.deckB.samplerButtons[5].input - PAD 5 - 0x97 - 0x3C - - - - - - [Sampler6] - DJCi500.deckB.samplerButtons[6].input - PAD 6 - 0x97 - 0x3D - - - - - - [Sampler7] - DJCi500.deckB.samplerButtons[7].input - PAD 7 - 0x97 - 0x3E - - - - - - [Sampler8] - DJCi500.deckB.samplerButtons[8].input - PAD 8 - 0x97 - 0x3F - - - - - - - - - [Channel2] - DJCi500.deckB.pitchUpSemiTone.input - Pitch up - semitone - 0x97 - 0x42 - - - - - - [Channel2] - DJCi500.deckB.pitchDownSemiTone.input - Pitch down - semitone - 0x97 - 0x41 - - - - - - [Channel2] - DJCi500.deckB.pitchUpTone.input - Pitch up - tone - 0x97 - 0x43 - - - - - - [Channel2] - DJCi500.deckB.pitchDownTone.input - Pitch down - tone - 0x97 - 0x40 - - - - - - [Channel2] - DJCi500.deckB.pitchSliderIncrease.input - Pitch slider increase resolution - 0x97 - 0x46 - - - - - - [Channel2] - DJCi500.deckB.pitchSliderDecrease.input - Pitch slider Decrease resolution - 0x97 - 0x45 - - - - - - [Channel2] - DJCi500.deckB.pitchSliderReset.input - Pitch slider Reset resolution - 0x97 - 0x44 - - - - - - - - [Channel2] - DJCi500.deckB.rollButtons[1].input - Loop 1/8 Beat (Pad 1) - 0x97 - 0x50 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[2].input - Loop 1/4 Beat (Pad 2) - 0x97 - 0x51 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[3].input - Loop 1/2 Beat (Pad 3) - 0x97 - 0x52 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[4].input - Loop 1 Beat (Pad 4) - 0x97 - 0x53 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[5].input - Loop 2 Beat (Pad 5) - 0x97 - 0x54 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[6].input - Loop 2 Beat (Pad 6) - 0x97 - 0x55 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[7].input - Loop 8 Beat (Pad 7) - 0x97 - 0x56 - - - - - - [Channel2] - DJCi500.deckB.rollButtons[8].input - Loop 2 Beat (Pad 8) - 0x97 - 0x57 - - - - - - - - [Channel2] - DJCi500.deckB.effectButtons[1].input - PAD 1 - 0x97 - 0x60 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[2].input - PAD 2 - 0x97 - 0x61 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[3].input - PAD 3 - 0x97 - 0x62 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[4].input - PAD 4 - 0x97 - 0x63 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[5].input - PAD 5 - 0x97 - 0x64 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[6].input - PAD 6 - 0x97 - 0x65 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[7].input - PAD 7 - 0x97 - 0x66 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[8].input - PAD 8 - 0x97 - 0x67 - - - - - - - - [Channel2] - DJCi500.deckB.effectButtons[1].input - PAD 1 - 0x97 - 0x68 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[2].input - PAD 2 - 0x97 - 0x69 - - - - - - [Channel2] - DJCi500.deckB.effectButtons[3].input - PAD 3 - 0x97 - 0x6A - - - - - - [Channel2] - DJCi500.deckB.effectButtons[4].input - PAD 4 - 0x97 - 0x6B - - - - - - [Channel2] - DJCi500.deckB.effectButtons[5].input - PAD 5 - 0x97 - 0x6C - - - - - - [Channel2] - DJCi500.deckB.effectButtons[6].input - PAD 6 - 0x97 - 0x6D - - - - - - [Channel2] - DJCi500.deckB.effectButtons[7].input - PAD 7 - 0x97 - 0x6E - - - - - - [Channel2] - DJCi500.deckB.effectButtons[8].input - PAD 8 - 0x97 - 0x6F - - - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[1].input - Beat jump 1 backward - 0x97 - 0x70 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[2].input - Beat jump 1 forward - 0x97 - 0x71 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[3].input - Beat jump 2 backward - 0x97 - 0x72 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[4].input - Beat jump 2 forward - 0x97 - 0x73 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[5].input - Beat jump 4 backward - 0x97 - 0x74 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[6].input - Beat jump 4 forward - 0x97 - 0x75 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[7].input - Beat jump 8 backward - 0x97 - 0x76 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[8].input - Beat jump 8 forward - 0x97 - 0x77 - - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[1].input - Beat jump 16 backward - 0x97 - 0x78 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[2].input - Beat jump 16 forward - 0x97 - 0x79 - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[3].input - Beat jump 32 backward - 0x97 - 0x7A - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[4].input - Beat jump 32 forward - 0x97 - 0x7B - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[5].input - Beat jump 64 backward - 0x97 - 0x7C - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[6].input - Beat jump 64 forward - 0x97 - 0x7D - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[7].input - Beat jump 128 backward - 0x97 - 0x7E - - - - - - [Channel1] - DJCi500.deckB.beatJumpButtons[8].input - Beat jump 128 forward - 0x97 - 0x7F - - - - - - - - - - - [Master] - DJCi500.crossfader - Crossfader - 0xB0 - 0x00 - - - - - - - [Library] - DJCi500.moveLibrary - Move Vertical (Browser Knob) - 0xB0 - 0x01 - - - - - - [Library] - MoveHorizontal - Move Horizontal (Browser Knob) - 0xB3 - 0x01 - - - - - - - - - - [Channel1] - DJCi500.deckA.volume.inputMSB - Volume Deck A - 0xB1 - 0x00 - - - - - - [Channel1] - DJCi500.deckA.volume.inputLSB - Volume Deck A - 0xB1 - 0x20 - - - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[1].inputMSB - EQ LOW Deck A - 0xB1 - 0x02 - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[1].inputLSB - EQ LOW Deck A - 0xB1 - 0x22 - - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[2].inputMSB - EQ MID Deck A - 0xB1 - 0x03 - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[2].inputLSB - EQ MID Deck A - 0xB1 - 0x23 - - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[3].inputMSB - EQ HIGH Deck A - 0xB1 - 0x04 - - - - - - [EqualizerRack1_[Channel1]_Effect1] - DJCi500.deckA.eqKnob[3].inputLSB - EQ HIGH Deck A - 0xB1 - 0x24 - - - - - - - [Channel1] - DJCi500.deckA.gainKnob.inputMSB - Gain Deck A - 0xB1 - 0x05 - - - - - - [Channel1] - DJCi500.deckA.gainKnob.inputLSB - Gain Deck A - 0xB1 - 0x25 - - - - - - - [Channel1] - DJCi500.deckA.filterKnob.input - Filter Deck A - 0xB1 - 0x01 - - - - - - - [Channel1] - DJCi500.deckA.pitchFader.inputMSB - 0xB1 - 0x08 - - - - - - [Channel1] - DJCi500.deckA.pitchFader.inputLSB - 0xB1 - 0x28 - - - - - - - [Channel1] - DJCi500.deckA.jogWheel.inputTouch - Jog Wheel Touch Deck A - 0x91 - 0x08 - - - - - - [Channel1] - DJCi500.deckA.jogWheel.inputTouch - Jog Wheel Touch Deck A - 0xB1 - 0x0C - - - - - - [Channel1] - DJCi500.deckA.jogWheel.inputWheel - Scratch Deck A (Jog-Wheel) - 0xB1 - 0x0A - - - - - - [Channel1] - DJCi500.deckA.jogWheel.inputWheel - Pitch Bend Deck A (Jog-Wheel) - 0xB1 - 0x09 - - - - - - - [Channel1] - DJCi500.deckA.jogWheel.inputTouch - Jog Wheel Touch Deck A - 0x94 - 0x08 - - - - - - [Channel1] - DJCi500.deckA.jogWheelShift.inputTouch - Jog Wheel Shift Touch Deck A - 0xB4 - 0x0C - - - - - - [Channel1] - DJCi500.deckA.jogWheelShift.inputWheel - Scratch Deck A (Jog-Wheel) - 0xB4 - 0x0A - - - - - - [Channel1] - DJCi500.deckA.jogWheelShift.inputWheel - Pitch Bend Deck A (Jog-Wheel) - 0xB4 - 0x09 - - - - - - - - - [Channel2] - DJCi500.deckB.volume.inputMSB - Volume Deck B - 0xB2 - 0x00 - - - - - - [Channel2] - DJCi500.deckB.volume.inputLSB - Volume Deck B - 0xB2 - 0x20 - - - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[1].inputMSB - EQ LOW Deck B - 0xB2 - 0x02 - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[1].inputLSB - EQ LOW Deck B - 0xB2 - 0x22 - - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[2].inputMSB - EQ MID Deck B - 0xB2 - 0x03 - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[2].inputLSB - EQ MID Deck B - 0xB2 - 0x23 - - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[3].inputMSB - EQ HIGH Deck B - 0xB2 - 0x04 - - - - - - [EqualizerRack1_[Channel2]_Effect1] - DJCi500.deckB.eqKnob[3].inputLSB - EQ HIGH Deck B - 0xB2 - 0x24 - - - - - - - [Channel2] - DJCi500.deckB.gainKnob.inputMSB - Gain Deck A - 0xB2 - 0x05 - - - - - - [Channel2] - DJCi500.deckB.gainKnob.inputLSB - Gain Deck A - 0xB2 - 0x25 - - - - - - - [Channel2] - DJCi500.deckB.filterKnob.input - Filter Deck B - 0xB2 - 0x01 - - - - - - - [Channel2] - DJCi500.deckB.pitchFader.inputMSB - 0xB2 - 0x08 - - - - - - [Channel2] - DJCi500.deckB.pitchFader.inputLSB - 0xB2 - 0x28 - - - - - - - [Channel2] - DJCi500.deckB.jogWheel.inputTouch - Jog Wheel Touch Deck B - 0x92 - 0x08 - - - - - - [Channel2] - DJCi500.deckB.jogWheel.inputTouch - Jog Wheel Touch Deck B - 0xB2 - 0x0C - - - - - - [Channel2] - DJCi500.deckB.jogWheel.inputWheel - Scratch Deck B (Jog-Wheel) - 0xB2 - 0x0A - - - - - - [Channel2] - DJCi500.deckB.jogWheel.inputWheel - Pitch Bend Deck B (Jog-Wheel) - 0xB2 - 0x09 - - - - - - - [Channel2] - DJCi500.deckB.jogWheel.inputTouch - Jog Wheel Touch Deck B - 0x95 - 0x08 - - - - - - [Channel2] - DJCi500.deckB.jogWheelShift.inputTouch - Jog Wheel Shift Touch Deck B - 0xB5 - 0x0C - - - - - - [Channel2] - DJCi500.deckB.jogWheelShift.inputWheel - Scratch Deck B (Jog-Wheel) - 0xB5 - 0x0A - - - - - - [Channel2] - DJCi500.deckB.jogWheelShift.inputWheel - Pitch Bend Deck B (Jog-Wheel) - 0xB5 - 0x09 - - - - - - - - - - [Channel] - DJCi500.deckSelector - Activate Deck1 (FX1 button) - 0x90 - 0x14 - - - - - - - [Channel] - DJCi500.deckSelector - Activate Deck2 (FX2 button) - 0x90 - 0x15 - - - - - - - [Channel] - DJCi500.deckSelector - Activate Deck3 (FX3 button) - 0x90 - 0x16 - - - - - - - [Channel] - DJCi500.deckSelector - Activate Deck4 (FX4 button) - 0x90 - 0x17 - - - - - - - - - - - - - [Library] - MoveFocus - Browser LED (Green) - 0.5 - 1 - 0x90 - 0x05 - 0x10 - 0x05 - - - [Skin] - show_maximized_library - Browser LED (BLUE) - 0.5 - 1 - 0x90 - 0x05 - 0x05 - 0x10 - - - - [AutoDJ] - enabled - Auto DJ On - 0.5 - 1 - 0x90 - 0x03 - 0x7f - 0x0 - - - - + + + + Hercules DJControl Inpulse 500 1d + DJ Phatso for Hercules Technical Support + MIDI Preset for Hercules DJControl Inpulse 500 + https://www.mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 + https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 + + + + + + + + + + + + + + [Library] + MoveFocus + Browser button + 0x90 + 0x00 + + + + + + + + [AutoDJ] + enabled + AutoDJ On/Off + 0x90 + 0x03 + + + + + + [Mixer Profile] + DJCi500.crossfaderEnable + CROSS FADER ENABLE + 0x90 + 0x18 + + + + + + + [Mixer Profile] + DJCi500.crossfaderSetCurve + CROSS FADER SET CURVE + 0xB0 + 0x0B + + + + + + + + + + [Channel1] + DJCi500.deckA.playButton.input + Play button + 0x91 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.cueButton.input + Cue button + 0x91 + 0x06 + + + + + + + [Channel1] + DJCi500.deckA.syncButton.input + Sync button + 0x91 + 0x05 + + + + + + + [Channel1] + DJCi500.deckA.pflButton.input + PFL button + 0x91 + 0x0C + + + + + + + [Channel1] + DJCi500.deckA.loadButton.input + LOAD A button + 0x91 + 0x0D + + + + + + + [Channel1] + DJCi500.deckA.loadButton.input + LOAD A button + 0x94 + 0x0D + + + + + + + [Channel1] + DJCi500.deckA.shiftButton.input + Shift Deck A button + 0x91 + 0x04 + + + + + + + [Channel1] + DJCi500.deckA.slipButton.input + SLIP button + 0x91 + 0x01 + + + + + + + [Channel1] + DJCi500.deckA.quantButton.input + Quantize button - Deck 1 + 0x91 + 0x02 + + + + + + + [Channel1] + DJCi500.deckA.quantButton.input + Keylock button (shift+quant) - Deck 1 + 0x94 + 0x02 + + + + + + + + [Master] + DJCi500.deckA.vinylButton.input + Vinyl Deck A + 0x91 + 0x03 + + + + + + + + [Channel1] + DJCi500.deckA.vinylButton.input + Shift + Vinyl Deck A + 0x94 + 0x03 + + + + + + + + [Channel1] + DJCi500.deckA.loopInButton.input + Loop In button + 0x91 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.loopOutButton.input + Loop Out button + 0x91 + 0x0A + + + + + + + [Channel1] + DJCi500.deckA.loopInButton.input + S+Loop In button (loop in goto) + 0x94 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.loopOutButton.input + S+Loop Out button (loop out goto) + 0x94 + 0x0A + + + + + + + + [Channel1] + DJCi500.deckA.loopEncoderPush.input + Loop Encoder Push button Deck A Reloop toggle + 0x91 + 0x2C + + + + + + + [Channel1] + DJCi500.deckA.loopEncoderPush.input + Loop Encoder Push button Deck A 4 Beat loop activate + 0x94 + 0x2C + + + + + + + + [Channel1] + DJCi500.deckA.loopEncoder.input + Loop Halve/Double (Loop Knob Deck A) + 0xB1 + 0x0E + + + + + + + + + + [Channel2] + DJCi500.deckB.playButton.input + Play button + 0x92 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.cueButton.input + Cue button + 0x92 + 0x06 + + + + + + + [Channel2] + DJCi500.deckB.syncButton.input + Sync button + 0x92 + 0x05 + + + + + + + [Channel2] + DJCi500.deckB.pflButton.input + PFL button + 0x92 + 0x0C + + + + + + + [Channel2] + DJCi500.deckB.loadButton.input + LOAD B button + 0x92 + 0x0D + + + + + + + [Channel2] + DJCi500.deckB.loadButton.input + LOAD B button + 0x95 + 0x0D + + + + + + + [Channel1] + DJCi500.deckB.shiftButton.input + Shift Deck A button + 0x92 + 0x04 + + + + + + + [Channel2] + DJCi500.deckB.slipButton.input + SLIP button + 0x92 + 0x01 + + + + + + + [Channel2] + DJCi500.deckB.quantButton.input + Quantize button - Deck 2 + 0x92 + 0x02 + + + + + + + [Channel2] + DJCi500.deckB.quantButton.input + Keylock button (shift+quant) - Deck 2 + 0x95 + 0x02 + + + + + + + + [Master] + DJCi500.deckB.vinylButton.input + Vinyl Deck B + 0x92 + 0x03 + + + + + + + + [Channel2] + DJCi500.deckB.vinylButton.input + Shift + Vinyl Deck B + 0x95 + 0x03 + + + + + + + + [Channel2] + DJCi500.deckB.loopInButton.input + Loop In button + 0x92 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.loopOutButton.input + Loop Out button + 0x92 + 0x0A + + + + + + + [Channel2] + DJCi500.deckB.loopInButton.input + Loop In button (Loop In Goto) + 0x95 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.loopOutButton.input + Loop Out button (loop out goto) + 0x95 + 0x0A + + + + + + + + [Channel2] + DJCi500.deckB.loopEncoderPush.input + Loop Encoder Push button Deck B (reloop toggle) + 0x92 + 0x2C + + + + + + + [Channel2] + DJCi500.deckB.loopEncoderPush.input + Loop Encoder Push button Deck B (beatloop 4 activated) + 0x95 + 0x2C + + + + + + + + + [Channel2] + DJCi500.deckB.loopEncoder.input + Loop Halve/Double (Loop Knob Deck B) + 0xB2 + 0x0E + + + + + + + + + + [Skin] + show_maximized_library + Browser button - Maximize Library view + 0x93 + 0x00 + + + + + + + + + + [Channel1] + DJCi500.deckA.playButton.input + SHIFT + Play: Play Stutter + 0x94 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.cueButton.input + SHIFT + Cue: REWIND to beginning + 0x94 + 0x06 + + + + + + + [Channel1] + DJCi500.deckA.syncButton.input + SHIFT + Sync: Match key + 0x94 + 0x05 + + + + + + + + + [Channel2] + DJCi500.deckB.playButton.input + SHIFT + Play: Play Stutter + 0x95 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.cueButton.input + SHIFT + Cue: REWIND to beginning + 0x95 + 0x06 + + + + + + + [Channel2] + DJCi500.deckB.syncButton.input + SHIFT + Sync: Sync key + 0x95 + 0x05 + + + + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[1].input + PAD select + 0x91 + 0x0F + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[2].input + PAD select + 0x91 + 0x10 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[3].input + PAD select + 0x91 + 0x11 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[4].input + PAD select + 0x91 + 0x12 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[5].input + PAD select + 0x91 + 0x13 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[6].input + PAD select + 0x91 + 0x14 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[7].input + PAD select + 0x91 + 0x15 + + + + + + [Channel1] + DJCi500.deckA.padSelectButtons[8].input + PAD select + 0x91 + 0x16 + + + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[1].input + PAD 1 + 0x96 + 0x00 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[2].input + PAD 2 + 0x96 + 0x01 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[3].input + PAD 3 + 0x96 + 0x02 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[4].input + PAD 4 + 0x96 + 0x03 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[5].input + PAD 5 + 0x96 + 0x04 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[6].input + PAD 6 + 0x96 + 0x05 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[7].input + PAD 7 + 0x96 + 0x06 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[8].input + PAD 8 + 0x96 + 0x07 + + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[1].input + PAD 1 + L-Shift + 0x96 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[2].input + PAD 2 + L-Shift + 0x96 + 0x09 + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[3].input + PAD 3 + L-Shift + 0x96 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[4].input + PAD 4 + L-Shift + 0x96 + 0x0B + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[5].input + PAD 5 + L-Shift + 0x96 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[6].input + PAD 6 + L-Shift + 0x96 + 0x0D + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[7].input + PAD 7 + L-Shift + 0x96 + 0x0E + + + + + + [Channel1] + DJCi500.deckA.hotcueButtons[8].input + PAD 8 + L-Shift + 0x96 + 0x0F + + + + + + + + [Channel1] + DJCi500.deckA.loopButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x96 + 0x10 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x96 + 0x11 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x96 + 0x12 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[4].input + Loop 1 Beat (Pad 4) + 0x96 + 0x13 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[5].input + Loop 2 Beat (Pad 5) + 0x96 + 0x14 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[6].input + Loop 4 Beat (Pad 6) + 0x96 + 0x15 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[7].input + Loop 8 Beat (Pad 7) + 0x96 + 0x16 + + + + + + [Channel1] + DJCi500.deckA.loopButtons[8].input + Loop 16 Beat (Pad 8) + 0x96 + 0x17 + + + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[1].input + Loop 3/4 Beat (Pad 1) + 0x96 + 0x18 + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[2].input + Loop 5/4 Beat (Pad 2) + 0x96 + 0x19 + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[3].input + Loop 6/4 Beat (Pad 3) + 0x96 + 0x1A + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[4].input + Loop 7/4 Beat (Pad 4) + 0x96 + 0x1B + + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[5].input + Loop 32 Beat (Pad 5) + 0x96 + 0x1C + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[6].input + Loop 64 Beat (Pad 6) + 0x96 + 0x1D + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[7].input + Loop 128 Beat (Pad 7) + 0x96 + 0x1E + + + + + + [Channel1] + DJCi500.deckA.loopShiftButtons[8].input + Loop 256 Beat (Pad 8) + 0x96 + 0x1F + + + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[1].input + PAD 1 + 0x96 + 0x20 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[2].input + PAD 2 + 0x96 + 0x21 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[3].input + PAD 3 + 0x96 + 0x22 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[4].input + PAD 4 + 0x96 + 0x23 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[5].input + PAD 5 + 0x96 + 0x24 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[6].input + PAD 6 + 0x96 + 0x25 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[7].input + PAD 7 + 0x96 + 0x26 + + + + + + [Channel1] + DJCi500.deckA.slicerButtons[8].input + PAD 8 + 0x96 + 0x27 + + + + + + + + [Sampler1] + DJCi500.deckA.samplerButtons[1].input + PAD 1 + 0x96 + 0x30 + + + + + + [Sampler2] + DJCi500.deckA.samplerButtons[2].input + PAD 2 + 0x96 + 0x31 + + + + + + [Sampler3] + DJCi500.deckA.samplerButtons[3].input + PAD 3 + 0x96 + 0x32 + + + + + + [Sampler4] + DJCi500.deckA.samplerButtons[4].input + PAD 4 + 0x96 + 0x33 + + + + + + [Sampler5] + DJCi500.deckA.samplerButtons[5].input + PAD 5 + 0x96 + 0x34 + + + + + + [Sampler6] + DJCi500.deckA.samplerButtons[6].input + PAD 6 + 0x96 + 0x35 + + + + + + [Sampler7] + DJCi500.deckA.samplerButtons[7].input + PAD 7 + 0x96 + 0x36 + + + + + + [Sampler8] + DJCi500.deckA.samplerButtons[8].input + PAD 8 + 0x96 + 0x37 + + + + + + + + [Sampler1] + DJCi500.deckA.samplerButtons[1].input + PAD 1 + 0x96 + 0x38 + + + + + + [Sampler2] + DJCi500.deckA.samplerButtons[2].input + PAD 2 + 0x96 + 0x39 + + + + + + [Sampler3] + DJCi500.deckA.samplerButtons[3].input + PAD 3 + 0x96 + 0x3A + + + + + + [Sampler4] + DJCi500.deckA.samplerButtons[4].input + PAD 4 + 0x96 + 0x3B + + + + + + [Sampler5] + DJCi500.deckA.samplerButtons[5].input + PAD 5 + 0x96 + 0x3C + + + + + + [Sampler6] + DJCi500.deckA.samplerButtons[6].input + PAD 6 + 0x96 + 0x3D + + + + + + [Sampler7] + DJCi500.deckA.samplerButtons[7].input + PAD 7 + 0x96 + 0x3E + + + + + + [Sampler8] + DJCi500.deckA.samplerButtons[8].input + PAD 8 + 0x96 + 0x3F + + + + + + + + [Channel1] + DJCi500.deckA.pitchDownTone.input + Pitch down - tone + 0x96 + 0x40 + + + + + + [Channel1] + DJCi500.deckA.pitchDownSemiTone.input + Pitch down - semitone + 0x96 + 0x41 + + + + + + [Channel1] + DJCi500.deckA.pitchUpSemiTone.input + Pitch up - semitone + 0x96 + 0x42 + + + + + + [Channel1] + DJCi500.deckA.pitchUpTone.input + Pitch up - tone + 0x96 + 0x43 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderIncrease.input + Pitch slider increase resolution + 0x96 + 0x46 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderDecrease.input + Pitch slider Decrease resolution + 0x96 + 0x45 + + + + + + [Channel1] + DJCi500.deckA.pitchSliderReset.input + Pitch slider Reset resolution + 0x96 + 0x44 + + + + + + + + [Channel1] + DJCi500.deckA.rollButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x96 + 0x50 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x96 + 0x51 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x96 + 0x52 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[4].input + Loop 1 Beat (Pad 4) + 0x96 + 0x53 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[5].input + Loop 2 Beat (Pad 5) + 0x96 + 0x54 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[6].input + Loop 2 Beat (Pad 6) + 0x96 + 0x55 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[7].input + Loop 8 Beat (Pad 7) + 0x96 + 0x56 + + + + + + [Channel1] + DJCi500.deckA.rollButtons[8].input + Loop 2 Beat (Pad 8) + 0x96 + 0x57 + + + + + + + + [Channel1] + DJCi500.deckA.effectButtons[1].input + PAD 1 + 0x96 + 0x60 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[2].input + PAD 2 + 0x96 + 0x61 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[3].input + PAD 3 + 0x96 + 0x62 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[4].input + PAD 4 + 0x96 + 0x63 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[5].input + PAD 5 + 0x96 + 0x64 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[6].input + PAD 6 + 0x96 + 0x65 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[7].input + PAD 7 + 0x96 + 0x66 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[8].input + PAD 8 + 0x96 + 0x67 + + + + + + + + [Channel1] + DJCi500.deckA.effectButtons[1].input + PAD 1 + 0x96 + 0x68 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[2].input + PAD 2 + 0x96 + 0x69 + + + + + + [Channel1] + DJCi500.deckA.effectButtons[3].input + PAD 3 + 0x96 + 0x6A + + + + + + [Channel1] + DJCi500.deckA.effectButtons[4].input + PAD 4 + 0x96 + 0x6B + + + + + + [Channel1] + DJCi500.deckA.effectButtons[5].input + PAD 5 + 0x96 + 0x6C + + + + + + [Channel1] + DJCi500.deckA.effectButtons[6].input + PAD 6 + 0x96 + 0x6D + + + + + + [Channel1] + DJCi500.deckA.effectButtons[7].input + PAD 7 + 0x96 + 0x6E + + + + + + [Channel1] + DJCi500.deckA.effectButtons[8].input + PAD 8 + 0x96 + 0x6F + + + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[1].input + Beat jump 1 backward + 0x96 + 0x70 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[2].input + Beat jump 1 forward + 0x96 + 0x71 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[3].input + Beat jump 2 backward + 0x96 + 0x72 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[4].input + Beat jump 2 forward + 0x96 + 0x73 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[5].input + Beat jump 4 backward + 0x96 + 0x74 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[6].input + Beat jump 4 forward + 0x96 + 0x75 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[7].input + Beat jump 8 backward + 0x96 + 0x76 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[8].input + Beat jump 8 forward + 0x96 + 0x77 + + + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[1].input + Beat jump 16 backward + 0x96 + 0x78 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[2].input + Beat jump 16 forward + 0x96 + 0x79 + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[3].input + Beat jump 32 backward + 0x96 + 0x7A + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[4].input + Beat jump 32 forward + 0x96 + 0x7B + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[5].input + Beat jump 64 backward + 0x96 + 0x7C + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[6].input + Beat jump 64 forward + 0x96 + 0x7D + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[7].input + Beat jump 128 backward + 0x96 + 0x7E + + + + + + [Channel1] + DJCi500.deckA.beatJumpButtons[8].input + Beat jump 128 forward + 0x96 + 0x7F + + + + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[1].input + PAD select + 0x92 + 0x0F + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[2].input + PAD select + 0x92 + 0x10 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[3].input + PAD select + 0x92 + 0x11 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[4].input + PAD select + 0x92 + 0x12 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[5].input + PAD select + 0x92 + 0x13 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[6].input + PAD select + 0x92 + 0x14 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[7].input + PAD select + 0x92 + 0x15 + + + + + + [Channel2] + DJCi500.deckB.padSelectButtons[8].input + PAD select + 0x92 + 0x16 + + + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[1].input + PAD 1 + 0x97 + 0x00 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[2].input + PAD 2 + 0x97 + 0x01 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[3].input + PAD 3 + 0x97 + 0x02 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[4].input + PAD 4 + 0x97 + 0x03 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[5].input + PAD 5 + 0x97 + 0x04 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[6].input + PAD 6 + 0x97 + 0x05 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[7].input + PAD 7 + 0x97 + 0x06 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[8].input + PAD 8 + 0x97 + 0x07 + + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[1].input + PAD 1 + R-Shift + 0x97 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[2].input + PAD 2 + R-Shift + 0x97 + 0x09 + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[3].input + PAD 3 + R-Shift + 0x97 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[4].input + PAD 4 + R-Shift + 0x97 + 0x0B + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[5].input + PAD 5 + R-Shift + 0x97 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[6].input + PAD 6 + R-Shift + 0x97 + 0x0D + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[7].input + PAD 7 + R-Shift + 0x97 + 0x0E + + + + + + [Channel2] + DJCi500.deckB.hotcueButtons[8].input + PAD 8 + R-Shift + 0x97 + 0x0F + + + + + + + [Channel2] + DJCi500.deckB.loopButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x97 + 0x10 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x97 + 0x11 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x97 + 0x12 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[4].input + Loop 1 Beat (Pad 4) + 0x97 + 0x13 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[5].input + Loop 2 Beat (Pad 5) + 0x97 + 0x14 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[6].input + Loop 4 Beat (Pad 6) + 0x97 + 0x15 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[7].input + Loop 8 Beat (Pad 7) + 0x97 + 0x16 + + + + + + [Channel2] + DJCi500.deckB.loopButtons[8].input + Loop 16 Beat (Pad 8) + 0x97 + 0x17 + + + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[1].input + Loop 3/4 Beat (Pad 1) + 0x97 + 0x18 + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[2].input + Loop 5/4 Beat (Pad 2) + 0x97 + 0x19 + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[3].input + Loop 6/4 Beat (Pad 3) + 0x97 + 0x1A + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[4].input + Loop 7/4 Beat (Pad 4) + 0x97 + 0x1B + + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[5].input + Loop 32 Beat (Pad 5) + 0x97 + 0x1C + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[6].input + Loop 64 Beat (Pad 6) + 0x97 + 0x1D + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[7].input + Loop 128 Beat (Pad 7) + 0x97 + 0x1E + + + + + + [Channel2] + DJCi500.deckB.loopShiftButtons[8].input + Loop 256 Beat (Pad 8) + 0x97 + 0x1F + + + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[1].input + PAD 1 + 0x97 + 0x20 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[2].input + PAD 2 + 0x97 + 0x21 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[3].input + PAD 3 + 0x97 + 0x22 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[4].input + PAD 4 + 0x97 + 0x23 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[5].input + PAD 5 + 0x97 + 0x24 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[6].input + PAD 6 + 0x97 + 0x25 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[7].input + PAD 7 + 0x97 + 0x26 + + + + + + [Channel2] + DJCi500.deckB.slicerButtons[8].input + PAD 8 + 0x97 + 0x27 + + + + + + + + [Sampler1] + DJCi500.deckB.samplerButtons[1].input + PAD 1 + 0x97 + 0x30 + + + + + + [Sampler2] + DJCi500.deckB.samplerButtons[2].input + PAD 2 + 0x97 + 0x31 + + + + + + [Sampler3] + DJCi500.deckB.samplerButtons[3].input + PAD 3 + 0x97 + 0x32 + + + + + + [Sampler4] + DJCi500.deckB.samplerButtons[4].input + PAD 4 + 0x97 + 0x33 + + + + + + [Sampler5] + DJCi500.deckB.samplerButtons[5].input + PAD 5 + 0x97 + 0x34 + + + + + + [Sampler6] + DJCi500.deckB.samplerButtons[6].input + PAD 6 + 0x97 + 0x35 + + + + + + [Sampler7] + DJCi500.deckB.samplerButtons[7].input + PAD 7 + 0x97 + 0x36 + + + + + + [Sampler8] + DJCi500.deckB.samplerButtons[8].input + PAD 8 + 0x97 + 0x37 + + + + + + + + [Sampler1] + DJCi500.deckB.samplerButtons[1].input + PAD 1 + 0x97 + 0x38 + + + + + + [Sampler2] + DJCi500.deckB.samplerButtons[2].input + PAD 2 + 0x97 + 0x39 + + + + + + [Sampler3] + DJCi500.deckB.samplerButtons[3].input + PAD 3 + 0x97 + 0x3A + + + + + + [Sampler4] + DJCi500.deckB.samplerButtons[4].input + PAD 4 + 0x97 + 0x3B + + + + + + [Sampler5] + DJCi500.deckB.samplerButtons[5].input + PAD 5 + 0x97 + 0x3C + + + + + + [Sampler6] + DJCi500.deckB.samplerButtons[6].input + PAD 6 + 0x97 + 0x3D + + + + + + [Sampler7] + DJCi500.deckB.samplerButtons[7].input + PAD 7 + 0x97 + 0x3E + + + + + + [Sampler8] + DJCi500.deckB.samplerButtons[8].input + PAD 8 + 0x97 + 0x3F + + + + + + + + + [Channel2] + DJCi500.deckB.pitchUpSemiTone.input + Pitch up - semitone + 0x97 + 0x42 + + + + + + [Channel2] + DJCi500.deckB.pitchDownSemiTone.input + Pitch down - semitone + 0x97 + 0x41 + + + + + + [Channel2] + DJCi500.deckB.pitchUpTone.input + Pitch up - tone + 0x97 + 0x43 + + + + + + [Channel2] + DJCi500.deckB.pitchDownTone.input + Pitch down - tone + 0x97 + 0x40 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderIncrease.input + Pitch slider increase resolution + 0x97 + 0x46 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderDecrease.input + Pitch slider Decrease resolution + 0x97 + 0x45 + + + + + + [Channel2] + DJCi500.deckB.pitchSliderReset.input + Pitch slider Reset resolution + 0x97 + 0x44 + + + + + + + + [Channel2] + DJCi500.deckB.rollButtons[1].input + Loop 1/8 Beat (Pad 1) + 0x97 + 0x50 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[2].input + Loop 1/4 Beat (Pad 2) + 0x97 + 0x51 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[3].input + Loop 1/2 Beat (Pad 3) + 0x97 + 0x52 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[4].input + Loop 1 Beat (Pad 4) + 0x97 + 0x53 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[5].input + Loop 2 Beat (Pad 5) + 0x97 + 0x54 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[6].input + Loop 2 Beat (Pad 6) + 0x97 + 0x55 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[7].input + Loop 8 Beat (Pad 7) + 0x97 + 0x56 + + + + + + [Channel2] + DJCi500.deckB.rollButtons[8].input + Loop 2 Beat (Pad 8) + 0x97 + 0x57 + + + + + + + + [Channel2] + DJCi500.deckB.effectButtons[1].input + PAD 1 + 0x97 + 0x60 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[2].input + PAD 2 + 0x97 + 0x61 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[3].input + PAD 3 + 0x97 + 0x62 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[4].input + PAD 4 + 0x97 + 0x63 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[5].input + PAD 5 + 0x97 + 0x64 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[6].input + PAD 6 + 0x97 + 0x65 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[7].input + PAD 7 + 0x97 + 0x66 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[8].input + PAD 8 + 0x97 + 0x67 + + + + + + + + [Channel2] + DJCi500.deckB.effectButtons[1].input + PAD 1 + 0x97 + 0x68 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[2].input + PAD 2 + 0x97 + 0x69 + + + + + + [Channel2] + DJCi500.deckB.effectButtons[3].input + PAD 3 + 0x97 + 0x6A + + + + + + [Channel2] + DJCi500.deckB.effectButtons[4].input + PAD 4 + 0x97 + 0x6B + + + + + + [Channel2] + DJCi500.deckB.effectButtons[5].input + PAD 5 + 0x97 + 0x6C + + + + + + [Channel2] + DJCi500.deckB.effectButtons[6].input + PAD 6 + 0x97 + 0x6D + + + + + + [Channel2] + DJCi500.deckB.effectButtons[7].input + PAD 7 + 0x97 + 0x6E + + + + + + [Channel2] + DJCi500.deckB.effectButtons[8].input + PAD 8 + 0x97 + 0x6F + + + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[1].input + Beat jump 1 backward + 0x97 + 0x70 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[2].input + Beat jump 1 forward + 0x97 + 0x71 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[3].input + Beat jump 2 backward + 0x97 + 0x72 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[4].input + Beat jump 2 forward + 0x97 + 0x73 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[5].input + Beat jump 4 backward + 0x97 + 0x74 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[6].input + Beat jump 4 forward + 0x97 + 0x75 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[7].input + Beat jump 8 backward + 0x97 + 0x76 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[8].input + Beat jump 8 forward + 0x97 + 0x77 + + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[1].input + Beat jump 16 backward + 0x97 + 0x78 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[2].input + Beat jump 16 forward + 0x97 + 0x79 + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[3].input + Beat jump 32 backward + 0x97 + 0x7A + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[4].input + Beat jump 32 forward + 0x97 + 0x7B + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[5].input + Beat jump 64 backward + 0x97 + 0x7C + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[6].input + Beat jump 64 forward + 0x97 + 0x7D + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[7].input + Beat jump 128 backward + 0x97 + 0x7E + + + + + + [Channel1] + DJCi500.deckB.beatJumpButtons[8].input + Beat jump 128 forward + 0x97 + 0x7F + + + + + + + + + + + [Master] + DJCi500.crossfader + Crossfader + 0xB0 + 0x00 + + + + + + + [Library] + DJCi500.moveLibrary + Move Vertical (Browser Knob) + 0xB0 + 0x01 + + + + + + [Library] + MoveHorizontal + Move Horizontal (Browser Knob) + 0xB3 + 0x01 + + + + + + + + + + [Channel1] + DJCi500.deckA.volume.inputMSB + Volume Deck A + 0xB1 + 0x00 + + + + + + [Channel1] + DJCi500.deckA.volume.inputLSB + Volume Deck A + 0xB1 + 0x20 + + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[1].inputMSB + EQ LOW Deck A + 0xB1 + 0x02 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[1].inputLSB + EQ LOW Deck A + 0xB1 + 0x22 + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[2].inputMSB + EQ MID Deck A + 0xB1 + 0x03 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[2].inputLSB + EQ MID Deck A + 0xB1 + 0x23 + + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[3].inputMSB + EQ HIGH Deck A + 0xB1 + 0x04 + + + + + + [EqualizerRack1_[Channel1]_Effect1] + DJCi500.deckA.eqKnob[3].inputLSB + EQ HIGH Deck A + 0xB1 + 0x24 + + + + + + + [Channel1] + DJCi500.deckA.gainKnob.inputMSB + Gain Deck A + 0xB1 + 0x05 + + + + + + [Channel1] + DJCi500.deckA.gainKnob.inputLSB + Gain Deck A + 0xB1 + 0x25 + + + + + + + [Channel1] + DJCi500.deckA.filterKnob.input + Filter Deck A + 0xB1 + 0x01 + + + + + + + [Channel1] + DJCi500.deckA.pitchFader.inputMSB + 0xB1 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.pitchFader.inputLSB + 0xB1 + 0x28 + + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0x91 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0xB1 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputWheel + Scratch Deck A (Jog-Wheel) + 0xB1 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputWheel + Pitch Bend Deck A (Jog-Wheel) + 0xB1 + 0x09 + + + + + + + [Channel1] + DJCi500.deckA.jogWheel.inputTouch + Jog Wheel Touch Deck A + 0x94 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputTouch + Jog Wheel Shift Touch Deck A + 0xB4 + 0x0C + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputWheel + Scratch Deck A (Jog-Wheel) + 0xB4 + 0x0A + + + + + + [Channel1] + DJCi500.deckA.jogWheelShift.inputWheel + Pitch Bend Deck A (Jog-Wheel) + 0xB4 + 0x09 + + + + + + + + + [Channel2] + DJCi500.deckB.volume.inputMSB + Volume Deck B + 0xB2 + 0x00 + + + + + + [Channel2] + DJCi500.deckB.volume.inputLSB + Volume Deck B + 0xB2 + 0x20 + + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[1].inputMSB + EQ LOW Deck B + 0xB2 + 0x02 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[1].inputLSB + EQ LOW Deck B + 0xB2 + 0x22 + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[2].inputMSB + EQ MID Deck B + 0xB2 + 0x03 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[2].inputLSB + EQ MID Deck B + 0xB2 + 0x23 + + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[3].inputMSB + EQ HIGH Deck B + 0xB2 + 0x04 + + + + + + [EqualizerRack1_[Channel2]_Effect1] + DJCi500.deckB.eqKnob[3].inputLSB + EQ HIGH Deck B + 0xB2 + 0x24 + + + + + + + [Channel2] + DJCi500.deckB.gainKnob.inputMSB + Gain Deck A + 0xB2 + 0x05 + + + + + + [Channel2] + DJCi500.deckB.gainKnob.inputLSB + Gain Deck A + 0xB2 + 0x25 + + + + + + + [Channel2] + DJCi500.deckB.filterKnob.input + Filter Deck B + 0xB2 + 0x01 + + + + + + + [Channel2] + DJCi500.deckB.pitchFader.inputMSB + 0xB2 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.pitchFader.inputLSB + 0xB2 + 0x28 + + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0x92 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0xB2 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputWheel + Scratch Deck B (Jog-Wheel) + 0xB2 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputWheel + Pitch Bend Deck B (Jog-Wheel) + 0xB2 + 0x09 + + + + + + + [Channel2] + DJCi500.deckB.jogWheel.inputTouch + Jog Wheel Touch Deck B + 0x95 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputTouch + Jog Wheel Shift Touch Deck B + 0xB5 + 0x0C + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputWheel + Scratch Deck B (Jog-Wheel) + 0xB5 + 0x0A + + + + + + [Channel2] + DJCi500.deckB.jogWheelShift.inputWheel + Pitch Bend Deck B (Jog-Wheel) + 0xB5 + 0x09 + + + + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck1 (FX1 button) + 0x90 + 0x14 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck2 (FX2 button) + 0x90 + 0x15 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck3 (FX3 button) + 0x90 + 0x16 + + + + + + + [Channel] + DJCi500.deckSelector + Activate Deck4 (FX4 button) + 0x90 + 0x17 + + + + + + + + + + + + + [Library] + MoveFocus + Browser LED (Green) + 0.5 + 1 + 0x90 + 0x05 + 0x10 + 0x05 + + + [Skin] + show_maximized_library + Browser LED (BLUE) + 0.5 + 1 + 0x90 + 0x05 + 0x05 + 0x10 + + + + [AutoDJ] + enabled + Auto DJ On + 0.5 + 1 + 0x90 + 0x03 + 0x7f + 0x0 + + + + From 14cb213789d761c2d596c2138de6a5757f1342d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Tue, 25 Feb 2025 14:25:17 +0100 Subject: [PATCH 33/40] Fix the var stuff and jogWheel channels --- .../Hercules-DJControl-Inpulse-500-script.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index b43c0de74afc..da1094604b72 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -66,9 +66,7 @@ // * Add beat jump + SHIFT jumps // // **************************************************************************** - -// For some reason, if this is not var, the script errs -var DJCi500 = {}; +DJCi500 = {}; /////////////////////////////////////////////////////////////// // USER OPTIONS // @@ -457,13 +455,13 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { beta: (5/6)/128, rpm: 33 + 1/3, group: `[Channel${midiChannel}]`, - inputWheel: function(_channel, _control, value, _status, group) { + inputWheel: function(_channel, _control, value, _status, _group) { const deck = script.deckFromGroup(deckData.currentDeck); value = this.inValueScale(value); if (engine.isScratching(deck)) { engine.scratchTick(deck, value); } else { - engine.setValue(group, "jog", value); + engine.setValue(`[Channel${deck}]`, "jog", value); } }, inputTouch: function(_channel, _control, value, _status, _group) { @@ -488,13 +486,13 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { beta: (5/6)/128, rpm: 33 + 1/3, group: `[Channel${midiChannel}]`, - inputWheel: function(_channel, _control, value, _status, group) { + inputWheel: function(_channel, _control, value, _status, _group) { const deck = script.deckFromGroup(deckData.currentDeck); value = this.inValueScale(value) * 4; if (engine.isScratching(deck)) { engine.scratchTick(deck, value); } else { - engine.setValue(group, "jog", value); + engine.setValue(`[Channel${deck}]`, "jog", value); } }, inputTouch: function(channel, control, value, status, _group) { From f3556a28c1f3631f158745a2ae153ec6562ac462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Thu, 27 Feb 2025 15:12:16 +0100 Subject: [PATCH 34/40] fix: Comments and var with Eslint comment --- .../Hercules-DJControl-Inpulse-500-script.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 7b60300476bc..5ac57382c277 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -66,7 +66,9 @@ // * Add beat jump + SHIFT jumps // // **************************************************************************** -DJCi500 = {}; + +// esling-disable-next-line prefer-const +var DJCi500 = {}; /////////////////////////////////////////////////////////////// // USER OPTIONS // @@ -115,9 +117,8 @@ const pairColorsOff = [0x12, 0x12, 0x02, 0x02, 0x4C, 0x4C, 0x40, 0x40]; // SLICER // /////////////////////////////////////////////////////////////// DJCi500.selectedSlicerDomain = [8, 8, 8, 8]; // Length of the Slicer domain -//PioneerDDJSX.slicerDomains = [8, 16, 32, 64]; -// slicer storage: +// Slicer storage: DJCi500.slicerBeatsPassed = [0, 0, 0, 0]; DJCi500.slicerPreviousBeatsPassed = [0, 0, 0, 0]; DJCi500.slicerTimer = [false, false, false, false]; @@ -309,11 +310,11 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { unshift: function() { this.input = function(_channel, _control, value, _status, _group) { if (value === 0x7F) { - if (engine.getValue(deckData.currentDeck, "play_latched")) { //play_indicator play_latched + if (engine.getValue(deckData.currentDeck, "play_latched")) { const deck = script.deckFromGroup(deckData.currentDeck); if (deckData.slowPauseSetState[deck - 1]) { engine.brake(deck, - 1, //((status & 0xF0) !=== 0x80 && value > 0), + 1, 54); } else { script.toggleControl(deckData.currentDeck, "play"); @@ -449,8 +450,8 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { // TODO: Handle with less repeat the shift key for this this.jogWheel = new components.JogWheelBasic({ midi: [0xB0 + midiChannel, 0x0A], - deck: midiChannel, // whatever deck this jogwheel controls, in this case we ignore it - wheelResolution: 720, // how many ticks per revolution the jogwheel has + deck: midiChannel, // Whatever deck this jogwheel controls, in this case we ignore it + wheelResolution: 720, // How many ticks per revolution the jogwheel has alpha: 5/6, beta: (5/6)/128, rpm: 33 + 1/3, @@ -1482,7 +1483,7 @@ DJCi500.slicerButtonFunc = function(channel, control, value, status, group) { } // if value }; -// this below is connected to beat_active +// This below is connected to beat_active DJCi500.slicerBeatActive = function(value, group, _control) { // This slicer implementation will work for constant beatgrids only! const deck = script.deckFromGroup(group) - 1; @@ -1496,7 +1497,6 @@ DJCi500.slicerBeatActive = function(value, group, _control) { let slicerPosInSection = 0; - // this works. if (engine.getValue(group, "beat_closest") === engine.getValue(group, "beat_next")) { return; } @@ -1521,8 +1521,8 @@ DJCi500.slicerBeatActive = function(value, group, _control) { }; DJCi500.shutdown = function() { - //cleanup - midi.sendShortMsg(0x90, 0x05, 0x00); //turn browser led off + // Cleanup + midi.sendShortMsg(0x90, 0x05, 0x00); // Turn browser led off midi.sendShortMsg(0xB0, 0x7F, 0x7E); }; From 446b99b274c7758fbf54248bf8a8dd6d82139d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Sun, 2 Mar 2025 12:32:44 +0100 Subject: [PATCH 35/40] fix: range and key not working on correct deck and loop pad 8 fix --- .../Hercules-DJControl-Inpulse-500-script.js | 32 +++++++++---------- .../Hercules_DJControl_Inpulse_500.midi.xml | 6 ++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 5ac57382c277..7d10b2c88946 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -674,10 +674,10 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x40], on: pairColorsOn[0], off: pairColorsOff[0], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { - engine.setValue(group, "pitch_down", 1); - engine.setValue(group, "pitch_down", 1); + engine.setValue(deckData.currentDeck, "pitch_down", 1); + engine.setValue(deckData.currentDeck, "pitch_down", 1); midi.sendShortMsg(status, control, this.on); } else { midi.sendShortMsg(status, control, this.off); @@ -689,9 +689,9 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x41], on: pairColorsOn[1], off: pairColorsOff[1], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { - engine.setValue(group, "pitch_down", 1); + engine.setValue(deckData.currentDeck, "pitch_down", 1); midi.sendShortMsg(status, control, this.on); } else { midi.sendShortMsg(status, control, this.off); @@ -703,9 +703,9 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x42], on: pairColorsOn[6], off: pairColorsOff[6], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { - engine.setValue(group, "pitch_up", 1); + engine.setValue(deckData.currentDeck, "pitch_up", 1); midi.sendShortMsg(status, control, this.on); } else { midi.sendShortMsg(status, control, this.off); @@ -717,10 +717,10 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x43], on: pairColorsOn[6], off: pairColorsOff[6], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { - engine.setValue(group, "pitch_up", 1); - engine.setValue(group, "pitch_up", 1); + engine.setValue(deckData.currentDeck, "pitch_up", 1); + engine.setValue(deckData.currentDeck, "pitch_up", 1); midi.sendShortMsg(status, control, this.on); } else { midi.sendShortMsg(status, control, this.off); @@ -732,13 +732,13 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x46], on: 0x63, off: 0x42, - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { deckData.pitchRangeId++; if (deckData.pitchRangeId > 6) { deckData.pitchRangeId = 6; } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + engine.setValue(deckData.currentDeck, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); midi.sendShortMsg(status, control, this.on); //17 -- 3B } else { midi.sendShortMsg(status, control, this.off); //3B -- 33 @@ -750,13 +750,13 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x45], on: pairColorsOn[3], off: pairColorsOff[3], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { deckData.pitchRangeId = deckData.pitchRangeId - 1; if (deckData.pitchRangeId < 0) { deckData.pitchRangeId = 0; } - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + engine.setValue(deckData.currentDeck, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); midi.sendShortMsg(status, control, this.on); //17 -- 3B } else { midi.sendShortMsg(status, control, this.off); //3B -- 33 @@ -768,10 +768,10 @@ DJCi500.Deck = function(deckNumbers, midiChannel) { midi: [0x95 + midiChannel, 0x44], on: pairColorsOn[6], off: pairColorsOff[6], - input: function(channel, control, value, status, group) { + input: function(channel, control, value, status, _group) { if (value === 0x7F) { deckData.pitchRangeId = 0; - engine.setValue(group, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); + engine.setValue(deckData.currentDeck, "rateRange", deckData.pitchRanges[deckData.pitchRangeId]); midi.sendShortMsg(status, control, this.on); //17 -- 3B } else { midi.sendShortMsg(status, control, this.off); //3B -- 33 diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index 771a83862319..1d7d8e81b99f 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -902,7 +902,7 @@ 0x96 0x17 - + @@ -985,7 +985,7 @@ 0x96 0x1F - + @@ -2123,7 +2123,7 @@ 0x97 0x1F - + From 53263208caf4f21ae464d017143abfe4a9baf09f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Sun, 2 Mar 2025 19:37:17 +0100 Subject: [PATCH 36/40] fix: typo --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 7d10b2c88946..04a8efc8cc41 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -67,7 +67,7 @@ // // **************************************************************************** -// esling-disable-next-line prefer-const +// eslint-disable-next-line prefer-const var DJCi500 = {}; /////////////////////////////////////////////////////////////// From 4ae96e7da02323f87acb7f982b667810246bceda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Tue, 4 Mar 2025 14:26:24 +0100 Subject: [PATCH 37/40] fix: volume and pitch faders didn't work with shift --- .../Hercules_DJControl_Inpulse_500.midi.xml | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index 1d7d8e81b99f..eaa3a47bf52c 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -2914,6 +2914,27 @@ + + + [Channel1] + DJCi500.deckA.volume.inputMSB + Volume Deck A + 0xB4 + 0x00 + + + + + + [Channel1] + DJCi500.deckA.volume.inputLSB + Volume Deck A + 0xB4 + 0x20 + + + + @@ -3029,6 +3050,25 @@ + + + [Channel1] + DJCi500.deckA.pitchFader.inputMSB + 0xB4 + 0x08 + + + + + + [Channel1] + DJCi500.deckA.pitchFader.inputLSB + 0xB4 + 0x28 + + + + [Channel1] @@ -3124,6 +3164,27 @@ + + [Channel2] + DJCi500.deckB.volume.inputLSB + Volume Deck B + 0xB5 + 0x20 + + + + + + + [Channel2] + DJCi500.deckB.volume.inputMSB + Volume Deck B + 0xB5 + 0x00 + + + + [Channel2] DJCi500.deckB.volume.inputLSB @@ -3249,6 +3310,25 @@ + + + [Channel2] + DJCi500.deckB.pitchFader.inputMSB + 0xB5 + 0x08 + + + + + + [Channel2] + DJCi500.deckB.pitchFader.inputLSB + 0xB5 + 0x28 + + + + [Channel2] From f98243655184833b3a150e862327f870e4f4ec84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Wed, 12 Mar 2025 01:40:43 +0100 Subject: [PATCH 38/40] fix: warnings at startup, name and authors --- .../Hercules-DJControl-Inpulse-500-script.js | 30 +++++++++---------- .../Hercules_DJControl_Inpulse_500.midi.xml | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 04a8efc8cc41..35c79fb821d1 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -147,7 +147,7 @@ DJCi500.vuMeterUpdateMaster = function(value, _group, control) { midi.sendShortMsg(0xB0, ctrl, value); }; -DJCi500.vuMeterPeakLeftMaster = function(value, _group, _control, _status) { +DJCi500.vuMeterPeakLeftMaster = function(value, _group, _control) { if (value) { midi.sendShortMsg(0x90, 0x0A, 0x7F); } else { @@ -155,7 +155,7 @@ DJCi500.vuMeterPeakLeftMaster = function(value, _group, _control, _status) { } }; -DJCi500.vuMeterPeakRightMaster = function(value, _group, _control, _status) { +DJCi500.vuMeterPeakRightMaster = function(value, _group, _control) { if (value) { midi.sendShortMsg(0x90, 0x0F, 0x7F); } else { @@ -164,7 +164,7 @@ DJCi500.vuMeterPeakRightMaster = function(value, _group, _control, _status) { }; // Deck VU Meter callbacks -DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { +DJCi500.vuMeterUpdateDeck = function(value, group) { // Reserve the red led for peak indicator, this will in turn, make // the display more similar (I hope) to what Mixxx VU shows value = script.absoluteLinInverse(value, 0.0, 1.0, 0, 125); @@ -175,7 +175,7 @@ DJCi500.vuMeterUpdateDeck = function(value, group, _control, _status) { } }; -DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { +DJCi500.vuMeterPeakDeck = function(value, group, _control) { let channel = 0x00; if (DJCi500.deckA.currentDeck === group) { channel = 0x91; @@ -192,7 +192,7 @@ DJCi500.vuMeterPeakDeck = function(value, group, _control, _status) { } }; -DJCi500.numberIndicator = function(value, group, _control, _status) { +DJCi500.numberIndicator = function(value, group, _control) { if (DJCi500.deckA.currentDeck === group) { midi.sendShortMsg(0x91, 0x30, value); } else if (DJCi500.deckB.currentDeck === group) { @@ -1000,13 +1000,13 @@ DJCi500.init = function() { // Connect the VUMeters engine.makeConnection("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel1]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel1]", "vu_meter"); engine.makeConnection("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel2]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel2]", "vu_meter"); engine.makeConnection("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel3]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel3]", "vu_meter"); engine.makeConnection("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); - engine.getValue("[Channel4]", "vu_meter", DJCi500.vuMeterUpdateDeck); + engine.getValue("[Channel4]", "vu_meter"); // Deck VU meters peak indicators engine.makeConnection("[Channel1]", "peak_indicator", DJCi500.vuMeterPeakDeck); @@ -1016,13 +1016,13 @@ DJCi500.init = function() { // Connect number leds engine.makeConnection("[Channel1]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel1]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel1]", "play_indicator"); engine.makeConnection("[Channel2]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel2]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel2]", "play_indicator"); engine.makeConnection("[Channel3]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel3]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel3]", "play_indicator"); engine.makeConnection("[Channel4]", "play_indicator", DJCi500.numberIndicator); - engine.getValue("[Channel4]", "play_indicator", DJCi500.numberIndicator); + engine.getValue("[Channel4]", "play_indicator"); // Connect Master VU meter engine.makeConnection("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); @@ -1030,8 +1030,8 @@ DJCi500.init = function() { engine.makeConnection("[Main]", "peak_indicator_left", DJCi500.vuMeterPeakLeftMaster); engine.makeConnection("[Main]", "peak_indicator_right", DJCi500.vuMeterPeakRightMaster); - engine.getValue("[Main]", "vu_meter_left", DJCi500.vuMeterUpdateMaster); - engine.getValue("[Main]", "vu_meter_right", DJCi500.vuMeterUpdateMaster); + engine.getValue("[Main]", "vu_meter_left"); + engine.getValue("[Main]", "vu_meter_right"); // Connect the FX selection leds engine.makeConnection("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable", DJCi500.fxSelIndicator); diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index eaa3a47bf52c..92c45278068d 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -1,15 +1,15 @@ - Hercules DJControl Inpulse 500 1d - DJ Phatso for Hercules Technical Support + Hercules DJControl Inpulse 500 + DJ Phatso, Event1ne and Reset Reboot MIDI Preset for Hercules DJControl Inpulse 500 https://www.mixxx.org/wiki/doku.php/hercules_djcontrol_inpulse_500 https://mixxx.discourse.group/t/hercules-djcontrol-inpulse-500/19739 - + From 172e77507081c1497b713978ca9a516873fdac07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Wed, 12 Mar 2025 01:41:22 +0100 Subject: [PATCH 39/40] fix: remove commented lodash loading --- res/controllers/Hercules_DJControl_Inpulse_500.midi.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml index 92c45278068d..cc9317cdcbd5 100644 --- a/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml +++ b/res/controllers/Hercules_DJControl_Inpulse_500.midi.xml @@ -9,7 +9,6 @@ - From b162e0a96f72232c782bac83d4b1db7485e44a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Cuevas?= Date: Tue, 18 Mar 2025 15:02:54 +0100 Subject: [PATCH 40/40] fix: fix linter --- res/controllers/Hercules-DJControl-Inpulse-500-script.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/res/controllers/Hercules-DJControl-Inpulse-500-script.js b/res/controllers/Hercules-DJControl-Inpulse-500-script.js index 35c79fb821d1..afcc008e4923 100644 --- a/res/controllers/Hercules-DJControl-Inpulse-500-script.js +++ b/res/controllers/Hercules-DJControl-Inpulse-500-script.js @@ -67,8 +67,7 @@ // // **************************************************************************** -// eslint-disable-next-line prefer-const -var DJCi500 = {}; +var DJCi500 = {}; // eslint-disable-line /////////////////////////////////////////////////////////////// // USER OPTIONS //