-
Notifications
You must be signed in to change notification settings - Fork 2
/
keyboard-input.js
102 lines (83 loc) · 2.25 KB
/
keyboard-input.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Generates pseudo-MIDI messages from the computer's keyboard.
function initKeyboardInput() {
const MIN_OCTAVE = 1;
const MAX_OCTAVE = 8;
const PAD_NOTES = {
q: 36,
w: 37,
e: 38,
r: 39,
t: 44,
y: 45,
u: 46,
i: 47,
};
const KEY_NOTES = {
// white keys + black keys, at octave = 0
z: 0, s: 1,
x: 2, d: 3,
c: 4,
v: 5, g: 6,
b: 7, h: 8,
n: 9, j: 10,
m: 11,
',': 12, 'l': 13,
'.': 14, ';': 15,
'/': 16,
};
const COMMANDS = {
'[': 106, // trackPrev
']': 107, // trackNext
};
function listenToKeyboardMessages(handler) {
function emit(message) {
setTimeout(handler.bind(null, message), 0);
}
const stopAllNotes = () =>
Object.keys(KEY_NOTES).forEach(key => emit({
channel: 1,
command: 8,
note: getKeyNote(key),
velocity: 0,
}));
let octaveOffset = 3;
const incrementOctave = (incr) => {
stopAllNotes();
octaveOffset = Math.max(Math.min(octaveOffset + incr, MAX_OCTAVE), MIN_OCTAVE);
}
const OTHER_KEYS = {
'+': () => incrementOctave(+1),
'-': () => incrementOctave(-1),
'=': () => incrementOctave(+1), // to prevent having to press shift on american keyboard
};
const getPadNote = key => PAD_NOTES[key];
const getKeyNote = key => KEY_NOTES[key] + octaveOffset * 12;
const getKeyCommand = key => COMMANDS[key];
function handleKeyboardEvent(e) {
const keyUp = e.type === 'keyup';
const padNote = getPadNote(e.key);
const commandNote = getKeyCommand(e.key);
const note = getKeyNote(e.key) || padNote || commandNote;
if (note) {
emit({
channel: padNote ? 10 : 1,
command: commandNote ? 11 : (keyUp ? 8 : 9),
note,
velocity: keyUp ? 0 : 64,
});
}
}
function handleKeyboardCommand(e) {
const otherKeyFct = OTHER_KEYS[e.key];
if (otherKeyFct) {
otherKeyFct();
}
}
window.addEventListener('keydown', e => !e.repeat && handleKeyboardEvent(e));
window.addEventListener('keyup', handleKeyboardEvent);
window.addEventListener('keypress', handleKeyboardCommand);
}
return {
onKeyEvents: listenToKeyboardMessages,
};
}