version: current (code-driven)
author: Milkii B
target hardware: Novation Launchpad Pro MK3
target software: Mixxx DJ Software
Comprehensive Mixxx controller script for the Novation Launchpad Pro MK3, providing advanced DJ control capabilities with visual feedback through RGB LED pads. The script transforms the controller into a multi-deck hotcue station with BPM correction, beatjumping, looping, audio routing, and playback control features.
- main grid: 8×8 RGB pad matrix (64 pads total)
- side pads: 16 RGB pads (8 left, 8 right)
- control rows:
row0: 8 buttons above main grid (bank toggle + 8 function buttons)row1: 8 buttons in middle rowrow2: 8 buttons at bottom
- mode: Programmer mode (automatically switched from DAW mode)
- communication: SysEx messages for RGB LED control
- input handling: Note On (0x90) and Control Change (0xB0) messages
var LaunchpadProMK3 = {};
// Key state variables
LaunchpadProMK3.currentPage = 0; // 0-7
LaunchpadProMK3.totalPages = 8; // pages 0..7
LaunchpadProMK3.shiftHeld = 0; // set by row1[4] (middle row pad 5)
LaunchpadProMK3.keepPlayingMode = false; // toggled by row2[6]
LaunchpadProMK3.splitCue = 0; // headSplit state
LaunchpadProMK3.splitCueUnVol = 0; // UnVol system active
LaunchpadProMK3.totalDecks = 4; // Configurable 2-4// Colors for each deck, with the default physical order decks are usually arranged with
LaunchpadProMK3.deck.config = {
"1": { order: 2, colour: 0x378df7 }, // Blue
"2": { order: 3, colour: 0xfeb108 }, // Yellow
"3": { order: 1, colour: 0xd700d7 }, // Magenta
"4": { order: 4, colour: 0x88b31a } // Green
};
// Per-deck hotcue bank tracking - each deck has independent bank cycling
LaunchpadProMK3.hotcueBankPerDeck = { // Banks 1-3, cycle 1→2→3→1
1: 1, 2: 1, 3: 1, 4: 1
};// row2[0-3] toggle pairs for page selection (row2[4] is slip toggle)
LaunchpadProMK3.pageButtonConfig = [
{ primary: 0, alt: 1 }, // Hotcues ↔ One-Deck
{ primary: 2, alt: 3 }, // Beatjump ↔ BPM Scale
{ primary: 4, alt: 5 }, // Forward Loops ↔ Reverse Loops
{ primary: 6, alt: 7 } // Loop Move ↔ Loop Resize
];// https://manual.mixxx.org/2.5/en_gb/chapters/appendix/mixxx_controls#control-[ChannelN]-beatjump_X_forward
// beatjump_X_forward, beatjump_X_backward. Jump by X beats. A control exists for X = 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512. If a loop is active, the loop is moved forward by X beats.
LaunchpadProMK3.beatjumpControls = [ // Page 2 grid mapping
"beatjump_128_backward", "beatjump_64_backward", "beatjump_32_backward", "beatjump_16_backward",
"beatjump_8_backward", "beatjump_4_backward", "beatjump_2_backward", "beatjump_1_backward",
"beatjump_128_forward", "beatjump_64_forward", "beatjump_32_forward", "beatjump_16_forward",
"beatjump_8_forward", "beatjump_4_forward", "beatjump_2_forward", "beatjump_1_forward"
];
// BPM scaling columns with scale factors and Mixxx control names
LaunchpadProMK3.bpmScaleColumns = [ // Page 3 BPM scaling
{ index: 1, scale: 0.5, control: "beats_set_halve", colour: 0xFF5555 },
{ index: 2, scale: 0.666, control: "beats_set_twothirds", colour: 0x77FF77 },
{ index: 3, scale: 0.75, control: "beats_set_threefourths", colour: 0x7B00C2 },
{ index: 4, scale: 1, control: "beats_undo_adjustment", colour: 0xff0000 },
{ index: 5, scale: 1.25, control: "beats_set_fivefourths", colour: 0x00F },
{ index: 6, scale: 1.333, control: "beats_set_fourthirds", colour: 0x8B00C2 },
{ index: 7, scale: 1.5, control: "beats_set_threehalves", colour: 0x88FF88 },
{ index: 8, scale: 2, control: "beats_set_double", colour: 0xFF1111 }
];
// https://manual.mixxx.org/2.5/en_gb/chapters/appendix/mixxx_controls#control-[ChannelN]-beatloop_X_activate
// Activates a loop over X beats. A control exists for X = 0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512. Depending on the state of loop_anchor the loop is created forwards or backwards from the current position.
LaunchpadProMK3.loopControls = [ // Pages 4-5 loop sizes
"1_activate", "2_activate", "4_activate", "8_activate",
"16_activate", "32_activate", "64_activate", "128_activate"
];// Row Controls (0xB0) - Control Change messages
LaunchpadProMK3.row0 = [0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62];
LaunchpadProMK3.row1 = [0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C];
LaunchpadProMK3.row2 = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
// Main Grid (0x90) - Note On/Off for 8x8 matrix
LaunchpadProMK3.mainpadAddresses = [81, 82, 83, 84, 85, 86, 87, 88, ...];
// Sidepads (0x90) - 16 pads around main grid for deck-specific controls
LaunchpadProMK3.sidepads = [80, 70, 89, 79, 60, 50, 69, 59, ...];the controller operates in 10 pages (0–9). pages 0–7 are organized in four primary/alternate pairs selected from row2. animation pages are on 8/9 via shift + row2[3].
- row2[0]: page 0 ↔ page 1
- row2[1]: page 2 ↔ page 3
- row2[2]: page 4 ↔ page 5
- row2[3]: page 6 ↔ page 7 (shift selects 8/9 animations)
- row1[4]: slip toggle (global)
- row2[5]: undo hotcue, row2[6]: keep playing, row2[7]: split cue volume switch (unvol)
main grid: hotcues per deck with per-deck banking system
- Hotcue Banks: Bank 1 (1–16), Bank 2 (17–32), Bank 3 (33–36; shown on first 4 pads only)
- Total Capacity: 36 hotcues per deck with independent bank cycling per deck
- Interactions: Normal press activates hotcue; Shift + press clears individual hotcue; Keep Playing mode prevents stop-on-release
- Visual Feedback: Color-coded by deck with brightness scaling for loaded/unloaded states
side pads: intro/outro markers (4 per deck) with beat-synchronized flashing
intro_start_activate,intro_end_activate,outro_start_activate,outro_end_activate- Each deck's sidepads are positioned based on deck order configuration
main grid: mixed controls for the selected deck
- rows 7–8: selected deck hotcues (banked as in page 0)
- rows 5–6: beatjump controls with tempo-synced flashing
- rows 1–4: loop controls; row0[5]=exit-on-release, row0[6]=roll vs set
- sidepads: left column loop move; right column loop resize
- deck selection: row1 pads 1–4 select decks by physical order (magenta, blue, yellow, green)
main grid: beatjump controls per deck with deck-colored gradients and tempo-synchronized flashing
// Backward: 128, 64, 32, 16, 8, 4, 2, 1 beats
// Forward: 128, 64, 32, 16, 8, 4, 2, 1 beats- visual system: deck-colored gradients with beat-synchronized flashing for tempo feedback
- sidepads: deck colors with beat flashing for visual synchronization
- grid layout: 8×8 grid mapped to beatjump controls with visual feedback
main grid: BPM scale columns with animated feedback system
- even rows: display scale colors from
bpmScaleColumnsconfiguration - odd rows: show deck colors for visual consistency
- animation system: scaled-beat animations with 4-state cycle for visual tempo feedback
- sidepads: deck colors with beat flashing; scaled-beat animations synchronized to grid
main grid: beatloop activations across standard loop sizes
- loop sizes: 1, 2, 4, 8, 16, 32, 64, 128 beats
- controls: uses
beatloop_X_activateMixxx controls - visual: deck-colored grid with loop size indicators
main grid: reverse loop variations using beatlooproll/beatloop (follows row0[6])
main grid: move active loop by specified beat amounts
main grid: resize active loop with halve/double patterns
two animation/aux pages accessed by shift + row2[3]
bank toggle (top-left CC pad): switches between bank a and bank b
bank a (default - global controls):
| pad | function | notes |
|---|---|---|
| 0 | dim brightness down | Shift: cycle hotcue bank (all decks) |
| 1 | dim brightness up | Shift: cycle hotcue bank (all decks) |
| 2 | hotcue color previous | affects lastHotcueChannel |
| 3 | hotcue color next | affects lastHotcueChannel |
| 4 | selected deck swatch | displays one-deck selected deck color |
| 5 | exit-on-release toggle | loop persistence control (pages 1/4/5/6/7) |
| 6 | loop type toggle | roll vs set (pages 1/4/5/6/7) |
| 7 | toggle all effects | - |
bank b (deck controls for selected deck on page 1):
| pad | function | notes |
|---|---|---|
| 0 | cue | momentary (standard Mixxx cue behavior) |
| 1 | play/pause | toggle playback |
| 2 | beats translate half | shift beatgrid by half beat |
| 3 | undo seek | return to previous playposition |
| 4 | redo seek | go to next playposition |
| 5 | load selected track | load track from library |
| 6 | library up | move selection up |
| 7 | library down | move selection down |
| pad | normal function | shift function | alt (row1[0]) |
|---|---|---|---|
| 0 | alt modifier | - | hold to enable clear-all on pads 1–4 |
| 1 | deck 3 select / create multi hotcues | cycle bank | alt+shift: clear all deck 3 |
| 2 | deck 1 select / create multi hotcues | cycle bank | alt+shift: clear all deck 1 |
| 3 | deck 2 select / create multi hotcues | cycle bank | alt+shift: clear all deck 2 |
| 4 | deck 4 select / create multi hotcues | cycle bank | alt+shift: clear all deck 4 |
| 5 | redo last hotcue | - | - |
| 6 | slip toggle | global slip for all decks | - |
| 7 | split cue (headsplit) toggle | - | - |
| pad | function |
|---|---|
| 0 | Shift modifier |
| 1 | toggle page 0 ↔ 1 |
| 2 | toggle page 2 ↔ 3 |
| 3 | toggle page 4 ↔ 5 |
| 4 | toggle page 6 ↔ 7 |
| 5 | undo last hotcue |
| 6 | keep playing mode toggle |
| 7 | split cue volume switch (unvol) |
function: createLeadupDropHotcues(deck, value)
- purpose: creates precisely-timed hotcues for build-up and drop sections
- hotcue pattern: 6 leadup markers + drop point + 1 outro marker (8 total)
- timing: -265, -192, -128, -64 (dark green), -32, -16 (orange), DROP (red), +128 (purple)
- colors: dark green (leadup), orange (approach), red (drop), purple (outro)
- cooldown: 1-second minimum between activations to prevent rapid-fire creation
- use case: EDM/Dance music with predictable build-up and drop patterns
function: clearAllHotcues(deckNum)
- purpose: mass removal of all hotcues on specified deck for clean slate
- scope: clears all hotcues across banks 1–3 (36 total hotcues)
- undo integration: adds all cleared hotcues to undo stack for complete recovery
- trigger: hold Row0[7] while pressing corresponding Row1 deck button (Page 0)
- safety: full undo/redo compatibility prevents accidental data loss
data structure:
- undo stack:
LaunchpadProMK3.lastHotcue[]- tracks all operations in reverse order - redo stack:
LaunchpadProMK3.redoLastDeletedHotcue[]- tracks cleared operations - tracking: channel, control name, pad address, deck number, color for complete restoration
operations: individual hotcue deletion, mass hotcue clearing, multi-hotcue creation persistence: maintains across page switches and controller state changes recovery: full restoration of hotcue positions, colors, and deck associations
row0 bank b provides deck-specific playback controls:
- cue button: momentary cue (standard Mixxx behavior)
- play/pause: toggle playback state
- beats translate half: shift beatgrid by half beat for alignment correction
- undo seek: returns playhead to previous recorded position
- redo seek: advances playhead to next recorded position
- load track: loads selected track from library to deck
- library navigation: move up/down through library
playposition history:
- automatically records playposition on play state changes, cue presses, hotcue activations
- detects manual seeks via playposition monitoring
- maintains history stack per deck for unlimited undo/redo
- integrates with standard Mixxx transport controls
functions: toggleSplitCue() and toggleSplitCueUnVol()
- split (row1[7]): toggles
headSplitand updates LEDs - unvol (row2[7]): temporary volume split switch with state restore
- exit behavior: pressing row2[7] while UnVol active exits and restores prior
headSplit/headMix - visual feedback: Row2[6] shows orange when UnVol active; Row2[7] shows deep blue when split enabled
- use case: DJ monitoring without affecting main mix; temporary volume adjustments
function: prevents hotcue button releases from stopping playback
- activation: row2[6] toggle
- visual feedback: blue-purple button illumination when active
- auto-reset: automatically disables when new hotcue is pressed
- use case: live performance requiring continuous playback control; prevents accidental stops
- deck colors: Blue, Yellow, Magenta, Green (configurable via hex codes)
- brightness scaling:
- loaded deck active: 85% brightness for clear visibility
- loaded deck inactive: 40% brightness for secondary indication
- unloaded deck: 20% brightness for minimal presence
- hotcue states: present (full deck color), empty (dimmed deck color), bank indicator (bright/dim based on active bank)
- row0[0] and row0[1]: indicate hotcue bank usage across all decks
- color semantics:
- bright green: all decks using this bank
- medium green: some decks using this bank
- dim green: bank not in use
- orange glow: mixed bank usage patterns
- real-time updates: reflects current bank state across all active decks
- deck colors: sidepads display deck color based on physical positioning
- beat flashing: synchronized flashing on relevant pages (0–3) for tempo indication
- position mapping: 4 sidepads per deck based on deck order configuration
- beat-synchronized flashing: tempo-dependent visual feedback for beatjump and BPM pages
- gradient generation: visual organization with deck-colored gradients
- multi-pad SysEx: efficient LED updates using batch messaging
- state transitions: smooth visual transitions between different controller states
// SysEx message structure for LED control
// full message is wrapped with manufacturer header/footer internally:
// F0 00 20 29 02 0E 03 03 pad r g b F7
LaunchpadProMK3.sendSysEx([0x03, 0x03, padAddress, red, green, blue])
// RGB color conversion and direct control
LaunchpadProMK3.hexToRGB(hexColor) // Returns [r, g, b] array
LaunchpadProMK3.sendRGB(pad, r, g, b) // Direct RGB control with bounds checking- base framework: Mixxx Components.js framework for core functionality
- deck objects: extended
components.Deckwith custom properties and methods - button objects:
components.HotcueButtonwith enhanced functionality and state tracking - per-deck banks:
hotcueBankPerDeckmaps deck numbers to active bank states (1–3)
// page management
LaunchpadProMK3.selectPage(page); // switch pages 0-7 with cleanup
LaunchpadProMK3.updateHotcuePage(); // Update Page 0 display and bank lights
LaunchpadProMK3.updateBeatjumpPage(); // Update Page 2 display with gradients
LaunchpadProMK3.updateBpmScalePage(); // Update Page 3 display with animations
LaunchpadProMK3.updateLoopPage(); // update page 4
LaunchpadProMK3.updateReverseLoopPage(); // update page 5
LaunchpadProMK3.updateLoopMovePage(); // update page 6
LaunchpadProMK3.updateLoopResizePage(); // update page 7
// hotcue management
LaunchpadProMK3.createLeadupDropHotcues(deck, value); // multi-hotcue creation (6 leadup + drop + 1 outro)
LaunchpadProMK3.clearAllHotcues(deckNum); // clear all hotcues with undo
LaunchpadProMK3.undoLastHotcue(); // undo last operation
LaunchpadProMK3.redoLastHotcue(); // redo last operation
LaunchpadProMK3.cycleHotcueBank(deckNum); // cycle bank 1→2→3→1
LaunchpadProMK3.updateHotcueBankLights(); // update bank indicators
// visual & audio
LaunchpadProMK3.toggleSplitCue(); // toggle headSplit state
LaunchpadProMK3.toggleSplitCueUnVol(); // toggle UnVol system
LaunchpadProMK3.resetKeepPlayingMode(); // reset keep playing state
LaunchpadProMK3.sendRGB(pad, r, g, b); // send RGB to pad with validation
LaunchpadProMK3.hexToRGB(hexColor); // convert hex to [r,g,b] array- page selection: row2[0-3] →
handlePageButtonPress()→selectPage()with cleanup; row2[4] is slip toggle - hotcue operations: main grid → hotcue activation/deletion → undo/redo stack management
- bank switching: Shift + row1[4-7] →
cycleHotcueBank()→updateHotcueBankLights() - clear all: hold row0[7] + row1[4-7] →
clearAllHotcues()→ undo stack population - split cue: row2[6-7] →
toggleSplitCue()/toggleSplitCueUnVol()with state restoration
- comprehensive DEBUG system: color-coded terminal output with timestamp tracking
- graceful degradation: fallback behavior for missing deck configurations
- safe array access: bounds checking for all array operations
- connection cleanup: proper cleanup procedures on page switches and state changes
- batch LED updates: multi-pad SysEx messages for efficient LED control
- conditional page updates: prevents unnecessary processing for inactive pages
- efficient color calculation: cached RGB values and optimized color conversions
- connection management: proper cleanup procedures with connection state tracking
- 2-deck mode: full 36 hotcues per deck (72 total) with independent banking
- 4-deck mode: 36 hotcues per deck (144 total) with per-deck bank management
- color customization: hex color codes for deck identification and visual consistency
- physical order: configurable pad layout arrangement for different DJ setups
- page system: framework for additional control pages with toggle functionality
- control arrays: easily modifiable control mappings for different Mixxx versions
- color schemes: customizable visual themes and brightness scaling
- DEBUG levels: adjustable logging verbosity for development and troubleshooting
- lodash.mixxx.js: utility functions for enhanced JavaScript operations
- midi-components-0.0.js: component framework for MIDI device integration
- Mixxx Engine: core DJ software integration and control system
- initialize Programmer mode (switch from DAW mode automatically)
- configure deck objects and color schemes from configuration
- set up MIDI input handlers for all controls and pages
- initialize per-deck hotcue bank system and bank indicator LEDs
- load default page (page 0 - hotcues) with full visual setup
- display ASCII art welcome message and initialization status
- clear all LED displays and reset controller state
- cleanup beat connections and timers for proper resource management
- reset controller to default state for next session
- disconnect all MIDI connections and restore default LED states
This specification covers the complete functionality of the Launchpad Pro MK3 controller script as implemented. The system provides professional-grade DJ control with extensive hotcue management, visual feedback, playback control, and audio routing capabilities suitable for live performance and studio work. The modular page system and per-deck banking provide flexible control layouts for different DJ styles and performance requirements.