node-midi
node-midi copied to clipboard
Disconnect/Reconnect events?
Firstly, thanks for making this! Having fun with an 8x8 neotrellis button matrix over midi.
If I disconnect the device (after successfully connecting before), everything works perfectly once I reconnect the device.
I was hoping to send midi events to the device after it reconnects (e.g. to reset device state such as brightness, colour, etc per button). Is there a way to detect if a midi device disconnected & reconnected? I had a brief glance at the c++ implementation of input.cpp but I lack familiarity with how that might look.
I would imagine to emit an event for this, so an implementation like mine can use that as a trigger to re-sync all device states.
The only way I've found to do this (using this MIDI library) is to constantly poll available devices. I've done this in a project of mine and made a similar service available here.
Likely not the solution you're looking for, but I was in a similar situation.
The only way I've found to do this (using this MIDI library) is to constantly poll available devices. I've done this in a project of mine and made a similar service available here.
Likely not the solution you're looking for, but I was in a similar situation.
Thank you, cool projects too!
.. well the console says MidiOutWinMM::sendMessage: error sending MIDI message.
when sending data to a disconnected device.
it would be much cleaner if this message was thrown into a error handler on midi.Output()
..
like literally.. output.on("error"...
or something.
this is kind of annoying tbh.
also polling the device list is not really a good idea.
imagine a usb midi device disconnecting for a second due to a loose usb connection.. it could re-appear in polling before you check the device list if it's firmware takes no time to initialize.
@tiagosiebler: rtmidi-python exits when this occurs..
so.. it is catchable somwhow. (i'm digging through sources atm)
there is also this in node-midi:
https://github.com/justinlatimer/node-midi/blob/1356985b1fc0aef919dc0e7abb8918ebe83522be/src/input.cpp#L217-L226
https://github.com/justinlatimer/node-midi/blob/1356985b1fc0aef919dc0e7abb8918ebe83522be/src/output.cpp#L145-L154
which does not reset to false when I unplug my midi device:
let tick = 0;
while(true) {
tick++;
tick %= 2;
try {
console.log("input:", input.isPortOpen());
console.log("output:", output.isPortOpen());
output.sendMessage([176,71,tick * 127]);
} catch (e) {
console.log("such e", e);
}
await sleep(200);
}
first of all, I'd suggest upgrading to rtmidi 6.0.0 http://www.music.mcgill.ca/~gary/rtmidi/ which has been released on 3rd of august this year.
secondly I suggest adding this to node-midi https://github.com/justinlatimer/rtmidi/blob/c01a721217ab5b83a44e9b01f94cbea2e952a995/RtMidi.h#L79-L119
the authors page also lists a couple error handling cases. might be a good idea to include them in node-midi. http://www.music.mcgill.ca/~gary/rtmidi/index.html#error
will leave for today in half an hour so.. I'll fork this tomorrow and see what I can do.. (cuz when I set my laptop into sleep, I want it to reconnect after it wakes back up)
edit:
this half hour is over now..
my solution to this problem so far:
const sleep = time => new Promise(resolve => setTimeout(resolve, time));
const input = new midi.Input();
const output = new midi.Output();
const getMidiDevices = () => {
const inp = {}, out = {};
const inpc = input.getPortCount();
const outc = output.getPortCount();
for (let i = 0; i < inpc; i++) {
inp[input.getPortName(i)] = i;
}
for (let i = 0; i < outc; i++) {
out[output.getPortName(i)] = i;
}
return {inp, inpc, out, outc};
};
let midiDevices = getMidiDevices();
console.log(midiDevices);
input.openPort(midiDevices.inp.nanoKONTROL2);
output.openPort(midiDevices.out.nanoKONTROL2);
// ...
// various stuff that just sends commands to voicemeeter etc.
// ...
let tick = 0;
while(true) {
tick++;
tick %= 2;
try {
const old = JSON.stringify(midiDevices);
midiDevices = getMidiDevices();
if (old !== JSON.stringify(midiDevices)) {
console.log("change detected:", midiDevices);
console.log(midiDevices.inp);
if (!("nanoKONTROL2" in midiDevices.inp))
console.log("disconnecting");
if (input.isPortOpen()) input.closePort();
else {
console.log("connecting input to", midiDevices.inp.nanoKONTROL2);
if (!input.isPortOpen()) input.openPort(midiDevices.inp.nanoKONTROL2);
}
if (!("nanoKONTROL2" in midiDevices.out))
console.log("disconnecting");
if (output.isPortOpen()) output.closePort();
else {
console.log("connecting output to", midiDevices.out.nanoKONTROL2);
if (!output.isPortOpen()) output.openPort(midiDevices.out.nanoKONTROL2);
}
}
if (output.isPortOpen()) output.sendMessage([176,71,tick * 127]);
} catch (e) {
console.log("such e", e);
}
await sleep(200);
}
Hi, Any progress on this issue? Any suggestion on what other lib does this?
Have you seen this fork: https://github.com/Julusian/node-midi ?
Actively maintained, contains several fixes and QOL improvements. Not sure if it solves the problems you’ve highlighted, but probably worth a check.