node-midi
node-midi copied to clipboard
Method to list devices and listen for device changes
There should be a method dedicated to listing the available devices, that doesn't require creating a (stateful) midi.input
or midi.output
instance.
There should a also be a way to listen for changes to the device list, so the application can act when a device is detected or removed.
Having events would be nice but it doesn't look like something the library we wrap supports: http://www.music.mcgill.ca/~gary/rtmidi/
Listing the devices is certainly possible though, even if I have to do a for() loop over the devices. And right now, I'm also scanning for new devices at regular intervals.
Mere polling like this could be implemented until upstream gets support for device change events.
@awwright, I agree, but you could do that by yourself. I needed the same, so I made the following script:
// midi.js
const midi = require( 'midi' );
module.exports = {
/**
* Use property to store kind of a global input object,
* so we won't create a new MIDI instance all the time
*/
input: null,
/**
* Returns a list of device names
*/
list: function() {
if ( !this.input ) {
this.input = new midi.input();
}
const devices = [];
const size = this.input.getPortCount();
for ( let i = 0; i < size; i += 1 ) {
devices.push( this.input.getPortName( i ) );
}
return devices;
},
};
// midiInputChangeListener.js
const midi = require( './midi' );
function checkDeviceListChange( callback = () => {}, length = 0 ) {
const newDeviceList = midi.list();
let newLength = length;
if ( newLength !== newDeviceList.length ) {
newLength = newDeviceList.length;
callback( newDeviceList );
}
setTimeout( () => { // this line should be changed to be more async
process.nextTick( () => { checkDeviceListChange( callback, newLength ) } );
}, 100 );
}
module.exports = function( callback = () => {} ) {
let deviceList = [];
checkDeviceListChange( ( newDeviceList ) => {
oldDeviceList = [ ...deviceList ];
deviceList = newDeviceList;
callback( deviceList, oldDeviceList );
} );
}