mpp2vc/mpp2midiout.js

79 lines
2.8 KiB
JavaScript

var midi = require('midi');
var MidiOutput = new midi.output();
var portCount = MidiOutput.getPortCount();
var portConnected = false;
console.log(`Found ${portCount} MIDI ports:`);
for (let portNumber = 0; portNumber < portCount; portNumber++) {
let portName = MidiOutput.getPortName(portNumber)
console.log(`Port ${portNumber}: ${portName}`);
if (portName == "TiMidity 128:0" && !portConnected) {
MidiOutput.openPort(portNumber);
portConnected = true;
}
}
if (!portConnected) {console.error("Couldn't find MIDI port"); process.exit(1);}
var MIDI_TRANSPOSE = -12;
var MIDI_KEY_NAMES = ["a-1", "as-1", "b-1"];
var bare_notes = "c cs d ds e f fs g gs a as b".split(" ");
for(var oct = 0; oct < 7; oct++) {
for(var i in bare_notes) {
MIDI_KEY_NAMES.push(bare_notes[i] + oct);
}
}
MIDI_KEY_NAMES.push("c7");
var pressedKeys = {};
var gMidiOutTest = function(note_name, vel, delay_ms) {
var note_number = MIDI_KEY_NAMES.indexOf(note_name);
if(note_number == -1) return;
note_number = note_number + 9 - MIDI_TRANSPOSE;
//MidiOutput.wait(delay_ms).send([0x90, note_number, Math.floor(vel)]); //JZZ
setTimeout(function(){
// maintain on/off order
if (vel) { // if this is a start note
if (pressedKeys[note_number]) // and the key is pressed
MidiOutput.sendMessage([0x90, note_number, 0]); // send stop note before sending start note
MidiOutput.sendMessage([0x90, note_number, vel]); // go ahead…
pressedKeys[note_number] = true; // and the key is now pressed.
} else { // if this is a stop note
if (pressedKeys[note_number]) { // and the key is pressed
MidiOutput.sendMessage([0x90, note_number, vel]); // go ahead…
pressedKeys[note_number] = false; // and the key is now released.
} // else the key is already stopped; ignore.
}
}, delay_ms);
}
var Client = require("mpp-client");
global.gClient = new Client(process.env.MPU || "wss://www.multiplayerpiano.com:443");
gClient.setChannel(process.env.MPCH || "lobby");
gClient.start();
gClient.on("hi", ()=> console.log("MPP Client Ready"));
gClient.on("n", function(msg) {
var t = msg.t - gClient.serverTimeOffset + 1000 - Date.now();
for(var i = 0; i < msg.n.length; i++) {
var note = msg.n[i];
var ms = t + (note.d || 0);
if(ms < 0) {
ms = 0;
}
else if(ms > 10000) continue;
if(note.s) {
gMidiOutTest(note.n, 0, ms);
} else {
var vel = (typeof note.v !== "undefined")? parseFloat(note.v) : 0.5;
if(vel < 0) vel = 0; else if (vel > 1) vel = 1;
gMidiOutTest(note.n, vel * 127, ms);
setTimeout(gMidiOutTest, 1000, note.n, 0, ms); // limit note presses to 1 sec
}
}
});