We’ve just added EXPERIMENTAL support for the Windows Runtime MIDI API to the develop branch, which enables machines with Windows 10 Anniversary Update installed to connect to Bluetooth Low Energy (BLE) MIDI devices.
However, there are some very important caveats:
Once a BLE MIDI device is paired, the WinRT MIDI API will always list it as available, even if the device is powered off.
Sending or receiving sysex messages is very likely to cause a hang.
The WinRT MIDI API may also hang when attempting to connect to a device. We’re currently working around this by running the connection request in a thread and killing it violently after a timeout, but this is clearly a Bad Thing.
These three issues all originate from Windows’ Bluetooth stack, and JUCE’s support for the API will be branded EXPERIMENTAL until a Windows update fixes them. If you have both a Microsoft Account and a Windows 10 Anniversary Update machine then please visit the following URLs (via Edge) to vote for the corresponding, related issues and increase the pressure on Microsoft to get them fixed.
None of these issues are present if you are using the WinRT MIDI API over USB.
Compile-time requirements:
Windows 10 Anniversary Update
Visual Studio 2015 with version 10.0.14393.0 of the Windows SDK installed (use the Windows add/remove programs settings dialog to modify your VS installation)
In the Projucer
Select JUCE_USE_WINRT_MIDI in the juce_audio_devices_module
Provide the path to the WinRT headers in the Windows SDK in “Header search paths” in a Visual Studio build configuration (probably C:\Program Files (x86)\Windows Kits\10\Include\10.0.14393.0\winrt)
Runtime requirements:
Windows 10 Anniversary Update if you want to use BLE, otherwise there’s an automatic fallback to the old MIDI API for older Windows versions; using the new JUCE API will not break compatibility.
I’ve just tested this new midi API albeit not with blutooth. The only thing I’ve noticed so far is the list of Active Midi inputs now looks a bit different; previously it looked like
Arturia MINILAB
Scarlett 18i6 USB
now it looks like
4 - Arturia MINILAB [1]
Scarlett 18i6 USB (1)
Any idea where the numbers come from or what they mean?
The only difference I’ve noticed so far using the new API is that the application fail to reload stored midi settings. The midi inputs are always unchecked upon restarting the application, and default midiout is unselected. Probably its the AudioDeviceManager that doesn’t manage to read back the settings. Storing seems to be alright, xml-file looks ok, but with the strange prefix and suffix as of above.
Ah no… Now it’s really f*** up. After having to update to the new asio sdk (which of course has nothing to do with this), the Device combo is empty and when trying to select my Focusrite usb driver, I get the Juce message “Error when trying to open audio device! No such device”. Any subseq try to get in contact with my Asio audio device fail.
When inspecting the debug output console i find following disturbing lines repeated twice when starting my app
FFUsb2Asio::FFUsb2Asio()
Exception thrown at 0x00007FF925CF7788 (KernelBase.dll) in Daw2.exe: 0x40080201: WinRT originate error (parameters: 0x0000000080040155, 0x000000000000004A, 0x00000015B07FD650).
+FFUsb2Asio::~FFUsb2Asio()
FFUsb2Asio::stop()
FFUsb2Asio::disposeBuffers()
-FFUsb2Asio::~FFUsb2Asio()
Just to be sure I myself wasn’t to blame for this… misfortune, I replaced the new juce_win32_Midi.cpp (that’s the file right?) with the previous one, and voila, it works again.
To quote Clouseau, Something must be terribly wrong here…
I’m finding the new API a lot more stable when sending sysex data very rapidly from USB-MIDI devices (hundreds of kilobytes of sysex data per second).
Legacy API is subject to very serious packet loss in these situations. However, I’m not sure whether this is a low-level problem or a JUCE Win32 MIDI problem (perhaps too small or to few low-level buffers?)
Considering my packet loss problem, I’m wondering whether the “fallback” solution would re-introduce these problems even when compiling with the new JUCE API. Can you recommend a way to test the new JUCE API specifically with the fallback? Old windows version but same binary? Or is there a smarter way?
My testing has shown that sysex messages shorter then 19 bytes fail to send with the new API, longer messages (which are generally split into multiple parts at a lower level than JUCE) seem to work well.
The fallback is the same as simply not using the new API. When you select the new Windows API in the Projucer then your application will check if the API is available at runtime and, if it is, it will use it, otherwise it will use the older JUCE MIDI code.
An old Windows version but the same binary would do it, or just de-select JUCE_USE_WINRT_MIDI.
Not being able to send short messages is indeed a serious problem. But I actually see a problem also when sending large data. The new API won’t even attempt to transmit a sysex message larger than 256 bytes.
The HRESULT error code is: E_INVALIDARG (One or more arguments are invalid.)
Reception of large sysex data works flawlessly, so it is really unfortunate that it is instead problematic to send data. Legacy API would send large data without any problems, but wouldn’t receive successfully =)
Aha, I missed the obvious. After some more digging I see that the max buffer size is indeed determined inside the JUCE library code in the MidiRTOutputWrapper constructor.
Would you consider increasing the this from 256 bytes to perhaps 64k?