Releases: microsoft/MIDI
Dev Preview 8
Welcome to DP8!
The purpose of this preview release is to enable developers to code against the new centralized SDK. We'll be demonstrating some of these apps at the NAMM Show in January, as well as a preview of Network MIDI 2.0.
This is not an end-user-ready release.
Installation Notes
Always completely uninstall any previous Developer Preview releases before upgrading to a new release, and also before upgrading Windows to a new Canary Insider build.
Windows MIDI Services Dev Previews require Windows 11 Insider Developer channel or Windows 11 Insider Canary channel releases. Canary releases will be the first to receive the in-box builds. You can learn more about Windows Insider releases here
https://www.microsoft.com/windowsinsider/
You can enable Windows Insider releases on your non-production PC via Settings > Windows Update > Windows Insider Program
If you are running a recent Windows Insider Canary build, that build already ships with an older version of Windows MIDI Services pre-installed. Because it is an in-box release, the registry keys which it uses are protected and so our install this time around is a little more complex.
⚠️ IMPORTANT PRE-INSTALLATION STEPS ⚠️
To install a developer preview, we must unprotect those registry keys. If you do not do this, registering the service components will either fail with errors in the installation (most common outcome), or will fail silently.
- There's a new script which helps developers install the DP in a system which has Windows MIDI Services in-box installed. Run this before running the installer. The zip file below has the ones from the time of this build. You can always get the latest from:
https://github.com/microsoft/MIDI/tree/main/src/dev-tools/reg-helpers
Run list-reg.cmd
to see the current state of the system. If it returns back components with locations in your System32
folder, then you will need to run the dev-prep.cmd
to take ownership of those registry entries before installing DP8. For example, this shows System32
(pre-installed) Insider components.
This shows the successful output from the dev-prep
cmd file, which means you can then run the installers.
After running the installers, this output of list-reg
shows the DP8 components installed and registered. Note that the file locations have changed from System32
to Program Files
. Also note that the lack of entry for Network MIDI 2.0 is normal at the moment.
Notes:
- The scripts require Windows PowerShell 7.0 or higher, available here: https://learn.microsoft.com/powershell/scripting/install/installing-powershell-on-windows
- You must run the scripts from an Administrator (elevated) command prompt
- You must have script execution enabled (Settings > System > For Developers > PowerShell). Optionally, this can be done from an elevated PowerShell console using the
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
command as described here https://learn.microsoft.com/powershell/module/microsoft.powershell.security/set-executionpolicy .
When using dev builds with the Windows Insider Canary builds at this stage, there are several things to be aware of:
- You may see duplicate entries due to both
MidiSrv
andAudioEndpointBuilder
enumerating endpoints - It's a bit of a lottery as to which
WinMM
ports go throughMidiSrv
vs the older stack. This can result in problems with WinMM multi-client and more. - The existing bug with the older MIDI 1.0 class driver and power management is still there. When you assign a device to use the new MIDI 2 UMP class driver, and the device was previously assigned the generic MIDI 1.0 class driver, you need to unplug and replug the device quickly to avoid a potential green screen (BSOD) due to a power management bug in the old driver.
Those issues are all fixed, and we've provided a small number of partners with internal tools to enable the fixes, but we cannot distribute those broadly at this time. Instead, we're working to accelerate getting to a point where we can turn Windows MIDI Services on by default, along with these fixes and the new class driver, in Canary builds around the time of the NAMM show so that everyone may benefit and so customers can test as well.
Installer Versions
During installation, you may notice different versions between the two installers. That is fine. It's just a mismatch between file name and internal metadata when a file doesn't need to be rebuilt.
App SDK
Centralized Installation
In previous releases, apps had to ship the SDK implementation in the application's folder, and also had to include a manifest file which listed all the WinRT SDK types.
DP8 is the first version with the new centralized SDK. Desktop applications should no longer ship the Microsoft.Windows.Devices.Midi2.dll
, the initialization DLL, or any MIDI activation manifest entries. Please verify that your own applications are following this new approach.
- The NuGet package no longer includes the WinRT implementation DLLs
- Under the Build folder of the NuGet package, the .hpp file for C++ apps replaces the previous Initialization binary. The C++ samples have been updated to use this. This is how you initialize the SDK.
- The aka.ms for downloading the latest installer is not yet active
- The installers are not yet signed
The SDK now includes a MidiEndpointDevicePropertyHelper
class which is a convenience for identifying Windows MIDI Services properties. This is used in the console as described below.
Endpoint Connection Creation Hardening
In previous versions, you could pass any string to the session function to create a new connection, and it would happily return a connection object for you to later (fail to) open. This was brought up in issue #429.
The SDK code to create a new endpoint connection now pre-validates the supplied endpoint id by:
- Ensuring it represents a Windows MIDI Services MIDI device
- Checking to see if the MIDI streaming interface on the device has been activated.
If either check fails, the function returns nullptr
. Of course, in between the time the connection is created and opened, the endpoint could go away. In that case, the call to Open
will return false.
Additionally, the code to create a MidiEndpointDeviceInformation
object by Id now does the same type of validation.
URLs
- Changed SDK Method
InitializeSdkRuntime
toInitializeDesktopAppSdkRuntime
to avoid any confusion when using the SDK from packaged apps in the future, where it does not use the initializer - Removed
GetLatestSettingsAppReleaseInstallerUri
andGetLatestConsoleAppReleaseInstallerUri
. Instead, everything that is not in-box will be provided through a single installer atGetLatestDesktopAppSdkRuntimeReleaseInstallerUri
- Application developers are permitted to include the latest supported release version of the installer with their application. However, apps must not uninstall newer versions already installed on the PC. By default, the installer will not overwrite newer versions. When uninstalling your app, do not uninstall the SDK Runtime - mark it as permanent.
- To download the SDK runtime, please use the URLs returned by the Initialization methods, when they are activated (before 1.0 release)
Type Changes
- Fixed some static SDK types which had
[default_interface]
incorrectly specified, and some which didn't have the static keyword applied to the runtimeclass in the IDL. This changed the clsid property for a handful of classes - Function blocks and most other locations which previously used a
uint8_t
Group Index now use theMidiGroup
type.
Known Limitations
- The activation code doesn't prevent calling it twice within the same process (for example, the host app and a plugin). This is being worked on.
- For this release, packaged / MSIX / Sandboxed applications are not supported. Only desktop apps are supported.
- To fully support packaged apps, we need to get the runtime installed as a shared library/framework package in the store. Packaged apps will also continue to require the manifest.
Experimental SDK features
- SDK components for preview service plugins, like Network MIDI, are marked with the "experimental" attribute and may change in future releases. If you use them, you'll see warning
CS8305
with MSBuild.
- Network MIDI 2.0 is under development, and not yet available in this release - Experimental features are not guaranteed to be backwards compatible from release to release
DLL Versions
- SDK DLL properties now include proper product version resources
C# Projection
- .NET support has been moved to version 8 and above, as the SDK is using some COM features supported only in .NET 8 and higher. .NET 8 is the long-term-servicing version of .NET so this would have been required soon anyway.
WinMM Compatibility
Although we still have some bugs to sort out, the WinMM compatibility code is in place and is feature complete. However, do see the notes below about usage.
- For MIDI 2.0 devices, we use Function Block information, if available, and Group Terminal Block info if not, to decide which groups are active and should be exposed as MIDI 1.0 ports.
- For MIDI 1.0 devices, we try to name the ports in a way that makes sense g...
Developer Preview 7
Developer 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 util...
USB MIDI Class 2 Driver - August 2024 Developer Preview
USB MIDI Class 2 Driver
This release includes only a new driver. Please use the DP6 service, SDK, and tools.
In this release, we have a new version of the USB MIDI Class 2 UMP Driver. It fixes a large number of bugs and also adds in features to pull in the manufacturer name, vid/pid, serial number, etc. (Those features will light up with the next service and SDK release)
Important note if you don't want to bugcheck
IMPORTANT: We have a bug in the older MIDI 1.0 class driver in Windows. When you assign a device to the new driver after it was previously assigned the older class driver, you will need to reboot immediately, or disconnect and reconnect the device immediately, or else you are likely to get a green screen due to a power management event. This is a bug we're fixing in the old class driver and will need to release with Windows update; it's not a bug in the USB MIDI 2 driver. Notes from Michael from #198 :
We discovered that existing MIDI 1 Class driver, USBAUDIO.sys, was not properly removing event registrations thus requiring a force unload to use new driver. To do this, when you update driver from USBAUDIO.sys to new USBMIDI2.sys driver, immediately after update unplug the USB MIDI 1.0 device from USB before green screen occurs (up to 30 second window). Then about 10 seconds after plug back in the USB MIDI 1.0 device. Verify through device manager and device details that the new USBMIDI2.sys driver is loaded for the device. It should operate fine from this point on. You only have to do the unplug and replug when you update to new driver from original class driver. After avoiding the green screen, should be no issue to use device with new driver moving forward, even across multiple reboots and reloads.
Arm64 and x64 Versions
This release includes versions for both Arm64 and Intel/AMD x64
Bug fixes
USB Driver bug fixes for this release: https://github.com/microsoft/MIDI/issues?q=is%3Aissue+label%3Adriver-august-2024-fixed+
Installation
As in the past, because this developer preview is shipped out of band, you must manually assign it to your MIDI devices.
To manually assign the driver to a MIDI 1.0 or MIDI 2.0 device, follow the same instructions from Dev Preview 2
https://github.com/microsoft/MIDI/releases/tag/dev-preview-2
Developer Preview 6
Windows MIDI Services Developer Preview 6
We're pleased to announce Windows MIDI Services Developer Preview 6!
This preview includes many changes and bug fixes from partner testing, as well as our various internal reviews and tests. There are some important changes in this release which move us much closer to the final form before the official consumer release.
Update 2024-07-22
The C++ samples have been updated to the correct NuGet package references, and included in a separate zip file below.
Also, please note that there have been some issues with folks not having the latest VC runtime. The installer has been fixed for the next release, but if you run into service crashes, please see this issue:
Delivery Approach Change
When discussing the delivery approaches with the API review team, we jointly concluded that the WinRT MIDI2 Application API itself should be shipped out of band from Windows rather than as part of the Windows SDK. The primary reason for this is the release and update schedules for the Windows SDK are too sparse for this product, we'd have challenges trying to make the API available to down-level Windows 10, and we'd also have to have Day 1 support for platforms that we don't tend to initially support (x86-32, Xbox, Hololens, etc.).
So here's the current (mostly complete) plan:
- WinRT API Metadata and Initialization DLL: Ship through NuGet and Github.
- WinRT API Implementation: We plan to ship this separately so we can centrally service it, at least for desktop apps.
- Windows Service, WinMM/WinRT MIDI 1.0 API support, and USB MIDI 2.0 driver: delivered through Windows servicing.
- Console and settings app: May be through the store, or through the central API servicing approach.
IMPORTANT NOTE: For this preview release, the code for resolving the SDK types without a manifest, and centrally installed, is not yet fully in place. That means that any application using this preview release needs to ship the SDK dll files locally (in the same folder as the exe loading them), and also include an
appname.exe.manifest
with all the activation entries. The SDK solution includes the contents of the manifest which can be used in your own project. That's also why the NuGet package includes all of the implementation DLLs, and not just the Initialization DLL. This is the normal approach for WinRT out of box SDKs, but we're working on a solution that doesn't require the main exe to declare every possible type in a manifest, and also ship the implementations. That solution isn't ready for this preview. If you try to use the SDK WinRT types without the manifest, Windows will not know how to resolve the types.
Installers
There are now separate installers for the SDK runtime (not used in this preview, but it does include the mididiag.exe utility) the in-box components (service and plugins), console app, and settings app.
To install this preview release
- Fully uninstall all previous preview release components except the USB driver (Do this through Settings->Apps->Installed Apps)
- Install the Service / In-Box components
- Optionally Install the SDK Runtime installer. For this preview, this is only needed if you want to run the mididiag.exe utility app. It installs the runtime files and the
mididiag.exe
utility under %Program Files%\Windows MIDI Services, and adds the utility location to the path. - Install the MIDI Console. The installer will add midi.exe to the path for any console windows opened after the installer completes. We recommend you use Windows Terminal, which has full emoji support and GPU accelerated text output.
There is no settings app build for this preview. It will be in the next preview.
There is no updated USB driver for this preview, but it is coming soon.
Namespace and API signature changes
Because of the delivery approach change, the WinRT API namespace had to be changed from Windows::Devices::Midi2
to Microsoft::Windows::Devices::Midi2
. This is a Windows standard for APIs/SDKs.
Additional breaking changes
- The
MidiService
class was refactored intoMidiDiagnostics
,MidiReporting
, and also theMidiServiceConfig
classes across different winmd namespaces. - There are a number of naming and other changes, as well as type changes across the board, all to comply with the new delivery format. Many are just naming changes.
- Additionally, the
MidiEndpointDeviceInformation
class properties were refactored into a number of simple structs which are both easier to work with, and also more obvious in terms of data source.
Additional startup check
- The MIDI Service is now set to demand-start (triggered), as required by Microsoft for any Windows Services not required for startup.
- To support the new model, applications should now use
MidiInitializer::EnsureServiceAvailable()
as the first step when starting up. This will start the service if it is present but not already running, and also tell you if Windows MIDI Services is installed and running. You only need to do this check once, at app startup. If Windows MIDI Services is not installed, apps may then decide to fall back to an older MIDI API, or inform the user that they are on an unsupported version of Windows. This code flow works well, but may have a couple minor changes before final release, mostly to ensure apps understand the exact nature of any problem. - The settings app will likely include an easy way for a user to change the service to always run, should they want to.
New or updated Features
Full translation for MIDI 1.0 devices connected to UMP USB MIDI driver
- Previously, Message Type 4 (MIDI 2.0 Channel Voice messages) were dropped when sent to a MIDI 1.0 device connected to the MIDI UMP driver. Now they are downscaled to their MIDI 1.0 equivalents. This will never be perfect because of the extended uses of the MIDI 2.0 note on/off/etc messages, but consensus from partners was that getting a bad note is better than no note (example: when exact pitch is used and the note number is actually an index)
Automatic endpoint reconnection through API
- When creating a new connection to an endpoint, the application may optionally enable auto-reconnection via a boolean parameter. This spins up a device watcher behind the scenes, at the session level, to watch that specific endpoint. When the device is reconnected, if the Id has not changed, the connection will be re-established and will be usable.
- This is optional because the device watcher does add a small amount of overall overhead. Individual message send/receive is not impacted, however.
Dirty-disconnect cleanup
- If you control-C the
midi
console, or you crash out without closing your session in your own app, the service now detects this and cleans up the open connections using a context handle at the session level, and a server context run-down routine.
Aggregated MIDI 1.0 endpoints
- Previously, when using older or vendor drivers, only MIDI 1.0 endpoints with exactly one input and one output would be enumerated as UMP endpoints. Now, all MIDI 1.0 byte format endpoints on a KS filter (shows up as a "device" to us) are aggregated into a single UMP endpoint
- Internally, the service creates group terminal blocks to represent the different pins, and makes group numbers to those pins. This is consistent with the behavior of the same devices connected to the MIDI 2.0 UMP driver
NOTE: We're looking into the possibility of combining filters for a device so single physical devices do not show up as multiple logical UMP endpoints. This is not yet in place.
iJack names now used for MIDI 1.0 endpoints
- When provided, the value from
iJack
is now used as the name of a MIDI 1.0 endpoint. For aggregated UMP endpoints, this becomes the name of the generated group terminal blocks.
Arm64 support!
- Everything is built for both Arm64 and x64 starting with this release. Arm64 builds are supported only on the latest Windows 11 releases, not on Windows 10.
Settings app
- Service restarting is now built into the troubleshooting page. You must run as administrator to use it.
NOTE: The Settings app is not included in this preview. It should be in the next preview.
Console app
- Settings app
midi enum endpoints
now shows the function blocks or group terminal blocks for the endpoint when--verbose
is specified
Additional Notes
Projections
- This preview ships with the .NET projection as well as direct support for C++/WinRT, and header support for other C++ developers
- This preview will include an Electron projection, but not until end of next week. Please let us know on Discord if you are active using it, as this may be the last one we create.
- You can generate all the headers needed automatically if you use the cppwinrt tool in C++/WinRT (tool is also available in the C++/WinRT official NuGet package). However, the Windows MIDI Services NuGet package includes all the headers for this SDK in the build/native/include/midi2 folder. If your tooling doesn't support NuGet packages, just rename the package to .zip and until to a location of your choice.
Dependency Versions
- All .NET projections, references, and targets are now set to .NET 6 with a minimum Windows SDK version of 10.0.20348. .NET 8 is the most recent long-term support version of .NET and is recommended. .NET 6 is minimum. The NuGet package declares support for .NET 6, 7, 8, and 9.
- All projects updated to latest versions of C++/WinRT, and (where appropriate) latest Windows App SDK/WinUI 3
Documentation
Most of the documentation at https://aka.ms/midi is up to date with the SDK refactor. We're working on the rest of it. Feel free to log bugs if you find documentation issues.
Developer Preview 5
Hi Everyone. We're continuing our march to production with Developer Preview 5!
(Updated Windows.Devices.Midi2 zip below with missing header files)
Updated driver because the initial release went out with an old driver version.
In preparation for our next API review and for moving into production, we've looked at every aspect of the API and evaluated it for completeness, usability, and necessity and also rolled in a lot of the feedback we've had over the past 6 months.
As a result, there are a number of changes in this release. In our testing, all applications built against previous versions of the API will need to be recompiled against the new metadata, and may require some minor code changes. Note that changes in class signatures does result in changes to the generated interface Ids.
Please do file bugs! But please also check the current outstanding issues before doing so. Feel free to add more data or comments to existing issues if you find you've run across the same problem.
Documentation
In prep for production and for our internal API review, I've started fleshing out the documentation. Work-in-progress docs are currently using GitHub pages and are now published at https://aka.ms/midi . When we have an official MS Learn section for Windows.Devices.Midi2
, we'll repoint the aka.ms to that.
NOTE: Some of the docs, especially those about the configuration file format, need to be updated and are no longer valid. We're catching up with these as soon as possible.
Important Method Signature Changes
Our internal API validation required that any out or in/out parameters be the last items in a parameter list in any function. For that reason, all the MidiMessageReceivedEventArgs
methods which would fill an array, buffer, or struct, had to be modified so the array/buffer/struct was the last item in the parameter list. To keep things consistent, all the Send message methods were changed to operate the same way.
Additionally, any method which took an IVector
or IVectorView
as a parameter has been changed to take an IIterable
to be consistent with our API guidelines and automated validation.
Finally, for the same reasons, several of the "Flags" enums were renamed to be plural and remove the word "Flags" from the enum.
API and Service Highlights
App-to-app and Loopback MIDI
- App to app MIDI devices can now be created 100% through the API, from an application. See the app-to-app MIDI C# example for details. This version of app-to-app MIDI enables your application to appear as a full MIDI device, with endpoint information, function blocks, and more.
- Simple loopback MIDI now available through the configuration file and through the API
Active Sessions
- The service now tracks active sessions and displays the name your apps are providing when creating a new session. The console
midi enum sessions
command has been added to report on that information.
Installed Transports
- The service now reports on installed transport plugins. The console
midi enum transports
(with optional--verbose
) lists all the transports currently enabled in the service.
Example with --verbose
This information is also reported by the mididmp
utility.
MIDI Service Control
- The console
midi service
command has been updated to now have sub-commands to start/stop/restart the service. These must be run from a command prompt running as administratormidi service start
,midi service stop
, andmidi service restart
are the new commands.
MUID
- The
MidiUniqueId
class now has methods for generating a new random MUID, parsing the MUID from bytes or a single 32 bit integer, and more. This class is useful when you are working with MIDI CI.
Connection Updates including Multi-message sending
- Refactored the endpoint connection settings, resulting in different signatures to the
MidiSession
methods to create a new connection. MidiEndpointConnection
no longer implementsIClosable
/IDisposable
and no longer has aClose
orDispose
method. Always close the connection through the related session. This avoids having dead connections in the session collection. TheMidiSession
class still implements these interfaces.- Added to
MidiEndpointConnection
theSendMultipleMessagesWordList
andSendMultipleMessagesWordArray
to send a vector/collection/list/array of words. Currently, the code behind this will pick this apart into multiple discrete messages, and send all with the same specified timestamp. This is the only method which will accept multiple UMPs and send them all. We're including it for ease of use and for potential future optimization for sending more than one message at a time. - At the same time, the methods which send only a single message have been renamed to new names in the form
SendSingleXXXX
.
Here are some informal speed tests. The code that generated this output is in the samples section. This is going to vary a bit from time to time as we adjust timings and optimize code.
Full thread: https://discord.com/channels/980245825202552942/1208186499993178192
Message Scheduling
Now that we have other message sending bugs resolved, I've re-enabled message scheduling.
Message Scheduling is still due for an update to ensure that there's only one instance per device, so you may run into scheduling strangeness like before if you have multiple connections open to the same device, each sending scheduled messages.
Please file bugs here if you see problems.
Message updates
- The
MidiStreamMessageBuilder
API functions now take and returnIMidiUniversalPacket
instead of MidiMessage128. This makes them more usable from other functions - The
IMidiUniversalPacket
type now has functions to return all the words either as a new vector, or insert them into an existing vector - Removed the
MidiMessageTranslator
which was not yet implemented. Other libraries already do a good job of upscaling/downscaling MIDI 1 <> MIDI 2 messages.
MIDI Clock Update
- The
MidiClock
class now includes aTimestampConstantSendImmediately
property. You can still just use0
in place of the timestamp when sending messages if you want to bypass the scheduler, but this property makes that value more obvious. It's a property because WinRT doesn't support shipping defines or constants any other way. MidiClock
also has a few more conversion methods to make it easier to handle the time calculations from any language
Enumeration Updates
- Added additional sort order options to
MidiEndpointDeviceInformationSortOrder
so if you want to sort by the transport (for example, all network MIDI devices followed by all virtual devices) you can do that. - Added various "LastUpdateTime" properties to the device information object for the in-protocol discovered properties like function blocks, endpoint information, etc.
- Renamed some of the enumerated device properties so they better represent their source
- The
MidiEndpointDeviceWatcher
events have all been normalized to sendXXXXEventArgs
types as the second parameter. This was the result of automated API review. - There's a bug in the driver right now so we don't yet pull the
iSerialNumber
property. Next release for that.
Apps and Tools
Console
- The console has generally kept pace with the API changes and so surfaces new features like session reporting, transport enumeration, and more. There's quite a bit of new functionality in there.
MIDI Dump Utility
- The install now includes the
mididmp.exe
utility. This will be ship in Windows with the API. It's a lightweight bare-bones command-line program which outputs the devices, the midi clock information, and the results of a service ping test. Intention here is for this to be available for use by technical support personnel and for desktop applications as per original AMEI request. Output is plain text with machine-readable tokens because most apps will redirect output to a file or otherwise capture the output. Here's a screen shot from an early revision of the app:
This is a C++/WinRT console app which uses the API. Source here:
mididmp.exe source
The utility is in the app path, so to use it from your own applications, just ShellExecute
or your other favorite way to launch other processes, and capture the output.
Work-in-Progress MIDI Settings App
A very early build of the MIDI Settings app is also included with this release. There's a lot in here which is not yet wired up, but you can view endpoint devices, sessions, transports, etc. Expect random errors and more.
The settings app was built using .NET 8, WinUI 3, and the Windows App SDK. The installer package installs all of those components on the target PC. Note that .NET 8 is also used for the MIDI Console app.
Installed Transports
Enumerated Endpoints
Endp...
Developer Preview 4 (Official NAMM Readiness Preview)
Hi All
Here's the official Developer Preview 4, just in time for NAMM! This is the release I'll be using when presenting on stage.
This includes everything from the previous dailies:
- https://github.com/microsoft/MIDI/releases/tag/dev-preview-4-daily3
- https://github.com/microsoft/MIDI/releases/tag/dev-preview-4-daily2
- https://github.com/microsoft/MIDI/releases/tag/dev-preview-4-daily1
In addition to what was listed in the DP4 daily releases, we have the following:
Changes
This includes support for app-to-app MIDI, as long as the device is configured in the midiconfig file in advance. Later, we'll add in the plumbing to enable this at runtime. This is an unstable feature, however, so use at your own risk at the moment. The related PR shows the syntax of the config file entry. #232
- When the service starts, the config file is read and the device-side endpoint is created. This is the endpoint the app acting as a device should open. This endpoint is not visible in a normal enumeration call as it has a purpose of
MidiEndpointDevicePurpose::VirtualDeviceResponder
which is normally excluded from enumeration. - Once the app opens that endpoint connection, the service will enumerate a client-visible endpoint that is routed to the device endpoint. This is the normal multi-client endpoint that all apps should use.
- When the device app closes, the client-visible endpoint is torn down
This has basic support for reporting function blocks and endpoint metadata. Protocol negotiation is buggy for it, so that has been turned off for this release just for this type of endpoint. For now, you can use midi endpoint request endpoint-metadata --all
to request endpoint info and then midi endpoint request function-blocks --all
to get the function blocks.
In addition, there's a new sample app. It's a C# WinUI app that is a 4x4 pad controller demonstrating app-to-app MIDI and how to configure function blocks and endpoint metadata.
Fixes and Workarounds
#224 Fix: Console send-message should allow hitting escape. This is fixed in this preview.
#233 Work around: Slow send-message-file command has been worked around. For now, only failed messages are displayed on the console. There's a summary at the end telling you how many messages have been sent. This will later be changed to a better display, but I wanted to deal with the performance issue. If there are MANY failed messages (thousands), it'll be slow again.
Screen shot from the test vm. The messages sent in just a few seconds.
USB Driver
We don't yet have a new version of the USB driver, so please continue to use the one from December. Download and install instructions here: https://github.com/microsoft/MIDI/releases/tag/dev-preview-2
A reminder that the MIDI Association Developer Day is this Friday. I'm kicking it off at 10:30am with a presentation on Windows MIDI Services.
Thanks again to everyone for testing. See you at NAMM this week!
Developer preview 4 (NAMM Readiness - Daily 3)
Important items for this release:
- Something in the changes here triggered generation of a new .winmd file. My apologies there, as we were trying to keep that stable/static. As a result, the projections had to be regenerated including the NuGet package. That is all included in this release but you'll likely need to update your references.
- Made the
midi clock
command more informative. - Added more information to the monitor output summary, especially if running with debug settings
- Issue #227 worked around (but needs more diverse testing from folks). I've been testing with both the loopback and the protozoa. Where I was getting lost messages before, I am now receiving 100% of them. There's a bit more jitter (around 10 microseconds) as a result. We'll continue to monitor and Gary has an idea for how to better fix this long-term.
- Added a pair of test/debug flags to
send-message
andmonitor
on the midi console app. These are designed to work together over the loopback, or using the ProtoZOA firmware which sends messages with an increasing value in word 2.
Examples:
midi endpoint monitor --debug-warn-skipped-increment
midi endpoint send-message 0x41234567 0x00000000 --count 100000 --debug-auto-increment --pause 0
Please test on your systems and let us know if you run into any issues
Scheduled messaging is still turned off until we are sure on issue #227 above, so we can keep any problems isolated
We won't have a new revision of the USB driver before NAMM, so please continue to use the one from December.
If you are seeing green screens with that driver, one possible cause is power management. If you turn off USB suspend and related power management on Windows, it will stop those specific errors from happening.
Developer preview 4 (NAMM Readiness - Daily 2)
Ok, this time the console monitor speed improvements really ARE significant :) The console will now keep up monitoring within a few messages when it's getting spammed by a device sending messages in tens to hundreds of microsecond intervals. Previously, it would lag quite far behind.
Addresses issue #182
Addresses issue #222
Addresses issue #218
Still work to do on sending messages from the console. The current code doesn't allow for anything more rapid than around 700us.
Same NuGet package and winmd file as the previous preview. Please uninstall the previous exe installer from Settings -> Apps -> Installed Apps before installing this.
Tested on VM and dev workstation, but this is a daily, not a full preview.
Developer preview 4 (NAMM Readiness - Daily 1)
NOTE: The previous installer Windows.MIDI.Services.Developer.Preview.4.x64.1.0.24015.2013.exe had a bad config file with it which caused the install to fail. That has been fixed and replaced
Why the convoluted name? This is a quick release, and hasn't been through the usual level of testing for a developer release.
This preview is for anyone in active development, especially those who
- Are working on a Demo for NAMM (the winmd here represents the API as I will use it at the NAMM show)
- Are debugging a performance or lost message issue in the console
- Can provide immediate feedback for any problems
Main changes
- Significant performance improvement when monitoring in the console. I've also pared down the console output when you monitor in a non-verbose mode. Lower CPU usage and faster display is the main result
- Console gracefully handles a device disconnect during monitoring
- Group Terminal Blocks are projected as roughly equivalent function blocks if you call the .AsEquivalentFunctionBlock() method on the GTB.
- Endpoint discovery and protocol negotiation (UMP) happen when you plug in a USB MIDI 2.0 device
- In-protocol discovered metadata is now cleared when a device is enumerated (plugged in, or the service is restarted)
- USB device endpoint renaming works through the configuration file.
The API surface area won't change between this and the NAMM show, so metadata will remain valid.
- There is no Electron projection for this interim release.
- There is no updated USB driver for this interim release. Please use the one from December.
Please be sure to uninstall the previous version before installing this.
Developer Preview 3
This is a relatively small but important update over Developer Preview 2.x. For those who were blocked in the previous release due to bugs caused by the scheduler, this release will unblock you and allow you to continue development.
If you have a previous preview installed, please uninstall it.
Key notes
- Outbound message scheduling is temporarily disabled. It was causing a number of issues in the previous preview. Once it is solid, we'll release another preview with it enabled. The API is still the same, it's just that the timestamps are ignored and all messages are sent immediately.
- Still plenty of debug code (primarily OutputDebugString and similar) in the builds. If you run dbgview64, or attach to the service process (or app process) from Visual Studio, you can see the output.
- No updates to the USB driver due to the holidays. Please use the version from Developer Preview 2.
- Defender sometimes flags the setup package, or part of it, as a threat. This is a false positive. We'll look into code signing Github releases for the future. See screen shot below for VirusTotal and Kaspersky submission results
Please see the issues list for other known issues
Bug Fixes
This preview fixes or works around a few bugs:
- Fixed: #188 Incoming KS device timestamps are 0
- Worked Around #183 as this is related to outbound message scheduling crashing in the service
- Worked Around #182 also related to message scheduling
The last two are not yet marked as fixed because they are simply worked around in this preview release. However, it's key to work around those right now for you all to be able to test the release.
New features
Service metadata parsing
- The service now parses in-protocol endpoint data and function blocks as long as there is at least one client listening to an endpoint. Right now, this information persists across service restarts. In the future, we'll be clearing this information from the cache when the device goes away. There must be an active client connection at the time of message arrival for the data to be cached. This is by design.
MIDI Console
- The MIDI console can easily request endpoint metadata and function blocks through the new
midi endpoint request
command. If you don't have a long-running connection open in another application, the recommended way to use this is to open one console monitoring the UMP device, and another for sending the request. Note that the console doesn't keep an active connection after sending messages, unless you schedule messages out into the future. Otherwise, only when you are monitoring an endpoint is the connection maintained. - Function blocks are displayed in the endpoint properties
- Endpoint Device Watcher updated to display more information about what has changed
Enumeration API
- The Enumeration API has been updated to provide more information about which properties have changed in the Watcher Updated event.
- There have been additional properties added to the
MidiEndpointDeviceInformation
class, as well as an update to the Function Blocks vector to change it to a map, indexed by block #
Installation
Uninstall any older version of Windows MIDI Services from your apps -> installed apps in settings. You do not need to uninstall the USB driver.
Unzip the Windows.MIDI.Services... zip file somewhere and run the contained exe installer. This will install the API, Windows Service, and MIDI console. Keep the installer around so you know which version you last installed. This is needed for bug reports.
If you want to communicate with USB devices, install the attestation-signed USB driver from Developer Preview 2. Requirements for the driver are documented there. Primarily, you need to be running an Insider Canary build of Windows 11.
As always, discussions on Discord are welcome, as are bug reports here.