In-box Developer and Technical Customer Preview 9
Pre-releaseThis release is for developers and technical customers with an interest to test, file bugs, and provide feedback. There are almost certainly bugs and missing/incomplete features. Do not install anything unless you have read these release notes and are comfortable with what is here.
Please refer to preview 8 for the full list of changes up until this release. https://github.com/microsoft/MIDI/releases/tag/inbox-dev-preview-8 . This set of release notes only covers the delta from Preview 8.
Plan is to have all of these transports and the API in Windows 11 25h2 and higher starting during the last week of November 2026. The cutoff for getting into that release is in September, so that is what we are working towards. Any issues found after the cutoff will be fixed in subsequent Windows updates.
Updated 2026-09-21. See notes at bottom
Permitted use
We want to ensure customers have the best experience going forward. Because of this, we want to ensure that these app-local binaries are not present on customer systems which have the binaries in System32. There is nothing in these binaries to enforce this, so it is entirely on you, the app or library developer, to ensure you do not distribute these files in situations where that happens.
"Binaries" here refers to the .dll, .pri and .pdb files included in the packages in this release, as well as any tool .exe files included. "Product" here refers to your application, library, service, or other code you are writing against these files.
| Use | Permitted? |
|---|---|
| Development | Your developers may use the binaries here for development and testing of future releases of a product |
| Testing | Your testing team(s) may use these binaries with your product |
| Customer Preview | You may distribute the WinRT API binaries with an alpha/beta/preview version of your app as long as that app has an enforced (through code or obvious and explicit agreement) expiration date of no later than January 15, 2027, and you clearly indicate that this is using pre-release code which may not work in production. You are responsible for all support |
| Production / Release app | These WinRT API binaries are not permitted for this use. Do not distribute these binaries with a production application unless you have received explicit emailed permission from Pete Brown at Microsoft |
| Customer Use on their own PC | You are permitted to use all the packages here on your own PC(s). You will want to uninstall these when the official Windows releases come out. |
Do not redistribute any of the installers or transports.
What to Test?
Technical Customers
If you are a technical end-user, I would love testing on your experience with Bluetooth MIDI 1.0 devices, with the Patchbay and other apps like the Troubleshooting app, and more. Provide your feedback on Discord https://aka.ms/mididiscord as a new thread in the midi user questions channel, or here as a bug. Whichever works best for you.
If installed before the November release, this doesn't replace any existing in-box delivered components (like KS/KSA transports), so you are welcome to try it out and test.
Developers
For developers, please provide API feedback and log any bugs you run across.
Both
As mentioned below, keep in mind that not all features, especially in the MIDI 2 loopbacks, will be available until after the November release.
API Changes
NuGet package version for this release is 0.99.79-devpreview.9.
Three groups of changes landed in the API this time, and they came from three different places. The first group is small, targeted, and came from a developer working on a real application with preview 8. The second and third are new feature areas that were developed alongside the new in-box tools that use them.
Partner Feedback Changes
These changes were driven by some last-minute important partner feedback on the current API, based on use in a real-world application. Everything here is in the enumeration and watcher area, which is the first thing any host application touches and the part that is hardest to get right from the outside.
Update events now tell you what actually changed
MidiEndpointDeviceInformationUpdatedEventArgs gained six new properties:
IsEndpointDiscoveryStateUpdatedIsMidi1PortMappingUpdatedIsDevicePresenceUpdatedAreLatencyPropertiesUpdatedAreTransportSuppliedPropertiesUpdatedAreSystemDevicePropertiesUpdated
Previously, a number of the properties the watcher asks for were not covered by any flag at all. An application could receive an Updated event with every flag reporting false and have no way to know what to re-read, other than re-reading everything. Every property the watcher requests is now covered by at least one flag.
There is deliberately no "something else changed" catch-all flag. A catch-all becomes a compatibility problem the first time a new specific flag is added, because existing code cannot tell whether the catch-all means "a thing you know about" or "a thing you do not". Instead, the watcher now logs an error when it computes an update with no flags set at all, so that a property added in the future without a matching flag group is caught by us rather than by you.
MidiEndpointDeviceInformation.IsEndpointDiscoveryComplete
New property reporting whether in-protocol endpoint discovery has finished for the endpoint. This is a hint, not a barrier. Transports which do no in-protocol discovery (for example Bluetooth LE MIDI, and the aggregated MIDI 1.0 devices) set it when the endpoint is created. It is also set after a discovery timeout, not only after a successful completion. Use it to decide when function blocks and declared names are worth reading, not as a gate on opening a connection.
MidiFunctionBlock.RepresentsMidi10Connection default corrected
A default-constructed MidiFunctionBlock reported Reserved for this property rather than Not10. Code which read the value from a function block it had built itself, rather than one supplied by a device, saw a reserved value.
MIDI 1.0 port mapping
Feedback here was that the MIDI 1.0 port mapping for an endpoint is sometimes incomplete at the moment the endpoint's Added event arrives. That is structural and is not going to change: the MIDI 1.0 ports for an endpoint are separate Windows device nodes, created by the service after the endpoint itself, and they raise their own device notifications with no ordering relationship to the endpoint's. An application which needs the ports must watch for the ports.
The correct tool is MidiLegacyPortDeviceWatcher, and both watch-endpoints samples and a new knowledge base article now say so explicitly. See Endpoint arrival and update ordering.
Still open from this round
Being upfront about the items from that feedback which are not fixed in preview 9:
- Update events can be raised on more than one thread, and
UpdatedDevice()hands back the live endpoint object rather than a snapshot taken when the flags were computed. The reasoning is settled — a lock is not the fix, because raising the event inside the mutation lock reintroduces a re-entrancy deadlock that was fixed earlier in September — and the likely answer is to hand back a snapshot. That change is deferred rather than rushed in before the cutoff. In the meantime, treat the properties you read in anUpdatedhandler as possibly newer than the flags. - Function block names can be momentarily blank during discovery on devices which send function block info before function block names. This is a service-side change and lands after the current code freeze.
- The app-to-app (virtual device) sample can leave the service in a bad state on repeated runs. That is a known service defect with a fix already scheduled for the November release. #1047
MIDI CI
(developed in concert with the MIDI Keyboard app and the new in-box General MIDI Synth)
This is a new, substantial namespace: Windows.Devices.Midi2.CapabilityInquiry. It is UMP only, never bytestream, and it covers both halves of MIDI Capability Inquiry — asking a device what it can do, and answering when you are the device.
Resources
Strongly typed, with JSON in and JSON out, so an application never has to hand-parse a Property Exchange body:
MidiProgramList,MidiProgramListEntry— with paging, because workstations have thousands of patchesMidiChannelList,MidiChannelListEntryMidiResourceList,MidiResourceListEntry,MidiResourceLinkMidiDeviceInfo
Messages
MidiCapabilityInquiryMessage— decode a complete CI message from the UMP packets that carried it, including reassembly, with typed accessors for the discovery, property exchange, profile and acknowledgment sectionsMidiCapabilityInquiryMessageBuilder— build any CI message, including chunking a large property reply across multiple messagesMidiCapabilityInquiryMessageType,MidiCapabilityInquiryCategories,MidiProfileIdWindows.Devices.Midi2.Utilities.Messages.MidiSystemExclusive7MessageBuilder— the missing half of the SysEx7 story. We could read SysEx7 out of UMP already; now you can build it.
Initiator side
MidiCapabilityInquirySession— runs on a connection you already have open. Discovery, MUID management, request/response with timeouts, plus events for unsolicited traffic (ResponderFound,MessageReceived,ProfileStateChanged)MidiCapabilityInquiryResponder— one per remote MUID found, with async property exchange and profile callsMidiPropertyExchangeResponse,MidiProfileInquiryResponse,MidiCapabilityInquiryMessageReceivedEventArgs,MidiCapabilityInquiryStatus
Both an async request/response shape and events are provided, because both are legitimately needed.
Device side
MidiCapabilityInquiryDeviceResponder— you supply strongly typed resources and it answers requests automatically, the same way the virtual device API already answers endpoint discoveryMidiVirtualDevice.CapabilityInquiry— the responder for a virtual device. It does nothing until your application enables it and gives it something to publish.
MUIDs are per function block, owned and managed for you, and exposed as a property. Chunking, paging and the property exchange header rules are handled internally.
What is not there yet
Profiles are implemented (inquiry, set on and off, enabled and disabled reports, details), but no in-box endpoint answers a profile inquiry yet, so profiles have only been tested against test responders and virtual devices. The six newer Property Exchange resource specifications (controller resources, channel mode, local control, device state and so on) do not have strong types. They are all reachable today through GetPropertyDataAsync/SetPropertyDataAsync with a JSON header, and publishable through MidiCapabilityInquiryDeviceResponder.SetResource. If strong types for any of those matter to you, please say so — controller resources (M2-117) is the one we think has real value for a DAW.
Sequencing and MIDI File Parsing
(driven by the new MIDI File Player)
Two new namespaces. The MIDI File Player app is built on the same code, which is what shaped the API — every awkward thing the player had to do by hand is something the API now does for you.
Windows.Devices.Midi2.Utilities.Files
MidiStandardFileReader— async, static. Reads from a path or from a buffer.MidiFileReadOptions— every limit is settable, and all of them have safe defaults: total bytes, track count, event count, event byte count, single message size, text lengthMidiFileReadResult,MidiFileReadStatus
The reader handles SMF format 0, 1 and 2, and RIFF/RMID (.rmi) files by unwrapping the data chunk. It is deliberately forgiving: a chunk length which overruns the file is clamped and the result is marked truncated, and a short file keeps what was read, because real MIDI files are broken at a measurable rate. It is also deliberately defensive, because a .mid file arrives by double-click from the internet — nothing is allocated from a declared length without checking the bytes are actually present.
This reader has been run over a corpus of 175,163 real MIDI files — 5.2 GB, 1.4 billion events, 621 million notes — with no invariant violations. 99.6% were playable.
Windows.Devices.Midi2.Utilities.Sequencing
The model:
MidiSequence— the parsed file, plus a tempo map, a time signature map, note pairing, lyric lines and chord symbolsMidiSequenceTrack,MidiSequenceNote,MidiSequenceTempoChange,MidiSequenceTimeSignature,MidiSequenceTextEvent,MidiSequenceTextKind,MidiSequenceLyricLine,MidiSequenceBarPosition,MidiSequenceFormat
A sequence is a handle over its own storage, not a collection of message objects. The corpus above is why. The sparse parts a display genuinely needs in full — tracks, tempo map, time signature map, text events, lyric lines — are ordinary IVectorView collections built once. The dense part is not projected one item at a time: FillNotesInTickRange(start, end, startIndex, ref MidiSequenceNote[]) fills an array you own, so drawing a frame costs one call rather than one call per note. FillSoundingNoteCountsAtTick does the same for a per-track level display.
Position works both ways and neither direction walks the sequence: ConvertTickToMicroseconds, ConvertMicrosecondsToTick, GetBeatsPerMinuteAtTick, GetBarPositionAtTick. GetChordSymbolAtTick and GetLyricLineAtTick return what is in force at that moment rather than what happens at it.
The player:
MidiSequencePlayer,MidiSequencePlayerPosition,MidiSequencePlayerState,MidiSequenceTrackRouting
Notes on the player, because several decisions in it are deliberate:
- It supports both connection models. Construct it with a
MidiEndpointConnectionyou already have open and it borrows it; closing the player leaves it open. Or callCreateForEndpointAsync(session, endpointDeviceId, group)and it opens and owns one. Prefer borrowing — a connection is not cheap. SetSequenceAsyncis the expensive call, notPlay. The whole sequence is converted to UMP once.- The player hands timestamped messages to the service scheduler and lets the service release them, rather than waking up to send each one itself. That is what makes playback steady.
- Per-track routing, mute and solo. Only note starts are held back by muting and soloing — note ends, program changes and controllers always go out, or a muted track comes back on the wrong sound with a chord still sounding.
- Seeking re-sends the bank, program, controllers and pitch bend each channel was left in, so starting in the middle of a file does not play the rest of it on a piano.
SilenceAllNotes()sends note offs for what is sounding, then sustain off, all notes off, all sound off and pitch bend center, on only the channels the sequence actually uses. This matters on Windows MIDI Services specifically: blasting all sound off on all 16 channels would silence another application sharing the endpoint. It is sent for you on stop, on pause, on seek and at the end of a sequence.- There is no position event. Poll
Positionto drive a display.
Other Changes
Outgoing latency is now signed, and compensation has an explicit switch
This is a breaking change for anyone who used these in preview 8:
MidiEndpointUserSuppliedInfo.CustomMidiOutgoingLatencyTickschanged fromUInt64toInt64MidiServiceEndpointCustomizationConfig.OutgoingLatencyTickschanged fromUInt64toInt64
A device can be early as well as late, and an unsigned value could not express that.
Alongside that:
MidiEndpointUserSuppliedInfo.CalculatedMidiOutgoingLatencyTicks(new, read-only) — the figure the transport calculated, reported so an application can show what compensation is in effect without reading device properties itself.MidiServiceEndpointCustomizationConfig.UseCustomOutgoingLatency(new) — whether the scheduler should use the custom value in place of the calculated one. Setting this either way makes the choice explicit, so a measured value can be kept on file while compensation is switched off. Leave it alone and a non-zero latency continues to mean "use it", as before.
Reading stored endpoint customizations
Previously the customization API was write-only from an application's point of view. You could send and save a customization, but not ask what was already stored. New:
MidiServiceTransportPluginConfigManager.GetEndpointCustomizations()andGetEndpointCustomizations(Guid transportId)MidiServiceEndpointCustomization— the stored entry, includingResolvedEndpointDeviceId,IsOrphaned(the entry matches nothing currently on this PC) andHasUserContent(the entry holds something a customer would miss)MidiServiceEndpointCustomizationProvenanceandMidiServiceEndpointCustomizationConfig.Provenance— describes the device an entry was created for, so the entry can still be recognized by a human if its endpoint identifier changes. It takes no part in matching.MidiCustomizationLatencySource— whether a stored latency value was measured or typed in. Latency is the hardest setting to reproduce, so it is worth knowing before deleting an entry.
Transports which cannot report their customizations are skipped, so an empty result is not an error.
This is what the new re-link experience in MIDI Settings and the new midi endpoint customizations console commands are built on. See When saved endpoint settings do not match a device.
Smaller items
MidiSessionnames are now length-limited in the API to match what the service accepts. The limit is measured inwchar_tcharacters.MidiStreamMessageBuilder.ParseDeviceIdentityNotificationMessage— parses a UMP Stream Device Identity Notification into aMidiDeclaredDeviceIdentity. Returns null when the message is not one.- New API contracts:
MidiTransportsSynthApiContract,MidiSequencingUtilityApiContract,MidiFilesUtilityApiContract. - New namespace
Windows.Devices.Midi2.Transports.Synthfor the GM synth. Covered under Transports below.
Samples
- New:
capability-inquiry-browsein both C++/WinRT and C#. Discovers CI devices on an endpoint and reads their resource list, device info, channel list and program list, including chunked and paged replies. - New:
capability-inquiry-virtual-devicein both C++/WinRT and C#. Creates a virtual device which publishes resources and answers capability inquiry for itself. - Updated:
watch-endpointsin both C++/WinRT and C#. Now uses the six new update flags andIsEndpointDiscoveryComplete, and points atMidiLegacyPortDeviceWatcherfor MIDI 1.0 port mapping. - Updated:
simple-app-to-app-midiwith clearer commentary. - All sample projects reference the new NuGet package version.
Transports
New GM Synth
A clean-room MIDI 2.0 rewrite of the in-box synthesizer, shipping as a service transport. It uses the existing gm.dls sound set already present in System32\drivers, and nothing else.
It is a MIDI 2.0 endpoint. It answers UMP Stream endpoint discovery, endpoint info, device identity, product instance ID, stream configuration, and function block discovery and naming, in protocol.
It is a MIDI CI responder, and it is the first in-box endpoint that answers Property Exchange. It publishes ResourceList, DeviceInfo, ChannelList and a full ProgramList — 226 melodic programs with names and tags, delivered chunked and pageable. This makes it the easiest way to test a Property Exchange client on Windows with no hardware: point the new MIDI Keyboard patch browser at it and you get real patch names back.
MIDI 2.0 voice features implemented:
- Note On pitch 7.9 attribute
- Per-note pitch bend
- Registered per-note controllers: pitch 7.25, volume, pan
- Per-note management, including detach
Sound and compatibility decisions, all made against measured data rather than assumption:
- GM1 and GS, honestly declared. It does not claim GM2.
gm.dlscontains all 128 GM1 programs, 98 GS variations and the 9 expected drum kits, but its melodic banks are GS-addressed with the variation in the bank MSB. - Bank select mode is selectable: Roland GS, Yamaha XG, General MIDI 2, or Automatic. This exists because a survey of 175,163 real MIDI files found XG-style bank selects outnumbering GM2-style ones by more than 20 to 1, and neither is addressed the way
gm.dlsstores its variations. Automatic is moved only by a System On or reset; an explicit choice is never overridden. - The drum channel can be moved off channel 10, both through the API and through the GS "use for rhythm part" system exclusive.
- Its own reverb and chorus
Behavior which matters if you are sharing a machine with other audio software:
- The audio device follows sound, not connections. The endpoint protocol negotiator stays connected for the life of any endpoint, so "a client is connected" is not a usable signal. Audio is acquired when a channel voice message actually arrives and released after a short idle with no voices sounding. Channel state — program, bank, volume, pan, tuning — survives that release, so a song which sets up its instruments and then rests does not come back playing pianos.
- Disabling the synth removes the endpoint entirely rather than muting it. Applications which open every MIDI port, which some browser-based Web MIDI pages do, would otherwise hold the synth endpoint open, which holds the audio device, which blocks WASAPI exclusive mode and ASIO. Off means gone. It comes back on enable, and survives a service restart either way.
- It has its own user volume, persisted, and separate from the MIDI master volume that file content sets. The service runs in session 0, so the synth gets no slider of its own in the Windows Volume Mixer; without this there is no way to turn it down independently of master output.
API, console and PowerShell:
Windows.Devices.Midi2.Transports.Synth:MidiSynthManager,MidiSynthConfig,MidiSynthStatus,MidiSynthSoundSetInfo,MidiSynthInstrumentInfo,MidiSynthDrumKitInfo, and enumsMidiSynthRenderMode,MidiSynthAudioOutputMode,MidiSynthBankSelectModemidi synth status | enable | disable | configure, with--temporaryto apply without savingGet-MidiSynth,Set-MidiSynth,Get-MidiSynthEndpointDeviceId- A synth section in the MIDI Settings global settings dialog
Known limitations: WASAPI exclusive mode is present in the enum but not yet implemented. ASIO is not yet in the public API and will not be added without a device selection story to go with it. Poly pressure and channel pressure are not yet routed to anything. WinRT API reference documentation for this namespace is not written yet.
Other Transports
- Endpoint customization is now shared across the transports that support it. They use one update loop, they record provenance in the config file (for later reconnection hints), and they can report their stored customizations back to a caller. This is the transport half of the new read API above.
- Kernel Streaming and KS Aggregate: the endpoint ID hash is now frozen in a shared header, so an endpoint identifier cannot drift between builds and take a customer's customizations with it. Additional hardening in the device watcher.
- Loopback and Basic Loopback: a transport which rejects a configuration change now reports why. Previously a failing result discarded the transport's own error code and localized message before it reached the caller, so several rejection reasons were invisible.
- Default endpoint images for the General MIDI synth and for Bluetooth LE MIDI, and the app-to-app image is now named after its transport code so it is actually found.
- Removed some unused prototype message transforms from the service.
Applications
MIDI File Player Preview
A brand new app. It plays standard MIDI files to any Windows MIDI Services endpoint and group, and it is also the showcase and the real test for the new sequencing API.
- Reads SMF format 0, 1 and 2, plus
.rmi,.karand.smf - Two views. The horizontal track roll shown above, and an alternate falling-notes view with a piano keyboard. Both are drawn with the composition engine using a pool of reused visuals, so the cost tracks notes on screen rather than the size of the file.
- Bar and beat grid, with beats dropped automatically when they get too dense
- Track rail with per-track color, mute, solo, live activity level, and patch names. Patch names come from the file's own instrument name meta event first, then General MIDI. The middle source — the device's own name for that bank and program over MIDI CI Property Exchange — is next.
- Live tempo at the playhead, not a single "BPM" for the file. A MIDI file does not have a tempo, it has a tempo map; the sample file shipped with Windows has 20 changes in it.
- Lyrics, including Soft Karaoke
.karfiles, assembled into readable lines rather than one syllable per event - Chord symbols. A widely used manufacturer system exclusive carries chord names in lead sheet and karaoke files; 67,429 of them across 571 files in our corpus. The chord panel appears only when a file has them.
- Play queue, single-instance file handoff, and file associations. The installer registers a ProgId and adds the player to Open with and to Settings > Default apps. It deliberately does not take the default association for
.mid— Windows does not allow an installer to do that, and applications which try get reset and reported to the customer. - Panic on stop, pause, seek, mute, solo, load, close and end of file, limited to the channels the file actually uses.
MIDI Patchbay Preview
Another brand new app. A drag-and-drop canvas for routing MIDI between endpoints on this PC.
- Endpoints are nodes; connection points are per group, labeled with the same name that group gets as a MIDI 1.0 port
- Drag to connect, drag a connection end to retarget it, or click an output point then an input point if you prefer the keyboard. Drag nodes to arrange them, zoom, fit to content.
- Quick patch — pick a source endpoint and group and a destination endpoint and group, and you are routing. From there it is an ordinary patch.
- Patches are saved as individual
.midipatch.jsonfiles inDocuments\MIDI Patchbay, auto-saved, with an optional description. Temporary patches are supported too. - Circular route detection, as far as the app can see. Loopbacks are known with certainty; everything else is reported as possible rather than muted, because hardware loopbacks are invisible to us.
- Filters per connection: message types, channel voice statuses, system messages, channels, and an optional note range with a 128-key picker
- Transforms per connection, applied after the filter: transpose, a 1:1 note map, note-on velocity curve and rescale, and a 1:1 control change map. Note map entries are exceptions — a listed note goes exactly where the table says, everything else is transposed. Each note map row has an audition button.
- Offline endpoints are normal, not an error. The nav pane and the node both show it, and you can re-point a patch at a different device.
- Create MIDI 1.0 and MIDI 2.0 loopbacks from the design surface, because client-side routing only goes source to destination and a loopback is how a DAW joins the graph
- Start with Windows, and minimize to the notification area
On performance, since this sits in a MIDI path: the forwarding hop is roughly 27 microseconds end to end. A connection with a filter and a transform present but untouched adds 0.1 nanoseconds per message; with everything switched on, 3.25 nanoseconds. That is about 0.012% of the hop. So it's all super fast.
Storage is per-patch JSON files, not the service configuration file, and there is no new API surface for this. If the service ever gains routing natively, a migration tool folds the patch files into the main configuration.
Patches are only valid while the app is running. Therefore there is a System Tray option and a way to start this with Windows.
MIDI Keyboard
- The patch browser is now built on the new MIDI CI API instead of hand-rolled. The implementation went from roughly 960 lines to 250, and the
libmidi2andvcpkgdependencies are gone from this app entirely. - Point it at the new General MIDI synth endpoint and the bank and program flyout fills in with real names and tags read over Property Exchange.
- General UI updates.
- Try this on a touch screen!
Other app changes
MIDI Settings
- Re-link. When saved endpoint settings match nothing connected, a message appears above the endpoint list. The review dialog shows your orphaned settings on the left, with the name and picture you gave them and a summary of what each holds, and the devices they could be moved onto on the right. It puts the most likely candidate at the top and says why. It does not choose for you, and when nothing is clearly best, nothing is selected. Most of the time the honest answer is "that device is just unplugged", and the message can be dismissed permanently. This was designed to help with cases where the Endpoint Id changes due to using a different hub or USB port.
- Global settings dialog, including configuration file selection, creation and copying, MIDI 1.0 port naming approach, an elevated service restart, and the new synth controls.
- Notifications can now be configured for all users on the PC, with elevation.
- A first-run invitation.
MIDI Console
- New
midi synthcommand group - New
midi endpoint customizations list | relink | forget, with--orphanedonlist - Considerably better message decoding in the monitor output — many more message types are now decoded rather than shown as raw words
midi loopback removeandmidi basic-loopback removenow honor--save-to-config, which they parsed and ignored before, so a removed loopback no longer comes back after a service restart
MIDI Loopback Setup
- Manages both types of loopbacks, as before. It now works correctly against the loopback transport that is already in Windows today, by gating each feature on what the transport reports it can do rather than assuming. Some functionality will not be enabled until the November release has rolled out to your PC, and the app tells you when it is running with a reduced feature set rather than offering buttons that silently do nothing.
- Because of this change, you can now use this suite of apps rather than the old MIDI Settings app. The Loopback support was the main thing gating us here.
PowerShell
- New:
Start-MidiFilePlayback,Stop-MidiFilePlayback,Get-MidiSynth,Set-MidiSynth,Get-MidiSynthEndpointDeviceId
MIDI Troubleshooter — UI fix.
Log collection — CollectMidiLogs now gathers trace from the synth, MIDI Clock, MIDI File Player and Virtual MIDI Keyboard, none of which were previously collected.
Documentation
- New WinRT API reference section for Capability Inquiry — 20 pages covering every type in the new namespace
- New WinRT API reference sections for
Utilities.SequencingandUtilities.Files— 20 pages - New reference pages for the endpoint customization read API and
MidiSystemExclusive7MessageBuilder - Updated reference pages for the new update flags,
IsEndpointDiscoveryComplete, the signed latency properties,MidiVirtualDevice.CapabilityInquiryand the new contracts - New knowledge base article: Endpoint arrival and update ordering — what order endpoint and MIDI 1.0 port notifications arrive in, what is and is not guaranteed, and how to write a watcher that is correct anyway
- New knowledge base article: How to read a device's patch list — a walk through capability inquiry, property exchange and program lists
- New knowledge base article: When saved endpoint settings do not match a device
- New tools page for MIDI Patchbay
- Tools pages rewritten and brought up to date: Bluetooth MIDI Setup, Loopback Setup, Network MIDI 2.0 Setup, MIDI Scratchpad, SysEx Tool, Troubleshooter, Settings, MIDI Monitor and the console
- Knowledge base and tools index pages are now categorized rather than being one long list
Not yet written: reference documentation for the Windows.Devices.Midi2.Transports.Synth namespace, and tools pages for MIDI File Player, MIDI Keyboard and MIDI Clock.
Install Instructions
Using Windows Settings > Apps > Installed Apps, Uninstall all previous MIDI packages before installing this.
These previews are now signed by me. You will still get warnings like "not commonly downloaded" as file reputation is not automatic. But choosing to keep and run them will work.
They also require you to accept a few SmartScreen prompts and choose "keep" so the downloads are not automatically deleted. If you use third-party antivirus or anti-malware software, it may also delete the installs after they happen. You will need to refer
to your own software's settings.
If you are at all uncomfortable installing these preview packages, then please wait for the official versions to install with Windows 11 around the end of the calendar year.
Minimum OS version: Windows 11 25h2.
- Make sure you have read all of the information above. Do not install anything without reading and understanding what is in this release.
- Before installing anything, completely uninstall all previous loopback previews, network previews, Bluetooth previews, and SDK Runtime and Tools packages. Uninstall the previous in-box developer previews as well as the older release candidates. Ensure that your
Program Files\Windows MIDI Servicesdirectory is empty or missing, and delete the contents if not. - Uninstall any third-party Bluetooth MIDI drivers or apps like the KORG Bluetooth MIDI driver, or Bluetooth bridge apps.
- Install the Basic Loopback, Network, Bluetooth, and GM Synth transport packages. The order is not important. You don't have to install all of them if you are only interested in a subset.
- Install the Tools package. Again, the order is not important.
A common question is "will I need to uninstall these bits before the November release?". In general yes, but other than possibly with the PowerShell cmdlets, we do not anticipate issues if you do not. Just some confusion when you have multiple versions of the same app installed.
Firewall
If you are using Network MIDI 2.0, you may need to let the MIDI Service through the firewall. Additionally, you will need to let the Network MIDI 2.0 Setup app through the firewall; it will prompt on first use. See Network MIDI firewall. If you are using a third-party firewall product, please refer to their instructions. Both the app and the service need access.
Packages
Windows MIDI Services itself is already installed on your PC. These packages are add-ons which preview functionality coming to Windows. They are logically broken up so you do not need to install something you do not need or want.
| Package | Contents |
|---|---|
| Network install | The Network MIDI 2.0 Setup app and the Network MIDI 2.0 transport |
| Bluetooth install | The Bluetooth MIDI Setup app and the Bluetooth MIDI transport |
| Basic Loopback | The basic loopback transport. The app, which also supports MIDI 2.0 loopbacks, is in the tools install |
| GM Synth | The GM/GS Synth transport. This is a MIDI 2.0 rewrite of the in-box MIDI Synth, using the existing .dls file from System32 |
| Tools install | All the other console and GUI tools including the MIDI Console, MIDI Settings, MIDI Monitor, MIDI Clock, Troubleshooting, MIDI Player, MIDI Patchbay, and the PowerShell cmdlets for MIDI. Everyone will want this |
| NuGet package | For developers to build against in preparation for the November release |
| Samples zips | Source for the C++/WinRT, C# and PowerShell samples |
Updates
Updated 2026-09-21
- The custom action that preserves the registry is now signed so Smart App Control should no longer block it
- Tray support in the Patchbay app fixed
- Discovered accessibility bugs fixed.
- Settings icon moved to the title bar in the Monitor and Scratchpad apps, to patch the other apps.
- GM Synth Function Block UI Hint set properly, and replies to the property exchange capabilities request
- MIDI Keyboard sends the property exchange capabilities request
- MIDI Player now has borders around notes in the piano roll. This does make the animation somewhat less smooth, so still working on tweaks to that.
The .84 version of the Tools installer fixes the Troubleshooter issue where it wouldn't save the capture.