• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

docs/H03-May-2022-

packages/H28-Jun-2021-125114

scripts/H03-May-2022-

.babelrcH A D28-Jun-2021251 1110

.editorconfigH A D28-Jun-2021424 2419

.eslintignoreH A D28-Jun-202118 32

.gitignoreH A D28-Jun-20211.5 KiB9774

LICENSEH A D28-Jun-20211.1 KiB1815

MakefileH A D28-Jun-20212.2 KiB7153

README.MDH A D28-Jun-202115.1 KiB430287

lerna.jsonH A D28-Jun-202191 87

package.jsonH A D28-Jun-20211.3 KiB4443

README.MD

1# Mixxx mapping for Novation Launchpad ��
2
3**Flexible and (soon) customizable controller mapping for Launchpad. Make DJing
4with Mixxx fun on Launchpad!**
5
6[![Build status](https://img.shields.io/circleci/project/github/szdavid92/mixxx-launchpad.svg)](https://circleci.com/gh/szdavid92/mixxx-launchpad)
7
8There's already a Launchpad mapping shipping with Mixxx however it
9has several quirks and limitations:
10
11- it has a single hardcoded layout, supporting only the first 2 decks.
12  You can't e.g. change to decks 3 and 4, or sampler decks. This painfully
13  limits usability especially if you have multiple Launchpads (as I do!) and
14  want to control more decks.
15- It would be better if the deck layout was customizable. This is a problem
16  that crops up as you add support for sampler decks. E.g. when you play samplers, a small 4x4 interface with only hotcues is ideal.
17- Some of the controls are broken on recent Mixxx.
18- It has a mixer interface, but why? Launchpad is really not fit for mixing.
19- 8 of the buttons have no mapping, what a waste of resources!
20
21So I decided to make one that is more stable, flexible and customizable!
22
23## Features ✨
24
25 - map from 1 up to 4 channels (decks or samplers) on a single Launchpad at the same time ✨
26 - utilize presets with multiple sizes and features, change between them with ease ��
27 - x5 different deck presets in 3 sizes created for you and ready to use ✨, make it easy for the user to create new presets for their own needs (coming soon!)
28 - rich arsenal of controls ��
29   - play, cue, hotcues
30   - loop controls, beatloop, beatjump
31   - sync/master, tap, pitch shift
32   - custom controls like bouncy jumps
33   - and much more...
34 - trigger-like controls are favored - no clumsy mixers and faders ✨
35 - library navigation ��
36 - LED lights mimic Mixxx UI ✨
37
38## How to get started
39
40 �� Download the [latest release from here](https://github.com/szdavid92/mixxx-launchpad/releases/latest).
41
42 �� Follow the [instructions in the Mixxx User Manual](https://www.mixxx.org/manual/latest/chapters/controlling_mixxx.html#installing-a-preset-from-the-forum) to install the preset.
43
44 Alternatively, see [Build](#build) the build it from source
45
46## User guide
47
48### Global controls
49
50Global controls consist of **Deck selectors**, **Library controls** and
51**Modifier keys**.
52
53**Deck selectors** are located on the top bar. They are used to select decks and
54samplers to be laid out on the main grid. *D1-D4* are mapped to corresponding
55*decks*, *S1-S4* to *samplers*.
56
57**Library controls** are located on the sidebar to the right. They occupy the
58upper 5 buttons. Their functions from top to bottom:
59
60 - up in the library sidebar
61 - down in the library sidebar
62 - expand/close selected library sidebar entry
63 - up a track
64 - down a track
65
66> Note: The up/down controls are autoscrolled. If you hold them down for longer,
67the scrolling activates. This comes in handy when navigating lengthy playlists.
68
69![layout](docs/lp-mki-layout.png)
70
71**Modifier keys** are located on the lower 2 buttons of the sidebar, and used
72for the same purpose as you would expect on a computer keyboard.
73
74The figures show  Shift in **bold**,  Ctrl in *italic*, Ctrl+Shift
75in ***bold italic***.
76
77> Note: For some controls the modifier keys will act like toggles, but the modifier keys themselves are never toggled globally.
78
79### Using the deck selectors
80
81The deck selector is an essential feature of this Launchpad mapping. With it you
82can map multiple presets in multiple layouts on the main grid. The main grid is
83the inner 8x8 grid on the Launchpad. You have to memorize the layout patterns,
84but don't worry, there are only 4 of them.
85
86To select a single channel, simply press the button corresponding to the
87channel. This will remove all existing selections, and find the largest default
88preset that can be fit on the main grid.
89
90Presets come in 3 different sizes: *short* (4x4), *tall* (4x8) and *grande*
91(8x8)<sup>1</sup>. Multiple presets can have the same size, but only one preset
92can be default per size.
93
94To select multiple channels to be laid out, press the corresponding buttons
95in a *chord*. This way you can select to 4 channels.
96
97So what is a chord? In a chord you press buttons so you only release the first
98after you pressed the last one. The order of presses matter, however the order
99of releases does not. Now, instead of writing down how the exact layout
100algorithm works, I just show you the four different layouts that is generated
101for 1 (single channel), 2, 3 and 4 note chords. Once more the algorithm will
102fill out the spaces with the largest default preset.
103
104| ![1] | ![2] |
105|------|------|
106| ![3] | ![4] |
107
108[1]: docs/lp-1.png
109[2]: docs/lp-2.png
110[3]: docs/lp-3.png
111[4]: docs/lp-4.png
112
113This means that e.g. if you press down D3-D2-S1 in this chord sequence,
114- D3 will be mapped to block 1 with the default tall preset,
115- D2 will be mapped to block 2 with the default short preset and
116- S1 will be mapped to block 3 with the default short preset.
117
118Now you might ask: "But what if I don't want to use the largest default preset?"
119
120After a channel has been laid out you can cycle between all the presets that can
121fit into its space. This won't reflow the layout, even if you end up using a
122smaller preset. To cycle between presets
123  - press Ctrl + Channel Selector to cycle forward,
124  - press Shift + Channel Selector to cycle backward or
125  - press Ctrl + Shift + Channel Selector to revert to default.
126
127The cycling order is the following:
128  - primary: large to small
129  - secondary: default then all others in fixed but not specified order.
130
131See, not that complicated after all. Let's see the actual presets that are
132featured out of the box:
133
134|        | default                                                   |                                                                    |
135|--------|-----------------------------------------------------------|--------------------------------------------------------------------|
136| grande | ![grande]  **GRANDE** is currently the only grande layout.|                                                                    |
137| tall   | ![tall]    **TALL** is the default tall layout.           |![juggler] **JUGGLER** is a tall layout optimized for beat jumping. |
138| short  | ![short]  **SHORT** is the default short layout.          |![sampler]  **SAMPLER** is an all-cue short layout for samplers.    |
139
140
141[grande]: docs/lp-mki-grande.png
142[tall]: docs/lp-mki-tall.png
143[juggler]: docs/lp-mki-juggler.png
144[short]: docs/lp-mki-short.png
145[sampler]: docs/lp-mki-sampler.png
146
147<sup>1</sup> No identification with actual persons (living or deceased), places, buildings, and products is intended or should be inferred.
148
149### Deck controls
150
151Now that you are familiar with the presets, let's check the controls the make
152up these!
153
154#### PLAY
155
156Controls
157
158 - **normal**: toggles playing (if track is playable, starts playing; if track is playing, stops playing)
159 - **ctrl**: seeks to start of track
160 - **shift**: seeks to start of track and stops
161
162Feedback
163
164 - **bright red**: track is playing
165 - **bright red blinking**: track is stopped, playable
166 - **blank**: track is stopped, not playable
167
168#### SYNC / MASTER
169
170Controls
171
172 - **normal**: toggles sync:
173  - if deck is synced (follower or master) it becomes  not synced
174  - if track is not synced it becomes a sync follower
175 - **ctrl**: toggles master sync:
176  - if track is sync master, it becomes sync follower
177  - if track is not synced or sync follower, it becomes sync master
178
179Feedback
180
181 - **bright red**: track is sync master
182 - **bright orange**: track is sync follower
183 - **blank**: track is not synced
184
185#### NUDGE / PITCH
186
1872 button for down/up.
188
189Controls
190
191 - **normal**: nudges (temporarily alters pitch) in direction by primary value. See *Preferences > Interface > Temporary Speed Adjustment Buttons > Left click*
192 - **ctrl**: permanently changes pitch in direction by primary value. See *Preferences > Interface > Permanent Speed Adjustment Buttons > Left click*
193 - **shift**: nudges (temporarily alters pitch) in direction by secondary value. See *Preferences > Interface > Temporary Speed Adjustment Buttons > Right click*
194 - **ctrl+shift**: permanently changes pitch in direction by secondary value. See *Preferences > Interface > Permanent Speed Adjustment Buttons > Right click*
195 - **normal (both buttons simultaneously)**: reset pitch to original value
196
197Feedback
198
199  - **bright yellow**: while nudging with primary speed
200  - **dim yellow**: while nudging with secondary speed
201  - **bright red**: while permanently changing pitch with primary speed
202  - **dim red**: while permanently changing pitch with primary speed
203  - **dim amber**: while not pressing, and pitch has been altered in that direction
204
205#### CUE
206
207Controls
208
209- **normal**: behaves like the default cue method set in *Preferences > Interface > Cue mode*
210- **ctrl**: sets cue at cursor
211
212Feedback
213
214- **bright red**: display dictated by your Cue mode
215
216#### TAP
217
218tap tempo for playback or beatgrid.
219
220- **normal**: tapping adjusts song playback tempo. You should have correctly detected BPM and beatgrid.
221
222- **ctrl**: ~~instead of altering the playback tempo, tapping adjusts the beatgrid.~~ Not implemented. *Why?*
223- **shift**: sets the gridlines so the nearest beat aligns to current play position
224- **ctrl+shift**: second button: sets the gridlines so the nearest beat lines up with the other track's nearest beat
225
226Feedback
227
228- **bright red**: flashes up on gridline
229
230#### GRID MANIPULATORS
231
2322 controls for
233
234- **normal**: translating the grid backwards / forwards
235- **ctrl**: scaling the grid up (slower) / down (faster).
236
237#### PFL
238
239Controls
240
241- **normal**: toggle pre-fade listening (headphone)
242
243Feedback
244
245- **bright green**: PFL on
246- **blank**: PFL off
247
248#### QUANTIZE
249
250Controls
251
252- **normal**: toggle quantization (magnet)
253
254Feedback
255
256- **bright orange**: quantization on
257- **blank**: quantization off
258
259#### KEY SHIFTS
260
261Buttons for temporarily changing pitch, bound left to right, bottom to top. While pressed, they modify the key of
262the track. When pressing multiple, the one later pressed *steals* the modification.
263
264#### LOAD/EJECT
265
266Controls
267
268- **normal**: load the selected library track on deck. To prevent accidentally hitting, only works when the deck is empty.
269- **ctrl**: load the selected library track on deck. Works when the deck is not playing.
270- **shift**: eject deck. Works when the deck is not playing.
271
272Feedback
273
274- **dim red**: deck loaded, playing
275- **dim amber**: deck loaded, not playing
276- **dim green**: deck empty
277
278#### KEY
279
280Controls
281
282- **normal**: toggles keylock
283- **ctrl**: lowers key by semitone
284- **shift**: raises key by semitone
285
286Feedback
287
288- **hi red**: keylock on
289- **blank**: keylock off
290
291#### HOTCUES
292
293Hotcues are bound from left to right, bottom to top.
294
295Controls
296
297- **normal**: activates the hotcue:
298  - if the hotcue is set, seeks the player to hotcue's position.
299  - if the hotcue is not set, sets the hotcue to the current play position
300- **ctrl**:
301  - if the hotcue is set, deletes the hotcue
302  - if the hotcue is not set, sets the hotcue to the current play position
303
304Feedback
305
306- **bright yellow**: hotcue enabled
307- **blank**: hotcue disabled
308
309#### BEATJUMPS
310
311Controls for jumping backward (lower lane) and forward (upper lane).
312Supports two modes:
313 - the **normal mode** is represented with bright color. Jumping works as you would expect.
314 - the **rebouncing mode** is shown with dim color. It jumps on attack, then jumps back on release. Jumping legato works and uses the same stealing algorithm as key shifting.
315 Modes are switched with the CH MODE control (pressing `ctrl` and `shift` at the same time)
316
317You can change modes by pressing **ctrl+shift+[any beatjump key]**.
318
319There are two sets of jumps, switchable with the `ctrl` and `shift` keys, and shown in their corresponding colors. This means that pressing **ctrl+[any beatjump key]** will switch to the first set, while pressing **shift+[any beatjump key]** will switch to the second set.
320
321#### BEATLOOPS
322
323Controls for setting beatloops.
324
325Controls
326
327- **normal**: toggles beatloop
328
329Feedback
330
331- **bright red**: beatloop enabled
332- **dim red**: beatloop disabled
333
334#### LOOPJUMPS
335
336Almost the same as beatjumps, only instead of changing the current play position, they translate the position of the loop markers. As beatjumps, they support two modes and two sets. On how to use these, see [Beatjumps](#beatjumps)
337
338#### HALVE / DOUBLE
339
340They halve / double the current loop length, modifying the  position of the end marker.
341
342#### LOOPJUMP SMALL
343
344They translate the loop markers by a small amount backward/forward.
345
346Controls
347
348- **normal**: translates loop backward/forward
349
350#### LOOP
351
352Works the same way as the LOOP button on the GUI, ie. it toggles the current loop on or off.
353
354Controls
355
356- **normal**: toggles loop on/off
357
358Feedback
359
360- **bright green**: loop on
361- **dim green**: loop off
362
363## Technical details
364
365### JavaScript
366
367The code is written according to the [ES2015] specification. This is
368incompatible with the runtime running in Mixxx so it has to be transpiled back
369to ES5, which is done with [Babel] using the es2015 preset. Sadly due to the interpreter's only partial compatibility with the standard [even some ES3 transforms have to be enabled](bad-interpreter). The transpiled code
370is then bundled with [browserify] into a so called [standalone] module with the
371name `NovationLaunchpad`. Due to the lack of module loading system in the
372environment, the bundled code is placed on the global object with the above
373name. This works, because the same name is specified in the MIDI mapping XML file, so Mixxx will look for this name, and will call its `init` method upon loading.
374
375### MIDI mapping
376
377The controller mapping is generated from a template like
378[this][mapping-template] with [ejs]. The mapping reuses config from the package
379description and [buttons.js].
380
381### Build
382
383To build you need to have make, a recent Node (>=4), npm and jq.
384
385The multi-project build is managed with [lerna.js]. You need to  install it
386globally to make it available on the command line.  First clone the repo and
387install the dependencies:
388
389```
390git clone https://github.com/szdavid92/mixxx-launchpad
391cd mixxx-launchpad
392npm i --global lerna
393lerna bootstrap
394npm install
395```
396
397To compile the sources run
398
399```
400make compile
401```
402
403Afterward the `dist` folder will contain the files that need to be
404copied the Mixxx's controller folder.
405
406```
407make install
408```
409does this for you on macOS and Linux.
410
411### Known Issues
412
413#### No Windows build recipes
414Sorry, but building anything on Windows is pain.
415
416#### Lingering ES3 future reserved keywords
417
418Due to parser discrepancies, ES3 keywords and future reserved words that have been removed from ES5 can't be used as *(1) identifiers*, *(2) property literals* and *(3) member expression literals*. In ES5 you can use keywords and future reserved words in the last two cases.
419We have [transforms](.babelrc) for these two cases, however you still **can't use ES3 keywords and future reserved words as identifiers**, even if some of the latter was removed from ES5, for example `public`, `private` or `final`.
420
421
422[ES2015]:https://github.com/lukehoban/es6features#readme
423[Babel]:https://babeljs.io/
424[browserify]:http://browserify.org/
425[standalone]:https://github.com/substack/node-browserify#usage
426[mapping-template]:src/Launchpad/Launchpad.midi.xml.ejs
427[ejs]:http://ejs.co/
428[buttons.js]:src/Launchpad/buttons.js
429[lerna.js]: https://lernajs.io/
430