Developer Preview 7
Pre-releaseDeveloper Preview 7
This release includes a significant number of bug fixes as well as a few other changes.
Late-breaking Arm64 issue with workaround: #430
Bug fixes may be found with this query: dp7-fixed
You should run Windows Insider Developer or Canary channels to use this release.
NOTE: There are Canary builds which are starting to ship with Windows MIDI Services preinstalled. Those versions are not yet compatible with DP7. See #434 for the version to use when it is available.
Changes
WinMM Backwards Compatibility
An early version of the backwards compatibility shim is in place. This is implemented by the wdmaud2.drv which is loaded by WinMM, and forwards calls to the MIDI Service.
Only KS (new UMP driver) and KSA (MIDI 1.0 class driver and vendor drivers) devices currently work with the WinMM MIDI 1.0 API. (USB using the new driver, and USB MIDI 1.0 using older drivers), and only Group Index 0 is supported. (One Input and one Output). We'll add the other groups in soon.
We are interested in the experience you all have with this shim, outside of the Group Index 0 limitation. Specifically, if you have other vendor MIDI drivers installed, and if you run into any conflicts there.
Here's a short video showing the WinMM support in action
https://www.youtube.com/watch?v=Oa6_pVveqPI
Note: Without the new version of AudioEndpointBuilder
available in the latest Insider builds, you will see duplicate devices in device manager
Note also that 32-bit apps like MIDI-OX do not currently work with the WinMM redirection. They require the in-box WOW version. Additionally, apps using MIDI 1.0 APIs other than WinMM are untested and unlikely to work.
WinRT MIDI 1.0 Backwards Compatibility
This is not yet in place
MMCSS Usage
By default, the input side of a MIDI connection no longer uses MMCSS threads, but instead uses normal high priority threads. These are lower priority (15 rather than 25). Performance seems good so far in our testing.
Message Buffer Sizes
To date, the cross-process buffers have been set to PAGE_SIZE (1000 bytes) for the kernel streaming (USB, primarily) device connections. In this update, they are now set to PAGE_SIZE * 2, like the client buffer. We may experiment with this value a bit as a result of internal and partner testing.
Message Scheduler Priority
The priority of the worker thread for message scheduling is now set to the same as incoming messages (15)
Timer Interval
The MidiClock
class now has functions to enable and disable the minimum timer interval available for applications. The MIDI Console uses this at startup, and restores when it is closed. In some cases, this will greatly improve the message send/receive speed. In practice, many/most musician PCs are already running at the lowest timer interval available due to choices made by other applications or drivers.
What does this impact? One major item is the thread sleep time. If you Sleep(1), then you will get the system minimum sleep interval rather than just 1ms. By default, that interval is 15.625ms, but applications can set it to 1ms in most cases, and drivers or configuration can go down as low as 0.5ms.
Relevant functions:
MidiClock::GetCurrentSystemTimerInfo()
MidiClock::BeginLowLatencySystemTimerPeriod()
MidiClock::EndLowLatencySystemTimerPeriod()
Those calls wrap timeBeginPeriod
and timeEndPeriod
for convenience, and for languages which cannot easily make win32 API calls. For your convenience, the values are represented in MIDI Clock ticks.
System-wide, Windows will use the lowest value requested by applications or drivers. There's some subtlety to that, however. You may read more about it here.
libmidi2 Update
Updated to version 0.13 of Andrew Mee's libmidi2
. This is used in the service and SDK for message translation
COM Interface Name Changes
- To comply with in-box review requirements,
Abstraction
was changed toTransport
in service interface and parameter names. This is a breaking change if you're using the service interfaces directly in any way. This does also mean that this version of the service cannot be used with older versions of the SDK. The SDK has been updated to use the new interfaces.
Updates to Registry entries
Changed Abstraction
to Transport
in the registry entries which control loading transports. Also added a check in the service transport enumeration code to not fail if there are duplicate entries (by class id). However, we recommend that you do not have duplicate entries in there because it could get confusing to understand which are in use.
Added a registry DWORD value to disable MIDI 2.0 discovery and protocol negotiation globally across all transports. This is only useful for debugging issues. If the value is 0, then discovery and protocol negotiation are disabled. Any registry changes require service restart to be picked up.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows MIDI Services\Midi2DiscoveryEnabled
When Windows MIDI Services is in-box, this section of the registry will be protected, and can only be changed by someone who takes over control of that part of the registry first. The intent here is to lock these changes to just developers and advanced users who need to debug, try out new transports before they are shipped in box (or custom transports they develop), etc.
Removed unfinished transports
The Virtual Patch Bay, Network MIDI, and BLE MIDI transports are no longer installed by the main installer, and their registry keys are no longer created. These have been moved to another installer because they are on a different release schedule. These will be released out-of-box for technical users/developers before being rolled into Windows.
SDK Changes
NuGet package
- Rearranged the NuGet package version number so it worked with NuGet
PackageReference
versioning. - Aligned setup package version numbers with same.
The NuGet package still contains the implementation libraries which must be copied to your .exe folder. Centralized activation is not yet in place.
NuGet package C++ Specifics
Keeping the NuGet package version correct in the C++ samples has been a constant thorn in my side. It's not easy, because NuGet has only meh support for C++ projects compared to C# projects. C++ projects must always reference an exact NuGet package version, and there are several checks in the project file which reference that exact version. So here's what I did:
- Updated the build process so the C++ samples always reference the Midi2 NuGet that was last built. This required setting a specific version in the
packages.config
through the build script. - To make this easier in the samples, the C++ sample projects also define
WindowsMidiServicesSdkPackage
which is updated by the build process. The variable is only used for substitution in the vcxproj in all the places which reference the exact NuGet package version, so you can easily see how it's used and decide if you want to manually update those values or include the variable in your own projects. This is not a requirement for your own apps, but it does make MIDI SDK versioning easier. - Unfortunately, I couldn't just define that in a .props file and include with the package, because it's needed to find the package in the first place
- That doesn't mean that when you download the samples they will immediately work. You'll still need to ensure you put the NuGet package in a place you have set up as a local NuGet repo, and that you install and restore the packages in Visual Studio
End result is the projects, without manual intervention, always correctly reference the NuGet package that they were built with.
NuGet package C# Specifics
The C# NuGet references also needed some adjustment so that they always pick up the latest installed package.
- Updated Console and settings app (both C#) to use latest Midi2 NuGet package through the correct
PackageReference
setting (this required the version changing mentioned above). C# has better support for this kind of update vs. C++. The version string used for C# cannot be used for C++ because C++ does not supportPackageReference
, onlypackages.config
- Updated C# samples to the same.
Reduction in SDK binaries
DP7 cut the number of SDK binaries down to just two. The namespaces are as they were, but other than the initialization code, are all located in Microsoft.Windows.Devices.Midi2.*
.
At this time, the SDK still requires the use of a manifest file and local implementation libraries for type activation.
You must copy the
Microsoft.Windows.Devices.Midi*.dll
files into the folder where your exe lives. You must also copy the manifest file there and ensure it's named<myExeName.exe>.manifest
New utility: MidiUsbInfo.exe
This is a utility application provided as part of the SDK runtime. Use it to see how Windows (not Windows MIDI Services) sees the kernel streaming devices on the system. This has been provided as a simpler alternative to pnputil
.
Updates to MidiDiag.exe
MidiDiag.exe
, which is also installed with the SDK runtime, now includes information on the system timer resolution and also important registry keys. MidiDiag.exe
was designed to be both human and machine readable, as a utility DAWs or other applications can use to provide information to their support teams when needed.
Unlike MidiUsbInfo.exe
, MidiDiag.exe
pulls information from the system using the same SDK and APIs used by applications.
Overall SDK Packaging approach
Current intent is for the production SDK/Runtime out-of-band package installer to include:
- SDK implementation libraries in a centralized location
- The command-line tools like mididiag and midiusbinfo
- the midi.exe console
- the MIDI Settings app
This will ensure a quality experience for customers without having to hunt down the files from various locations. Please note this is a statement of intent. The latest installer will be available from a known URL. We will eventually create the production installs internally so they can be properly signed.
The in-box install, which will ship with Windows, will include the service and all production transports and transforms required.
Note: When the in-box feature is enabled, the process to install a Github version of the service will be different because we'd have to overwrite protected operating system files. Look for communication on that in the future.
The NuGet package will continue to be available on Github. When we host the production version at NuGet.org, it will be properly signed. We will also manage compatibility between the NuGet versions and the SDK install.
USB Driver
Updated USB driver
The USB MIDI 2.0 Class driver that works with this release is 10.0.1.7 or higher.
Therefore, if using DP7, use driver 10.0.1.7. If using DP6, stick with the older driver version. Do not mix and match.
10.0.1.7 is attestation signed as in the past, so the same install instructions apply.
The older Windows MIDI 1.0 class driver had a bug in it where it would remain loaded after the new driver was assigned. This is fixed in Windows 11 Insider Developer and Canary channel builds, but older Windows releases may still blue/green screen a minute or three after the driver is assigned if you do not reboot right after assigning the driver to a device which previously had the MIDI 1.0 class driver assigned to it. Unfortunately, I do not have a minimum build number for you on when this fix to usbaudio.sys was deployed.
Additionally, after switching a device over to the new driver, you may see duplicate entries. A service restart fixes this.
USB Driver bug fixes for this release: https://github.com/microsoft/MIDI/issues?q=is%3Aissue+is%3Aopen+label%3Adriver-august-2024-fixed
If you get any sort of failure when assigning the driver to a USB MIDI 2.0 device, and you have used a previous version of the USB MIDI 2.0 driver in the past, or you have multiple USB MIDI devices, you may need to do a little cleanup first.
- Right click the device in Device Manager and choose to "Uninstall Device"
- Be sure to select the option to attempt to remove/delete the drivers
- After all MIDI 2.0 devices have been uninstalled (including any MIDI 1.0 devices that have previously been assigned to the driver), go to the menu and choose Action > Scan for Hardware Changes
Once those steps have been completed, you can assign the driver to the devices using the "Have Disk" approach described in Dev Preview 2. It's important to follow the steps exactly
- Right-click the device in device manager and "update driver"
- Browse my computer for drivers
- Let me pick from a list of available drivers on my computer.
- Click "Have Disk..." even if compatible hardware is shown
- Browse to the location of the 10.0.1.7 inf file and hit ok in that browse dialog
- Hit Next once you have selected the 10.0.1.7 inf
- You will get an "Update Driver Warning" telling you Windows cannot verify the device is compatible. This is expected
- If it worked, you will get "Windows has successfully updated your drivers" with "USBMidi2-ACX" as the driver name.
Known Issues
The Github issues list includes current known issues. One of note that we're still working on is automatic reconnection when devices are disconnected (#320) . This work is not yet complete.
In addition, we're looking at performance, a small number of lost messages with high traffic on slow connections, etc. with the new driver and service. (#366 , #362)
The MIDI Settings app is not included with this release
The MIDI SysEx sending functionality in midi.exe is experimental and not complete
Documentation has not yet been updated for DP7
Installer Note: When you run the in-box installer, I just noticed it says .1347 as the version. That's fine. Nothing changed in that installer between the two versions. Sorry for any confusion!
NOTE: Sometimes the installers end up matching older Defender AV signatures. There's not much we can do about that until we start building these internally and signing them. Submitting to AV scanning sites and to internal Defender scan shows no threats with any of the installers, but this was flagged on a Windows 10 test VM with old signatures.