forked from espruino/EspruinoDocs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMidi.js
60 lines (56 loc) · 2.08 KB
/
Midi.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
/* Copyright (c) 2014 Luca S.G.de Marinis - loop23-at-gmail.com,
* See the file LICENSE for copying permission */
/* This module implements midi input (which is serial after all),
* and generates events based on what it received on the wire */
function Midi(uart, speed) {
this.uart = uart;
uart.setup(speed, { parity:'none', bytesize:8, stopbits:1 });
var state = 'W';
var message = '';
var p1 = 0;
var p2 = 0;
var channel = 0;
var emitter = this;
uart.on('data', function(data) {
for (var i in data) {
var b = data.charCodeAt(i);
if (state === 'W') {
if (b < 0x80) {
print("Out of order or non-command, discarding");
} else { // command
channel = b & 0xf;
message = b & 0xf0;
if (message == 0xc0 || message == 0xd0) {
state = '2';
} else {
state = '1';
}
}
} else if (state == '1') {
p1 = b;
state = '2';
} else if (state == '2') {
p2 = b;
if (message === 0x90) {
emitter.emit('noteOn', { chan: channel, note: p1, velocity: p2 });
} else if (message === 0x80) {
emitter.emit('noteOff', { chan: channel, note: p1, velocity: p2 });
} else if (message === 0xb0) {
emitter.emit('ctrlChange', { chan: channel, ctrl: p1, value: p2 });
} else if (message === 0xe0) {
emitter.emit('pitchBend', { chan: channel, value: p1 | (p2 << 7) });
} else if (message === '0xa0') {
emitter.emit('afterTouch', { chan: channel, note: p1, value: p2 });
} else if (message === 0xc0) {
emitter.emit('patchChange', { chan: channel, patch: p2 });
} else if (message === 0xd0) {
emitter.emit('channelPress', { chan: channel, press: p2 });
}
state = 'W';
}
}
});
};
exports.setup = function(uart, speed) {
return new Midi(uart, speed);
};