Releases: microsoft/MIDI
Developer Preview 2
NOTE: There's an update to this release which may be found here. You'll still need the driver, projections, etc. from this release, but there's a new installer.
https://github.com/microsoft/MIDI/releases/tag/dev-preview-2.1
===
We're excited to release the latest snapshot of Windows MIDI Services, including the new Windows Service, the API and projections, the console app, and the USB MIDI 2.0 driver.
This is a developer preview intended for application and device developers. This is not a customer / end-user / musician-ready release. It is not intended to be used on a production workstation or a PC you rely on. There is no end-user support for this release. Any bugs must be filed in Github for us to track.
Please do not host or distribute these files to others. Always refer them to this release page to read the instructions and download the files
We want to know about your experiences with this release. Please report (or add detail to) bugs on Github, and ask questions or have discussions on our Discord server.
Developer Preview Release Highlights
- A mostly complete UMP-based MIDI 2.0 API with features based on your feedback and discussions on Discord, at MIDI meetings, and at readiness events
- Multi-client by default
- Supports outbound message scheduling by default
- Provides much more information about connected devices
- A Windows Service with support for pluggable transports and pluggable message processing plugins*
- Much faster than the older MIDI infrastructure in Windows, using circular buffers in shared memory for communication between the service and API, and the service and the Windows Kernel-mode drivers.
- Provides a centralized location for translation, enumeration, message processing and more
- Doesn't require drivers for each type of transport. Most can be implemented as user-mode service plugins.
- A console app useful for testing, debugging, and general inspection of the system
* the message processing dynamic loading is not yet in place, but it is in place for transports. The plugins are loaded from entries in the registry.
Key Notes
Please report any bugs, no matter how small. There are many we know about, but they are not all documented just yet. We're moving to a phase of more formal bug reporting now.
Installer
If you are running any earlier previews, please uninstall them from Settings->Apps->Installed Apps. Patch/upgrade installs are not supported.
If you are running any OS dism
patches from the on-campus plug-fest and readiness event, please also remove those. The latest Windows Insider Canary build contains the OS components required.
The Windows MIDI Services Installer is not a full-featured installer. It's used only during these developer previews. Before installing a new version, you must always uninstall any previous versions through the Windows Settings app.
In addition, the installer temporarily takes over ownership of the registry location for WinRT activation entries, which is normally owned by Trusted Installer. This is not a supported scenario, but is needed for external releases from Github vs requiring your app keep the API local and include a large manifest file with activation entries. If this installer fails for some reason, it could leave you with a broken WinRT system requiring a repair or reinstall of Windows (we have not yet run into that in our testing, but it could happen). In addition, these entries get wiped out each time you upgrade from one Windows Insider Canary build to the next. We do not recommend you adopt this approach in any products you ship.
USB MIDI 2.0 Driver pre-release
The USB MIDI 2.0 driver needs to go through a lot more internal testing before we can qualify and production sign it. But we know we need solid USB device support for this API to succeed. In support of this, we also want to see it tested with as many different devices as possible. We'll do quite a bit of this ourselves and with partners, but this is where you can help. If you are a developer of a device and want to ensure your device works with the new MIDI stack and driver, please test and report any bugs here, or start discussions on Discord.
If you do not need to test USB devices under the new API, do not install this driver. There is no end-user support for this driver and it's quite likely you will have a crash or two.
We're providing the driver primarily to those actively implementing the API in their apps, or testing their own devices. If you do not need to work directly with USB MIDI devices, you can use the built-in loopback devices with the API.
- We have an attestation-signed pre-release USB MIDI 2.0 driver developed by AmeNote. This is a build of what will be the new MIDI class driver shipped in Windows. Because it has been attestation signed, you do not need to turn on test signing, disable secure boot, or any of the other things which make self-built versions more of a challenge.
- To use the driver, you must manually assign it to the device using "have disk". Unzip the driver files to a known location, right-click the hardware device (not the software device) in Device Manager and choose a driver from those on your PC.
- If you unplug the device and replug it, you may need to manually pick the driver again.
- The driver will green screen your system if you pick an incompatible device, such as the audio device from a combined audio/midi device, or a serial management endpoint of same.
- The driver requires the latest Insider Canary build of Windows 11 for our USB stack updates which have not yet been serviced to mainstream supported Windows 11 and Windows 10 releases. Only the Canary releases will work here. For more information on the Windows Insider program, check the documentation here.
- The driver currently supports only a single device at a time. #166
- The driver (and service plumbing) do not currently support the classic MIDI APIs on Windows.
- Please report any new bugs with as much detail as possible. If you are trying a MIDI device and found any failures or bugs, it would be helpful if you could also provide a copy of all the device header information using a tool like the Thesycon descriptor dumper or USB Device Tree Viewer. The latter has issues reporting all string properties, however, often saying the device is in a low power state.
- The password for the USB MIDI zip file is
preview-2
. The password is there to help ensure everyone installing it has read this section. :)
Upgrading your Windows Version
- If you upgrade to a new version of Windows (including to a new Canary build) you'll need to uninstall and then reinstall Windows MIDI Services and the USB driver.
Features and Other Notes
Service-based Message Scheduling
- Outgoing MIDI messages can now be scheduled through the service.
- Use a timestamp of 0 to bypass scheduling completely. You can also use a timestamp of
MidiClock::Now()
to effectively bypass scheduling. 0 is the better choice, however as it short-circuits the rest of the scheduler, and is also consistent with other operating systems. - Fix: Originally, messages with the same timestamp > now had indeterminate send order. That has been fixed so the order is retained.
- Don't queue thousands of messages. Performance degrades based on outgoing scheduler queue size. This is unlikely to change.
Enumeration
- It can be a challenge to get all the custom properties using our standard enumeration objects
- Also a lot of work just to find the parent device. We've handled that.
- These classes wrap the standard enumeration types
- New support for the
MidiEndpointDeviceInformation
class and metadata. See sample. - New support for the
MidiEndpointDeviceWatcher
class for add/update/remove notification. See sample. This is the preferred way for you to enumerate endpoints, because it will notify you when they are added or removed, and when properties (like function blocks) change.
Group Terminal Blocks
- The new USB driver now supplies Group Terminal Blocks from MIDI 2.0 devices. These are surfaced through the
MidiEndpointDeviceInformation
class and also through the console app as well usingmidi endpoint properties
- The new USB driver also creates group terminal blocks for USB MIDI 1.0 devices. The returned information should contain the correct names if you provide Pin names in your USB headers
A classic byte-stream MIDI 1.0 device. The names of the two virtual Group Terminal Blocks come from the iJack
descriptors.
Listeners
Client API Endpoint Listeners now in place
MidiChannelEndpointListener
: Receive messages only for a group and channelMidiGroupEndpointListener
: Receive messages only for a groupMidiMessageTypeEndpointListener
: Receive messages only for certain message types
Virtual D...
September Developer Preview (Dev Preview 1.1)
Windows MIDI Services September Developer Preview
This is the official Developer Preview 1 of Windows MIDI Services. (Updated to fix access violation in previous release)
Release Notes
As we get closer to a 1.0 release of Windows MIDI Services, we're working to have everything set up in a way that better represents how this will function when distributed with Windows. In all the interim previews to date, we've distributed everything through a NuGet package plus a small installer just for the Windows service.
Expect bugs. Please report them as issues on Github so we can track them
IMPORTANT NOTE: the installer requires that you are a local administrator on your PC. It does some hacky stuff to enable WinRT Type activation of an out-of-band library. This approach is neither supported by nor recommended by Microsoft, but we're doing it here to get you a dev preview, as open source, which behaves much like it will when in-box, without having to wait until the bits are in an Insider build. Specifically, the installer calls to a C# addin which takes ownership of the protected
HKLM\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassIds
, adds the new class Ids, and then returns ownership back to Trusted Installer. The implication here, if that gets interrupted or otherwise fails, is that the rights on that key could be compromised and either allow anything to be registered, or nothing. It has been tested on fresh VMs and developer PCs here. It uses registraton entries built as part of the cake build. You can see the source code in \src\oob-setup\RegistryCustomActions and specifically the CustomAction.cs file.For this reason, this is a developer-only release and is not for installation on end-user or customer machines.
Do not distribute the installer to others. Please instead provide the link to this release.
Major near-term items not yet present
Transports
- USB MIDI 2.0 class driver (so no USB devices or group terminal blocks yet)
- Virtual MIDI (including virtual CI devices)
Other Features
- Function blocks and endpoint information, including automatic discovery. This is coming soon, after I have built good tests for it.
- System-wide caching of function block / endpoint, and other information. Cache implementation is local for this preview.
- User-configurable setups
- SDK. Most of the required SDK functionality has now been incorporated into the API, so for simplicity, we're leaving the SDK out until we start adding in virtual/network/etc. transport configuration objects (which will be SDK items). Because this is not an end-user release, and this feature may be unnecessary over time, we also do not include the SDK code for checking if Windows MIDI Services is installed.
Apps
- GUI Settings app
- Recording MIDI messages to a file in the console app (this is coming soon, but didn't make the cut here)
- Additional developer features in the console app (endpoint/function block simulation, etc.)
Type Registration / Activation
- COM clsids are not registered. For COM activation during development, you may need to copy the Windows.Devices.Midi2.dll local to your project and use it as in the previous releases.
Architecture
- No Arm64 support yet. The project is Intel x64. A reminder that there will not be any x86 builds or support for 32 bit processors.
Known errors
- Although far fewer than the past, there are still a number of functions that throw E_NOTIMPL HRESULT. Here are the ones we're expecting hresults from for this release. Please report any other hresults or problems you find
MidiMessageReceivedEventArgs::FillBuffer
MidiEndpointInformationConfigurator::*
MidiFunctionBlockEndpointListener::*
MidiStreamConfigurationEndpointListener::*
MidiTransportInformation::*
MidiVirtualDeviceManager::*
MidiMessageBuilder::BuildSysEx7MessageFromArray
MidiMessageBuilder::BuildSysEx7MessageFromBuffer
MidiMessageBuilder::BuildSysEx8MessageFromArray
MidiMessageBuilder::BuildSysEx8MessageFromBuffer
MidiMessageBuilder::BuildMixedDataSetChunkHeaderMessage
MidiMessageBuilder::BuildMixedDataSetChunkDataMessage
MidiMessageBuilder::BuildMixedDataSetChunkDataMessageFromArray
MidiMessageBuilder::BuildMixedDataSetChunkDataMessageFromBuffer
MidiVirtualDeviceResponder::*
Other Known Issues
- The service eventually becomes unresponsive after a few hundred messages. During the runup to that, message transmit/receive times start to go up. You can see this by using the midi console and typing
midi service ping --verbose --count 50
and running that repeatedly. When the service becomes unresponsive, you can restart it in the Services snap-in or through SCM. We're looking into it.
Features
Now let's get to what is here, as there is quite a bit. In general, what you're seeing is much closer to the production version that will eventually ship in-box. There's a lot of service infrastructure in there, plenty of bug fixes and hardening, cleanup of type and parameter names and more. There's more to do, but if you're not already developing with the previews, this is a great one to start with.
API
- Quite a bit in the API and service, including all the infrastructure to send and receive messages For more information, see the API documentation
Service
- Diagnostics transport which includes cross-wired BiDirectional UMP endpoints, an input and output endpoint, and a ping endpoint. These are all for developer and testing/support use as described in the API docs.
- Bug fixes for the initial issues around flooding messages without consuming any of them. Hammer this as hard as you want and let us know what you find.
Documentation
- API overview documentation in \get-started\midi-developers\app-developers\docs
NuGet Package
- C# projection is fully functional
- NuGet package with the WinMD and C# projections and works for both C# and C++.
- Package no longer contains the API implementation DLL
- Package no longer contains any SDK components
Installer
- Installs the MidiSrv Windows service, the console app, and the API
- Installs the .NET 8 Release Candidate desktop runtime (required by the apps)
- Installs the retail Visual C++ Runtime (required by the API and service)
- Registers the WinRT types for activation (this is a hack for developer purposes only. See note above)
- Tested on Windows 10 22H2 bare VMs, and on developer machines
Service
- UMP Bidirectional loopback endpoints. Sending to A->out comes back on B->in. Sending on A->in comes back on B->out
- Unidirectional loopback endpoints. Sending on the out loopback comes back on the in loopback
- Ping transport. For internal use. The console application uses this, and the
MidiService
API type has a static method to perform the ping in case you need to do any sort of diagnostics from within your apps.
Console app
- Combined with the loopback UMP Endpoints, useful for testing MIDI 2.0 implementations. See this thread in Discord
- Service status and ping to check that the service is installed and running
- Message sending from the command line
- Send a file of messages for automated testing
- Monitor incoming messages on a UMP endpoint
- Enumerate all UMP Endpoints
- Enumerate all bytestream (MIDI 1.0 endpoints as they appear to WinMM and older WinRT APIs.
Build process
The entire package is built using the build.cake build script in the repo.
Verifying the install
A successful install looks like this:
- Root folder
%programfiles%\Windows MIDI Services
- API subfolder with
Windows.Devices.Midi.dll
andWindows.Devices.Midi.pri
- Service subfolder with
MidiSrv.exe
and the different abstraction DLLs. The abstraction DLLs are COM self-registered on install - Tools subfolder with Console and Settings folders.
- Console folder with midi.exe and all dependencies
- Settings folder is empty but will contain the Settings GUI app in a future release.
- %PATH% updated to include the location of the MIDI Console app midi.exe
- Microsoft MIDI Service installed in Services and running (it will make a device connection sound when it starts up on Windows 11. - Investigating to see if there's anything we can do about that)
- Opening up a new console and typing
midi service ping --verbose
returns a positive result
Testing without any MIDI 2.0 devices
The console app provides easy ways to send and receive UMP messages. You can load up a file with valid (or valid enough) UMPs and use that to test receive functions in your app.
Here's one of the files I used for testing the feature:
# This is a test file for sending UMPs through Windows MIDI Services
# It uses auto for the field delimiter so we can have different
# delimiters on each line
# The line above was empty. The next data line is a UMP32
0x22345678
# The messages aren't valid beyond their message type matching the number of words
0xF1345678 0x12345678 0x03263827 0x86753099
0xF2345678,0x12345678,0x86754321, 0x86753099
0xF3345678|0x12345678| 0x86754321|0x86753099
0x21345678
0x42345678 0x12341234
0x43345677 0x12341235
0x44345676 0x12341236
0x45345675 0x12341237
0x26989898
# The next two lines have different hex formatting
41345678h 12341234h
22989898h
F3345678h 12345678h 86754321h 86753099h
# The next lines have no hex formatting
41345678 12341234
22989898
# The next lines...
September Developer Preview (Dev Preview 1)
This has been replaced by Dev Preview 1.1 due to a console app access violation due to a mismatched NuGet package.
Please uninstall the previous release through Settings->Apps and install the new version from here
https://github.com/microsoft/MIDI/releases/tag/dev-preview-1.1
SDK and API Interim Developer preview 003
This is likely the last interim preview before the official August 2023 Developer Preview. Focus on this preview is the API, not the SDK, or other bits. There are still some internal API reviews to go through, so there may be additional changes to the API surface area, but we're feeling pretty good about this version based on feedback so far.
The intent behind this preview is to get you familiar with the shape of the API and allow you to start coding to it.
Associated NuGet package is version preview.1-0094
, included below. the source in the release is in sync with that. If your tools do not support consuming NuGet packages directly, you can rename it to .zip
and extract the files including the architecture-specific .dlls
and the .winmd
files with the metadata. Note that C# developers also need the projection library .dll
, but they will presumably use NuGet to get them.
Breaking Changes
- This is the first public preview with the SDK and API separated out, so most everything has changed. The SDK is in
Microsoft.Devices.Midi2
. The API isWindows.Devices.Midi2
. You will need to use both in a production application. For now, you can get away with justWindows.Devices.Midi2
as it is closer to a release version. - Many changes in the basics of sending and receiving messages to better support languages in addition to C++. Much of this was worked out with folks on our discord community. Thank you!
Loopback Service
- This release includes an internal build of
MidiSrv
, the actual Windows Service behind Windows MIDI Services. The service is what connects to transports and drivers, hosts filters, and routes messages. - The version of
MidiSrv
that comes with this release is not yet fully functional. However, it has a single hard-coded Loopback bidirectional endpoint built into it which echos back to MIDI In everything sent to MIDI Out on the Bidirectional endpoint. The loopback code is not in this repo, and will not be used in production. The device Id sent is ignored and the same loopback endpoint is always returned. - The service does have a complete path from API to loopback and back, using the mechanisms that will be used in production.
- The sample apps currently require the loopback endpoint service as do most of the tests.
Updated Samples
- The C++
sdk-client-basics
"get started" sample app has been updated to work with this version. - The C#
sdk-client-basics-cs
sample has also been updated
Important Notes
- The SDK calls are largely no-ops at the moment. We're working on it. Most of the functionality you will want to use from the SDK will be related to enumeration and getting additional information, names, etc. That is not yet in place other than stubs.
- The SDK includes some message listeners. Infrastructure is in place for them, but they are not yet functional. Intent there is to enable you to open a single connection to an endpoint (connections are expensive, relatively speaking), but get filtered (by group, for example) messages much like a MIDI 1.0 Input Port today. Sending is always done directly to the MIDI endpoint without any filtering.
- The only type of MIDI endpoint you can use is the Bidirectional endpoint. The Input and Output-only endpoints are non-functional and will throw failure
hresult
codes. - The send/receive mechanisms which use
IMemoryBuffer
are not yet complete, but the other mechanisms are in place other than the FillXXXArray methods. These all throw the not-implementedhresult
code. - Currently, an app can only create one connection to the MIDI endpoint.
- Currently, only one app can connect to the
MidiSrv
service. - If you fill the service with messages rapidly, you will likely get an error after a few thousand of them and have to stop and start the service. There are some known issues around service stability at the moment. For example, this happens after several runs of the benchmarking tests.
- Enumeration of MIDI 2 devices / endpoints is not yet in place. This is currently being worked on as are the client and device managers in the service.
- No updates to user tools for this preview.
- No "get started" documentation updates for this preview -- just the samples.
- You must be running Windows 10 22H2, or Windows 11 to use Windows MIDI Services.
We recommend using the C++/WinRT NuGet package and Visual Studio or msbuild
. However, to manually create projections, you can use the cppwinrt
command-line tool to create the header info outside of Visual Studio. C++/WinRT is a header-only library and is standards-compliant unlike C++/CX.
The cppwinrt
tool is included in this NuGet package: https://www.nuget.org/packages/Microsoft.Windows.CppWinRT
Example for the SDK: cppwinrt -in local -in Microsoft.Devices.Midi2.winmd -out some_output_folder -component -verbose
Note that C++/WinRT has a dependency on C++ 17. This is untested with C++ 20 and is unsupported on versions older than C++ 17.
As always, we welcome your feedback here and on the Discord server. Please do be sure to look at the sample applications and the notes above, first, as they may unblock you if you are stuck.
Removing some friction: SDK interim developer preview 002
Similar use as the previous release: this is primarily for testing that you can build your apps against the SDK.
Note: As before, many method calls will result in no-impl errors. This is by design. To know which methods are supposed to be working, look at the sdk-core-cpp-winrt-tests project and look at the test cpp files in there. All tests in the SDK project are currently passing.
Updated Targets in NuGet Package
The dll, winmd, and pri files are all copied to the output directory now. The Pri file isn't currently used, but will be in the future. The WinMD file is needed for compilation, but not to run. The DLL is required with your application.
When compiling an app using the SDK
- Add the NuGet package (use a local package respository. I use D:\peteb\Documents\GitHub\microsoft\midi\publish\ and have it set up in the NuGet Package Manager in Visual Studio
- If you see an error about a missing MIDI header file, build or rebuild the project.
New dependency for building the SDK
You don't need to build the SDK, but if you want to, you'll need the new dependency.
The Windows MIDI Services SDK has a dependency on boost 1.82 header libraries because I hate reinventing things. The root Boost install folder should be in the system environment variable %BOOST_ROOT% and in your Visual Studio project include path for all build configurations. This is internal, though, and only a consideration if you are building the SDK yourself.
Breaking changes in SDK
- CheckForWindowsMidiServices has different signature and updated return type now
- MidiSession uses an IMapView instead of IVector for the list of endpoint connections. This gives you O(1) access to the endpoints without you having to keep your own list
- Session.ConnectToEndpoint has the redundant boolean parameter removed
- Probably a few others, but we're not yet at the point where we track them that closely
Faked results
Some calls, like MidiServices::CheckForWindowsMidiServices()
return fake results right now.
Updated Sample
The sdk-client-basics
sample has been updated to use the NuGet directly, and to be in line with the SDK changes. I've also commented out a few lines that throw exceptions right now so you can run it without getting thrown into the debugger.
SDK-local inproc loopback for testing
This has not yet been implemented, but you may see some of the code and wonder about it.
- This is an SDK-only MIDI loopback that you'll be able to use for testing in future builds. It has no dependency on the MIDI Services Windows Service or API.
- I've started implementing this, but it is not currently functional beyond creating the stub of the endpoint. If you try to use it beyond simply creating the two UMP Endpoints, expect errors.
NuGet and Code below are in sync. I will not update this release in any way that gets them out of sync
Thanks to Geil Bremmers and muzak for their testing of the previous preview!
Updated: Core SDK Shape Developer Preview 1
PLEASE READ THIS ENTIRE POST
Note: Rather than create a new release, I've updated this one. I won't usually do that, but really this was about getting a first release that folks can compile against, and the previous NuGet package failed there. The source code in the zip is out of date.
I know many DAW and audio developers are new to WinRT, so this release is to help you get started with it and also to be able to look at the SDK in the context of your own project, and provide feedback. The Core SDK is neither complete in shape nor functional. The packages in this release are for Intel x64 architecture only, not Arm64.
ALMOST ALL SDK CALLS WILL FAIL WITH AN EXCEPTION. THIS IS BY DESIGN
The implementation of almost every method call is this:
throw hresult_not_implemented();
One exception to that (no pun intended) is the MidiServices::SdkVersion
call. That will return a valid string. You can use that to verify you can call methods/properties and that the toolchain is working for you. Additionally, there's now a DummyClass which you can use to verify calls work. See the SDK Test project for an example of calling that.
The intent here is to provide a set of .winmd and .dll files that developers can use to make sure they are able to reference the WinRT library and call functions in their code.
Please refer to this documentation for getting set up:
For developers (C++) who need to access the DLL and WinMD directly, here are the steps. Right now, everything is part of the same NuGet package and installation is somewhat manual. That will change in the future as we break everything out by the type of client.
Current Way for Visual Studio:
- Set up a local NuGet Package Repository on your dev PC. On my setup, it's the "publish" folder under the "midi" root of the GitHub project. Easiest way to do this is to go into the NuGet Package Manager, click the settings button, and then add a local repo. I called mine "MIDI Services Local" and have the SDK NuGet generation steps throw the files in that folder.
- Put the downloaded NuGet package in that folder
- In the Project, add a NuGet reference to the package (Manage NuGet Packages)
- After that, until the .targets are set up properly, there's one manual step: in the same project, click "Add Reference" and then "Browse" to the project file's packages subfolder, then to the folder for this NuGet package, and in there, down to the runtimes\win10-x64\native folder (there will be a .winmd a .dll, and a .pri file in there) and reference the .winmd directly. This will force C++/WinRT to generate the projection. And, if you were building the sample project, remove the error about the missing Microsoft.Devices.Midi2.h file.
Alternative way for all tools:
- If you do not have Visual Studio 2022 installed, and don't plan to use it, then install the latest VC runtime for your platform. NOTE: The first preview here will only work with setups that have Visual Studio 2022 installed as it has a dependency on the debug VC++ runtimes. Working on it.
- Download the NuGet package.
- Change the file extension of the package to .zip from .nuget
- Inside the file, copy the .winmd and .dll files from runtimes\win10-x64\native\ to your project. Put them both in the same folder.
- In Visual Studio, add a reference to the .winmd file (see Get Started documentation in this repo for more information on this, including using with other toolchains.)
The root namespace is Microsoft::Devices::Midi2
Everything (SDK calls, namespaces, etc.) is subject to change, but it is getting more solidified over time. Feedback and discussion welcome in GitHub and on Discord.
Note: the C# projection is in the same NuGet package. Please see the Gett Started documentation for how to use the C# NuGet.