10000 feat: add Launchpad MK3 support (#3) · duncte123/launchpad.js@d30c9e7 · GitHub
[go: up one dir, main page]

Skip to content

Commit d30c9e7

Browse files
authored
feat: add Launchpad MK3 support (#3)
* feat: add Launchpad MK3 support Differences with MK2: - I've switched to using Programmer Mode instead of Session Mode. - Don't know if MK2 has the ability to set multiple button colors at the same time, but MK3 does have that; we can't currently offer that capability because the API doesn't allow it though. - The color range has changed from [0..63] to [0..127], so all color utilities don't really work anymore. I thought we could switch all color values to be floats between [0..1], and automatically scale them to the right input range for the Launchpad... but there will be edge cases in which we cannot do this automatically and transparently for users. * Fix x/y mapping * Remove unused imports * Do ignore SysEx messages returned by the LP * Set brightness to maximum * Refactor to new base class * Fix typo * Type colorutils functions as 3-tuples * Add MK3 to README * Add `autoDetect` function * Add tests, combine X/Y mode and non-X/Y mode * Small fixes * Turn abstract base class into an interface * Starting to add some protocol tests * Add event tests for mk2 * Rescale colorspace to 0..1 * Remove unnecessary quotes * Add mk3 tests * Add palette colors * Linter errors * Update README * Run tests on PRs * Adding .js extensions back * Palette is 128 colors * Remove dependencies on nonexistant definitions * Fix more references to palette size * Update exxamples, fix ESM tests
1 parent 7e1487b commit d30c9e7

30 files changed

+9806
-1068
lines changed

.github/workflows/lint.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
name: Lint Code
1+
name: Lint and Test Code
22

33
on:
4-
- push
4+
push:
5+
pull_request:
6+
types:
7+
- edited
8+
- opened
9+
- synchronize
10+
- reopened
511

612
jobs:
713
build:
@@ -20,3 +26,5 @@ jobs:
2026
run: npm ci
2127
- name: Run eslint
2228
run: npm run lint
29+
- name: Run tests
30+
run: npm run test

README.md

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,94 @@
33
Interact with your launchpads in Node.js
44

55
Launchpad running an [example script](./examples/example.js)
6-
![](./assets/Active_launchpad_resize.png)
6+
7+
![Launchpad displaying a cross](./assets/Active_launchpad_resize.png)
78

89
This project started as a module for my own stream system to make several things interact with OBS studio, named [rewards-interaction][rewards-interaction].
910
After re-writing a broken launchpad library I decided to release the library to the public so everyone can enjoy easy programming on their launchpad.
1011

1112
Some sample programs can be found in the [examples folder](./examples).
1213

13-
### Launchpad models currently supported
14+
## Launchpad models currently supported
15+
1416
- Launchpad MK2
17+
- Launchpad MK3 (only tested with Mini)
18+
19+
### Why are only these launchpads supported?
1520

16-
##### Why are only these launchpads supported?
1721
These launchpads are supported because I own them myself and have been able to test them.
1822
If a launchpad is not listed here it means that I do not own one and have not been able to test that one with the program.
1923

20-
### Examples
24+
## Examples
25+
2126
More examples can be found in the [examples folder](./examples), this is just a simple button listener.
27+
2228
```js
23-
const { LaunchpadMK2, colors } = require('launchpad.js');
29+
const { autoDetect, colors } = require('launchpad.js');
2430
const { colorFromHex, defaultColors } = colors;
2531

26-
// we are enabling xyMode here
27-
const lp = new lpJs.LaunchpadMK2({ xyMode: true });
32+
const lp = autoDetect();
33+
34+
// Alternatively:
35+
//
36+
// await waitForReady(lp);
2837

2938
lp.once('ready', (deviceName) => {
3039
console.log(`${deviceName} is ready!!`);
3140

32-
lp.on('buttonDown', (button, value) => {
33-
// generate a random color on each button press
41+
lp.on('buttonDown', (button) => {
42+
// Generate a random color on each button press
3443
const randHex = Math.floor(Math.random() * 16777215).toString(16);
35-
// we have the parse the colors to a special RGB value as
36-
// the launchpad does not go from 0-255 but from 0-63 for each color
44+
45+
// The Launchpad accepts an RGB-triple between 0 and 1. This converts the
46+
// hex code to the appropriate number array.
3747
const color = colorFromHex(randHex);
3848

39-
console.log('Button pressed: ' + button);
49+
console.log(`Button pressed ${button.nr} (x: ${button.xy[0]}, y: ${button.xy[1]}`);
4050

4151
lp.setButtonColor(button, color);
4252
});
4353

44-
lp.on('buttonUp', (button, value) => {
54+
lp.on('buttonUp', (button) => {
4555
lp.setButtonColor(button, defaultColors.off);
4656
});
4757
});
4858
```
4959

50-
## TODO:
60+
## API
61+
62+
A number of methods are available to control the button colors on
63+
the LaunchPad. In all of these methods, the button to control can be
64+
specified in one of the following ways:
65+
66+
- `number`, indicating a Launchpad-specific button number
67+
- `[x, y]`, a Launchpad-independent button coordinate with (0, 0) in
68+
the top-left.
69+
- `Button`, a Button object (as returned by the `buttonDown` or `buttonUp`
70+
event handlers).
71+
72+
The follow methods control a button's color:
73+
74+
- `lp.setButtonColor(button, colorOrRGB)`: set a button to a solid color.
75+
`colorOrRGB` is either:
76+
- `number` between 0..127, a color in the 128-color palette of the Launchpad.
77+
- `[r, g, b]`, an array of RGB values between 0 and 1.
78+
- `lp.flash(button, color, colorB?)`: flash a button between two palette
79+
colors. For colors that don't support a second color, the button will flash
80+
to black.
81+
- `lp.pulse(button, color)`: a button will pulse between black and the given
82+
palette color.
83+
84+
## TODO
85+
5186
- Add support for the same launchpads as launchpad.py
5287

5388
### Links
54-
Launchpad developer manual: https://resource.novationmusic.com/support/product-downloads?product=Launchpad
89+
90+
- [Launchpad developer manual](https://resource.novationmusic.com/support/product-downloads?product=Launchpad)
5591

5692
### Notice
93+
5794
This project contains modified code from https://github.com/Lokua/launchpad which was released under the MIT license
5895

5996
[rewards-interaction]: https://github.com/duncte123/rewards-interaction

examples/example.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { LaunchpadMK2, colors } from '../dist/index.js';
1+
import { autoDetect, colors } from '../dist/index.js';
22
const { colorFromHex, defaultColors } = colors;
33

44
// upon connect the launchpad will be put into "Session" mode
5-
const lp = new LaunchpadMK2({
6-
debug: false,
7-
});
5+
const lp = autoDetect();
86

97
lp.on('rawMessage', (message) => {
108
console.log('Raw message', message);

examples/pulseAndFlash.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { LaunchpadMK2, colors } from '../dist/index.js';
1+
import { autoDetect, colors } from '../dist/index.js';
22
const { colorFromHex } = colors;
33

4-
const lp = new LaunchpadMK2();
4+
const lp = autoDetect();
55

66
// just a basic color setup
77
const noteColors = {
@@ -21,11 +21,12 @@ lp.once('ready', (name) => {
2121
});
2222

2323
// set to true to pulse instead
24-
const pulse = false;
24+
const pulse = true;
2525
const flashColor = 5;
2626
const states = {};
2727

28-
lp.on('buttonDown', (note, value) => {
28+
lp.on('buttonDown', (button) => {
29+
const note = button.nr;
2930

3031
// we are currently flashing
3132
if (states[note]) {

examples/rememberColors.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// by now you can probably see that this is just me having fun :P
22

3-
import { colors, LaunchpadMK2 } from '../dist/index.js';
3+
import { colors, autoDetect } from '../dist/index.js';
44

55
const { colorFromHex, defaultColors } = colors;
66

7-
const lp = new LaunchpadMK2();
7+
const lp = autoDetect();
88

99
lp.once('ready', (name) => {
1010
console.log(`Connected to ${name}`);

examples/simpleAnimation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { LaunchpadMK2, colors } from '../dist/index.js';
1+
import { autoDetect, colors } from '../dist/index.js';
22
const { colorFromHex, colorFromRGB } = colors;
33

4-
const lp = new LaunchpadMK2();
4+
const lp = autoDetect();
55

66
let currentFrame = 0;
77
// this was coded by hand, yeah I know

examples/xyModeExample.js

Lines changed: 0 additions & 36 deletions
This file was deleted.

jest.config.cjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2+
module.exports = {
3+
testEnvironment: 'node',
4+
5+
// Necessary for ESM support (maps the .js imports to the correct .ts files)
6+
preset: 'ts-jest/presets/default-esm', // or other ESM presets
7+
globals: {
8+
'ts-jest': {
9+
useESM: true,
10+
},
11+
},
12+
moduleNameMapper: {
13+
'^(\\.{1,2}/.*)\\.js$': '$1',
14+
},
15+
};

0 commit comments

Comments
 (0)
0