Skip to content

Instantly share code, notes, and snippets.

@jsantell
Created June 28, 2019 16:24
Show Gist options
  • Save jsantell/2c30bd69517eebba708d44a6213d5369 to your computer and use it in GitHub Desktop.
Save jsantell/2c30bd69517eebba708d44a6213d5369 to your computer and use it in GitHub Desktop.
MIDI to OSC
const midi = require('midi');
const { Client } = require('node-osc');
const MIDI_INPUT = 1;
const ADDRESS = 'localhost';
const PORT = 8886;
class MIDI2OSC {
constructor(midiInput=MIDI_INPUT, address=ADDRESS, port=PORT) {
this.client = new Client(address, port);
this.input = new midi.input();
this.inputCount = this.input.getPortCount();
this.inputName = this.input.getPortName(midiInput);
this.input.openPort(midiInput);
this.input.on('message', (delta, message) => {
this.send(message);
});
console.log('Found inputs:');
for (let i = 0; i < this.inputCount; i++) {
console.log(`${this.input.getPortName(i)}${i === midiInput ? ' [selected]' : ''}`)
}
}
send(data) {
console.log(data);
const oscData = this.midiToOsc(data);
if (oscData) {
const [command, value] = oscData;
console.log(`Sending: dirtgl/${command}:${value}`);
this.client.send(`dirtgl/${command}`, value);
}
}
/**
* Maps midi commands from LaunchControl to OSC address/value,
* device-configuration specific.
*/
midiToOsc(data) {
const [status, data1, data2] = data;
const channel = status & 0b00001111;
const message = status >> 4;
let type;
switch (message) {
case 8: type = 'noteOff'; break;
case 9: type = 'noteOn'; break;
case 10: type = 'keyPressure'; break;
case 11: type = 'controlChange'; break;
case 12: type = 'programChange'; break;
case 13: type = 'channelPressure'; break;
case 14: type = 'pitchBend'; break;
default: type = `UNKNOWN-${message}`;
}
// https://users.cs.cf.ac.uk/Dave.Marshall/Multimedia/node158.html
let command = null;
let value = null;
if (type === 'controlChange') {
const note = data1;
value = data2;
if (note >= 13 && note <= 20) {
command = `send-a/${note - 13}`;
} else if (note >= 29 && note <= 36) {
command = `send-b/${note - 29}`;
} else if (note >= 49 && note <= 56) {
command = `pan/${note - 49}`;
} else if (note >= 77 && note <= 84) {
command = `fader/${note - 77}`;
}
}
else if (type === 'noteOn') {
const note = data1;
//const value = data2;
if ((note >= 41 && note <= 44) ||
(note >= 57 && note <= 60)) {
value = note > 44 ? (note - 57 + 4) : note - 41;
command = `scene-select`;
} else if ((note >= 73 && note <= 76) ||
(note >= 89 && note <= 92)) {
value = note > 76 ? (note - 89 + 4) : note - 73;
command = `execute`;
}
}
return command != null && value != null ? [command, value] : null;
}
}
const converter = new MIDI2OSC();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment