Replies: 5 comments 6 replies
-
Hi! Thank you for asking! |
Beta Was this translation helpful? Give feedback.
-
I had a go at adding support for multiple MIDI devices with identical device names in JZZ.js, for node.js and the Jazz-Plugin and jazz-midi engines. I modified _refresh() so that if multiple identical device names were encountered, the names in _engine._outs and _engine._ins were replaced with unique device names (adding " #2", " #3", etc. after the device name). I keep the original device name and the device index in the info object. In the _engine._openIn() function, I check to see if the unique name and the original device name match. If they match, the device is opened using device name, just like before. If the names do not match, we have multiple devices with identical names and the device is opened using the device index. This works fine for me, on Windows 10, running node.js, with three Zoom MS pedals connected - all of which report device name "ZOOM MS Series". As far as I can see, I haven't broken anything, and the behavior for devices without identical names should be the same as before. The changed behavior only affects the Jazz-Plugin and jazz-midi engines for node.js, and the changes should only come into play if there are multiple devices with identical names connected, and only for the second, third, etc. devices. The first of the devices with identical names are opened using the name string, just as before.. When devices with identical names are disconnected or reconnected, using any of the other already opened devices with identical names might not work (depending on which device was removed). So the client code has to connect to the onChange event and open all the devices with identical names again. I'm currently looking into this, to see if any changes in JZZ.js is required, or if this can be handled purely on the client side. Aside from that, everything works as it should on my machine at least. My changes to the JZZ.js library are here: https://github.com/thammer/JZZ/tree/feature/support-identical-device-names The test-identical-device-names.js file is an example demonstrating how this works. I'd be very happy to tidy it up and submit a PR for you if you're interested in incorporating these changes into JZZ.js. |
Beta Was this translation helpful? Give feedback.
-
Hi! Thank you for looking into the issue! |
Beta Was this translation helpful? Give feedback.
-
As you mentioned, the fix should be done in the jazz-midi module. |
Beta Was this translation helpful? Give feedback.
-
My latest commits to the branch mentioned above lets the application handle the disconnect/connects. It seems to work fine no matter which devices I connect or disconnect. Although I haven't stress-tested it thoroughly yet. The problem I'm solving with these commits is that when a device with device name identical to another device is disconnected or connected, I don't think it's possible for JZZ.js to know which of these devices were connected or disconnected (jazz-midi doesn't tell JZZ.js which of these were connected/disconnected, just that one of them was). So JZZ.js has to assume that all devices were disconnected and that some of them were connected again. The application will need to respond to that in a reasonable manner, typically by closing all the devices with identical device names (if JZZ.js hasn't closed them already) and opening the devices again, as well as connecting MIDI input handlers. The solution I currently implemented requires the application to test if a disconnected or connected device is one of multiple devices with identical device names, by reading the deviceName property of the info object in the onChange handler and compare that to the deviceName of other devices. This leaks implementation details from inside the JZZ.js library to the application and makes the client slightly more complicated than necessary. A cleaner approach would be to have JZZ.js populate the diff object passed to the onChange handlers with removed and added devices, and close all the removed devices (including all devices with same device name as one that has been removed or added). Then the application's onChange handler could just loop through the inputs.added and outputs.added and reopen these. One way to do this in JZZ.js is to modify _postRefresh() so that after calling
it would do
Then the Jazz-Plugin / jazz-midi engine could add the extra devices to the diff object, whereas the other engines would do nothing. Here's an example where one of the devices are removed (it doesn't matter which, the diff would be the same)
If you're interested in merging this stuff into JZZ.js, I'm happy to hear your thoughts on how that could best be done, and to do my best to make a proper PR for you. If not - then what I have done so far solves the problem for me in the application I'm creating, and I can keep using my own fork just for my application, and just be grateful for all the work you have put into the JZZ.js library so far, sharing the source code to JZZ.js and allowing me to use it as I do. I'm happy either way :-). |
Beta Was this translation helpful? Give feedback.
-
Hi.
I'm developing a node.js app using JZZ.js. I have 2 MIDI devices with the same device name in Windows ("ZOOM MS Series"), and I would like to access both using JZZ,js.
If I loop through info().inputs, I can see both devices. The JZZ docs says I should be able to open the port by index. https://jazz-soft.net/doc/JZZ/midiin.html.
However, as far as I can see, even if I specify an index as parameter to the openMidiIn() function, JZZ looks up the device name and passes that to impl.plugin.MidiInOpen(), in line 923. So in jazz-midi, the plugin function napi_value MidiInOpen(napi_env env, napi_callback_info args) is always called with a string input, and as a result MidiInOpen(const char_type*, void*) is called, with the device name as parameter.
Since the jazz-midi library has a function that allows opening a MIDI device given an index, MidiInOpen(int, void*), I was hoping to be able to call that function from JZZ. As far as I can see that is not currently possible.
The only solution I've been able to come up with so far is for me to do a slight modification to JZZ.js so that if the user passes an index (number) to midiInOpen(), that index is sent to the plugin function napi_value MidiInOpen(napi_env env, napi_callback_info args), and MidiInOpen(int, void*) is called in jazz-midi.
I'm not sure that is the best approach. I'm concerned I might break something for other platforms than node.js/Windows. But that's what I'm currently exploring. I'm not there yet, but hope to be able to figure this out in a couple of days.
I'd appreciate any advice on how to proceed if anyone has experience with this. Otherwise, I'll just post my findings here as I stumble along :-).
Beta Was this translation helpful? Give feedback.
All reactions