-
Notifications
You must be signed in to change notification settings - Fork 275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows 10 UWP MIDI API to enable MIDI over Bluetooth? #145
Comments
Not aware of any plans as such. |
(ps., leaving this open in case anyone wants to contribute an implementation..) |
In case it's a motivation for anyone to work on this: The new MIDI API also brings other improvements such as being able to open a MIDI port from more than one application at the same time. |
hello, I've been working on a fork of RtMidi which starts to have some support for UWP MIDI if anyone's interested : https://github.com/jcelerier/RtMidi17/blob/master/rtmidi17/detail/winuwp.hpp (feel free to port it back to RtMidi proper) |
Nice work on that fork! Personally I'd try putting all the UWP stuff into a separate DLL to support older OSes but this is definitely a great start. |
@jcelerier What a timing! I just started fiddling with C++/WinRT MIDI myself with the aim of using it as the windows implementation in a cross platform CMake based midi library. Nice work 👍 |
Fantastic job, Microsoft. |
Does anyone know if the new UWP MIDI format supports making virtual ports? As that's an issue I was about to make |
@marksyzm - The UWP WIn32 API does not support that. (At least not using the Win32 wrapper) Steinberg has enabled "Bluetooth" MIDI in Cubase 12. which is actually just UWP MIDI, and you can see the several warning that things may not work, and it's got nothing to do with "older" devices. (unless Microsoft/Steinberg points out the details why this is ) Cubase is probably using that WIN32 wrapper or an alternative coded inhouse one. I used the wrapper from Microsoft in a client to enable UWP MIDI. and bumped into issues. No matter the Microsoft wrapper or custom one, the key problem is not in the WIN32 but in the core of UWP. For example, UWP cannot handle multiple same hardware devices and upon plug/in out weird things happen. I cannot recall all the details, but I have the nitty gritty details and evidence of debugging somewhere . After that nightmare, dumped the whole UWP MIDI part. The developer of the wrapper at Microsoft informed the port naming issues are due to Microsoft's implementation of UWP and it would be up to the Microsoft developers to fix this. Mainly issues arise when you unplug or plug a device , not only Bluetooth, and you can read this between the lines in the Cubase 12 warnings as well .Sysex is another problems. I have the Bobpad (great features, terrible quality) and it does a lot of sysex. UWP MIDI has been broken from the start since Windows 10 came out. No evidence win11 is better - still have to try it. I informed the person who is supposed to lead all the MIDI/audio Windows stuff (you can find him easily on twitter or other social networks), but nothing happened. It seem no one can push the UWP team at Microsoft and musical stuff just does not have priority. It is ultimately frustrating. You can find several posts on Microsoft Forums as well about this topic that jcelerier pointed out. Nobody at the dev team at Microsoft cares or perhaps there isn't even a real solution. Probably nobody at Microsoft likes to read this, but well , we need to keep raising this flag. A few more posts: https://www.midi.org/midi-articles/midi-enhancements-in-windows-10 With MIDI 2.0 UMP coming, the question is really if Microsoft will revamp the whole UWP API (and finally fix this as well). Likely they have to if DAW's need to use MIDI 2.0 since it is unlikely Microsoft will change the Win32 API, and that should then go along with a well supported and stable Win32 wrapper. But now comes the worry, if the new UWP MIDI API only support UMP, the legacy MIDI issues may stay forever. Hopefully Bitwig or other DAW providers can push, but Steinberg seems to have given up and "adopted" the bugs What really would be nice is that after 6 years to see a formal statement and reaction from Microsoft. And BTW, on Ubuntu BLE MIDI it is now starting to work pretty well - even with the BobPad. There is a new SDK, WinAppSDK a.k.a Project Reunion) For those who wish to play around with UWP MIDI API: For those who wish to use the UWP Win32 wrapper (requires Visual Studio 2015) |
I'm implementing Windows UWP MIDI API to enable BLE MIDI (Bluetooth MIDI) in #299.
Building requires: Visual Studio Community 2019 |
Very cool! I'm reviving a project soon so your timing is perfect :) |
In #299, I've implemented MIDI port open/close and MIDI message output. |
In #299, I've implemented MIDI message input. |
Fantastic! Thanks so much for your hard work |
Adding another issue found a few years back: Unplugging an BLE device still causes the MIDI device to show up in the enumeration of UWP MIDI devices. Not sure if this still happens with the latest W10 and W11 versions. With the coming of MIDI 2.0 perhaps Microsoft has picked up MIDI UWP and started fixes,. YMMV. Take a look a above reported problem before creating new issues. A warning in RTMIDI possibly might be justified that potentially major problems may persist in the UWP implementation. |
@symdeb The issue of some MIDI OUT port names being simply |
As far as I used UWP about 3 years ago, after enumerating, then adding/removing devices and then enumerating once again it is a problem to correctly indentify which ports were added or removed because of the port naming issues. Perhaps MS has made fixes in the past three years for BLE/UWP. |
I've found that Windows UWP timestamp bug. So I've added a workaround to fix the wrong timestamps. For example, YAMAHA MD-BT01 V1.0.7 (the latest firmware) generates such BLE packets, so the timestamps are incorrect without the workaround. |
@symdeb "What really would be nice is that after 6 years to see a formal statement and reaction from Microsoft. Hi All I just ran across this thread today. Naming issues we know about. BLE SysEx is something else we fixed a few years ago, so if there are still problems there, they are not known to the team. But some of the other issues reported here have never popped up before, like wrong timestamps from the Yamaha BT01. Were they reported in some way? I don't know if they were and somehow lost, or if they were never actually reported. I also don't know how many of the bugs here, going back to 2017 in this thread, (other than naming, of course) are ones folks are still running into. Aside: not sure why people keep referring to WinRT MIDI as a "wrapper". It's not. It talks to the same kernel streaming layers WinMM/MME MIDI API does. (unless you're referring to Dale's C++ wrapper which was needed prior to C++/WinRT. That's actually a wrapper :) ) Pete - Microsoft |
I reported the issue with the timestamps generated by YAMAHA MD-BT01 on the Feedback Hub at the following URL.
If I understand correctly, there are other issues with BLE-MIDI packet parser in WinRT MIDI. I created a test data set for BLE-MIDI packet parser. In my experiments on Windows 10 21H2, the following BLE-MIDI packets are incorrectly parsed by WinRT MIDI.
The following two BLE-MIDI packet parsing issues were reported in the Feedback Hub above.
|
@trueroad thank you so much for the detailed response. We will look into this. Pete |
Not sure if the sudden interest for the issues with MIDI UWP is related to adding MIDI 2.0 in Windows. No matter what, It would be nice if Microsoft could list all the claims of issues mentioned above and provide feedback if each of them has been fixed (when in the kernel ) or "cannot reproduce" and when. The issues are not limited to BLE but also to enumeration. Regarding:" not sure why people keep referring to WinRT MIDI as a "wrapper": The "wrapper" refers here to the code that wraps around the UWP API to make it available for legacy (C) windows clients, which can be found at https://github.com/stammen/winrtmidi. The README states: _This GitHub WinRTMidi project wraps the Windows Runtime Windows::Devices::Midi API in a Win32 DLL I used two identical MIDI to USB devices with multiple MIDI ports. 1/ Port naming issue and port re-numeration after hot in/out plug event I programmed a C client for Mac OSX, Linux MIDI ALSA sequencer, ALSA raw and Win32 API and could make it work to update the ports status by enumeration when hot plugging devices, when some ports were already open to identify after a hot plug event to re-enumerate to trace back in the list which ports after enumeration mapped to the port after the hot plug event. This worked well except using the windows UWP API. After trying to fix the wrapper, the conclusion was that there is a problem in the windows UWP. The bug is in the UWP API call "MidiOutGetInterfaceID" After having a discussion with Dale via email, this was confirmed on Feb 28, 2020: "Unfortunately the port naming issue is a Windows 10 MIDI bug that has not been fixed. There is nothing I can do about it". 'They are already aware of this issue but have not fixed it in Windows 10. You can use the Feedback Hub app in Windows 10 to report your issue". The issues was posted on the feedback up, but can't recall any update. The feedback seems a one way path.Perhaps catch up with the team if they may remember this ? if confirmed that this was fixed, would be glad to spend some time in the nearby future (or new API with MIDI 2.0) to verify it. 2/ Port change callback issue For this item, did not receive a response. BTW, Here is the contents of the email of March 22, 2020: [1] What is left is the port change callback. Is there a way to uniquely identify the port from the port callback? In port_change_callback(const void *portWatcher, const int update) I can use gWatcherPortNameFunc(portWatcher, 0); [2] Would it be possible to add a custom data pointer to the data and port change callback ? This can avoid to declare a global variable to the client application data, The legacy win32 API supports this as well, for example: void change_callback(const void *portWatcher, const int update, void *ptr) void input_callback(void input_port, double timeStamp, unsigned char message, unsigned int nBytes, void *ptr) and declare this pointer in gMidiInitFunc(change_callback, midiPtr, ptr); There are other issues with UWP MIDI, for example, when a Bluetooth device is not present it still gets returned by the PortWatcher and when accessing it causes a crash. Hopefully these issues can be addressed in the next update of UWP MIDI. I would like to open the new port without having to close all already opened ports that have a gMidiPtr already assigned in the OpenFunc. gMidiOutPortOpenFunc(midiPtr, id, &gMidiPort); is there a way to get the ID from the Portwatcher in the callback ? I tried to add in WinRTMidi the following new function to obtain the ID of the port, but calling it with 0 as index crashes. To find which port was removed, can only the "name" be used to identify it ? To obtain the (unique) Id of the port would be perfect. --- end note Even if the UWP API was changed and fixed these issues, the wrapper is not supported anymore. Hopefully someone can pick this up and provide an updated wrapper on Github to make the fixes accessible for Win32 legacy application ? What also could help is a to have a Microsoft test application to test /validate enumeration and MIDI functionality to that developer can create units tests and validate the API they developed works as expected using a legacy Win32 client. |
I only just found this GH issue randomly, which is why I'm replying here. FWIW, with C++/WinRT, the wrapper Dale (Dale and I are on the same team) wrote is no longer needed, but he does have good code in there for fixing up names. C++/WinRT is standard C++ code with a nuget package. The wrapper was created because the only reasonable way to use WinRT from C++ at the time was C++/CX which had proprietary extensions. Device/Port naming is being redone as part of the MIDI 2.0 project which will go public later this year. After the initial release, WinMM MIDI and WinRT MIDI will have their implementations repointed to the new code to get some of the new features, but apps which use the new API (which is also built on WinRT) will have access to everything. Device hot plug/unplug is made worse with the name bugs. I agree. But on that specific thing, what I really want is for device manufacturers to implement USB iSerialNumber in their devices so that the different operating systems don't have to jump through hoops to figure out if the device is the same one that was previously plugged in. Without that, we don't really have a reliable unique ID for a port. Other operating systems have the same issues with identifying devices, especially when there's more than one of the same. But maybe they are a little cleaner about the impacts. The BLE connection issue is known as well. The timestamp issue was new, but I've made folks aware now. The connection issue has to do with how BLE devices work on Windows compared to other Bluetooth standards: we don't know if the device is still there until we try to access it. We need to handle this better, though. The new USB Driver, API, SDK, and other future transports are all open source (edit: unless they are existing code. We're investigating the right approach for BLE going forward). The repo at github.com/Microsoft/midi will be public as soon as the MIDI Association votes to approve the latest standards update (the vote is in progress now). I can't open the repo until that NDA is lifted. But once that happens, we will be happy to take issues, PRs, etc. in a more transparent way. Feedback hub is necessary for some things, but it's difficult to close the loop there. |
It is great to have someone from Microsoft here paying attention as the feedback hub did not provide any progress for the many posts placed in the past 6 years . I have been using MSYS /GCC which I don't think it can link nuget packages. A working Win32 wrapper for WINRT would be very welcome. I can't recall ever having unrecoverable hot-plug issues with Mac OSX (BLE+USB) and ALSA (BLE+USB) Linux and the legacy Win32 (USB) devices. Could identify the open/close port after hot plug without issues, even using 2 identical devices. Some devices do not provide serial-numbers though. |
I'll keep in mind the non-Nuget folks. We'll have the winmds and whatnot on github for people who can't use the package manager. But any wrapper would need to be written and maintained by others. MIDI 2.0 is significantly more complex and continues to evolve (new transports etc.) so better to use the delivered API and SDK directly if at all possible. I really don't think a wrapper will be needed, but I'm not familiar with how GCC on Windows works today, or what it can consume. But C++/WinRT has support for more than just Visual Studio. Everything it produces is just standard C++. https://en.wikipedia.org/wiki/C++/WinRT BLE: Thanks. I said "how BLE works on Windows", but that likely wasn't exactly correct. It's more about how the BLE/GATT APIs used worked on Windows at the time BLE MIDI was written. It's being looked at with an eye on these and other concerns, and also with it being fully open source. Pete |
I guess this issue should be closed as RtMidi 6.0.0 adds support for UWP. @Psychlist1972 would you be able to comment on the fact why most MIDI output devices do appear to have nonsensical device names in Windows 10? @trueroad added a workaround for this in the RtMidi code but the workaround doesn't work if there's more than one of the same device. I added another pull request to address this (#321), but it would be good to know why this happens in the first place. Is it to be considered an OS bug? |
I consider it an OS bug with our enumeration code for WinRT MIDI 1.0. It's being addressed as part of the stack update, but that would mean anything to WinRT MIDI until next year when we repoint the API to the new service. Names come from so many places, and devices are not consistent in how they supply them, and there are differences depending on driver model used, so some (in my opinion) incorrect choices were made when sorting out naming for that API. WinRT MIDI's uptake is low compared to WinMM, so we haven't prioritized changes there and instead are dealing with it in the new stack. FWIW, this is where we are with the new stack today: Pete |
Thanks for the explanation Pete. As you probably know much more than us about the issue with output port names, maybe you could have a look at the PR I mentioned (#321) and just confirm that in general RtMidi is doing the right thing? Is the substring comparison in that function even sensible, or should it instead only check for exact matches?
Unfortunately I think this is also a bit of a chicken/egg problem. At least for me the naming issue is definitely one reason why I wouldn't consider enabling the WinRT API by default in my project (@OpenMPT) yet and still use WinMM as the default choice, even though I would be really happy to offer the improvements it brings to my users. |
The substring search is probably reasonable, but needs testing, of course. Devices have all sorts of names, and some include "MIDI" in various positions. Note that this will change when we repoint the WinRT and WinMM APIs, and the related device enumeration, to Windows MIDI Services in 2024, so you'll want to make sure your code doesn't break there. After that change, the names will be consistent across APIs. Pete |
Hi. I am a music hobbyist with no programming experience. The developer of certain music software that I am interested in purchasing (XotoPad 2) advised me that he uses the rtmidi library. When I inquired of this developer whether I would be able to use XotoPad 2 with MIDI over Bluetooth on a Windows 10 tablet, he indicated that the rtmidi library would need to be updated to use the Windows 10 UWP MIDI API. Can you please let me know if there are any plans to update the rtmidi library to use the Windows 10 UWP MIDI API to permit MIDI over Bluetooth, rather than the Windows Multimedia API that I understand rtmidi currently uses?
Thank you!
The text was updated successfully, but these errors were encountered: