Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AppCompat]Different port names for MIDI 1.0 from Windows MIDI Services vs. WinMM are problematic #522

Open
ReinholdH opened this issue Feb 7, 2025 · 18 comments
Assignees
Labels
area-service-or-api 🖥️ Related to the Windows Service, core API, abstractions, etc. bug 🐞 Something isn't working in progress Approved work in progress

Comments

@ReinholdH
Copy link

ReinholdH commented Feb 7, 2025

Describe the bug
Different port names for MIDI 1.0 from Windows MIDI Services vs. WinMM are problematic

To Reproduce
Connect external MIDI device and compare MIDI 1.0 port names of Windows MIDI Service vs WinMM

Expected behavior
Port names for MIDI 1.0 from Windows MIDI Services vs. WinMM should be the same

Screenshots
Screen shots of MIDI configurations Screenshot_comparison_WinMM_WinMIDIServices.zip

Installer Name or Version
Customer Preview 1 - Feb 5, 2025 Windows Insider Canary

Desktop (please complete the following information):
Windows 11 Canary, OS Build 27788.100

Device information, if this is with an external MIDI device:
Yamaha keyboard PSR-S910
Yamaha Driver: USB-MIDI Driver V3.1.4 for Win 11/10/8.1/8/7 (64-bit)
https://de.yamaha.com/de/support/updates/umd_win64_kbd.html

Application Information
Notation Composer, Musician, Player from www.notation.com

Additional context
One essential point for MIDI 2.0 is that the exsiting interface for MIDI 1.0 is kept and stays the same. This fundamential principle is key to use existing MIDI 1.0 hardware AND software. I consider it to be problematic that port names for MIDI 1.0 are different with Windows MIDI Services compared to the port names provided by the WinMM interface.

Let me bring up an example:
The Yamaha PSR-S910 keyboard has two ports:
Port 1: input to and output from the software
Port 2: output from the software

WinMM offer the interface calls midiInGetDevCaps, midiOutGetDevCaps to retrieve the port names from keyboard.

WinMM result of midiGetDevCaps / midiOutGetDevCaps gives:
Port 1:
midiInGetDevCaps
MIDIINCAPS midiInCaps.szPname = "Digital Keyboard-1"
midiOutGetDevCaps
MIDIOUTCAPS midiOutCaps.szPname = "Digital Keyboard-1"

Port:2
midiOutGetDevCaps
MIDIOUTCAPS midiOutCaps.szPname = "Digital Keyboard-2"

Windows MIDI Services result of midiGetDevCaps / midiOutGetDevCaps gives:
midiInGetDevCaps
MIDIINCAPS midiInCaps.szPname = "Yamaha USB-MIDI-1 I-1"

midiOutGetDevCaps
MIDIOUTCAPS midiOutCaps.szPname = "Yamaha USB-MIDI-1 O-1"

midiOutGetDevCaps
MIDIOUTCAPS midiOutCaps.szPname = "Yamaha USB-MIDI-2 O-2"

Due to the downward compatibility of Windows MIDI Servives with the WinMM interface introducing a new naming scheme is problematic because:
(1) ports have different names now
(2) exiting apps need to be changed to achieve the same logic that input and output ports can be associated to each other

Since the early days of the WinMM interface the names of the ports are used to associate input- and output ports to each other. Further the port names are used through the software to determine a certain behavior. Such behavior of MIDI ports is stored in device configuration files by a software addressed by the name of ports. We have customers who verbosely use such configuration files where they connect up to 50 different USB MIDI devices at the same time. A typical kind of an "unusual" MIDI device is the Ampero Control foot switch (https://www.hotone.com/products/controlers/Ampero%20Control) ) Folks use such MIDI devices to switch instruments in live performances. Another example is that folks created MIDI tracks for MIDI devices (addressed by name) to launch smoke on stage by certain MIDI events. Keeping the name of such devices between WinMM and Windows MIDI Services is essential.

From a user point of view it is not acceptable that all the configuration setups have to be adopted due to an update of Windows 11.

I fully appreciate all the work and ideas which have been incorporated for MIDI 2.0 and in particular to be downwards compatible to MIDI 1.0. But on the other side this new design needs to meet the real world of existing solutions which are available for ~30 years now.

Thanks for understanding such situations.

Reinhold Hoffmann
CEO of Notation Software www.notation.com

@ReinholdH ReinholdH added the bug 🐞 Something isn't working label Feb 7, 2025
@ReinholdH ReinholdH changed the title [BUG] Different port names for MIDI 1.0 from Windows MIDI Services vs. WinMM are problematic Feb 7, 2025
@Psychlist1972
Copy link
Contributor

Psychlist1972 commented Feb 7, 2025

Hi Reinhold.

Thanks for the report.

Other than supporting multi-client, the top feedback we've had over the years is that our MIDI port names are not good, which is why we changed them during the developer previews. It's also important to note that we now allow customers to change the names of devices and ports themselves (it's not enabled in Customer Preview 1, but the code is there).

Can you run the midiksinfo.exe tool (installed with the SDK) and paste the output here for just the MIDI keyboard? I would like to see what our USB stack is sending us. It's possible the logic is not correct.

(Aside: is there a reason to use the Yamaha driver in this case?)

Pete

@Psychlist1972 Psychlist1972 added needs-investigation 🔍 Needs to be investigated before considering or solving. area-service-or-api 🖥️ Related to the Windows Service, core API, abstractions, etc. and removed bug 🐞 Something isn't working labels Feb 7, 2025
@MusicMaker
Copy link

MusicMaker commented Feb 7, 2025

AFAIK see, Legacy clients use the product name from the USB device descriptor. MIDI services use the Endpoint name.
Perhaps the legacy client should get the EP name in case it's an UMP device

@Psychlist1972
Copy link
Contributor

AFAIK see, Legacy clients use the product name from the USB device descriptor. MIDI services use the Endpoint name. Perhaps the legacy client should get the EP name in case it's an UMP device

We have a hierarchy in there for MIDI 1 devices using a MIDI 1 driver because each device reports in different places. We have to check the KS Filter, which is a USB interface, the device name itself, and the iJack values.

In some cases, the iJack is useless like in the case of the MOTU Express 128 or the ESI M8U. In that case, it just says "MIDI" (which is why WinRT MIDI 1.0 would report 16 ports named "MIDI" if you had one of those). In other cases, the iJack has the full device and port name in it. It doesn't help that if the iJack is empty, our KS stack puts some default text in there with an index number. In another case, the developer ships software with the device which lets the user rename the iJack value. In some cases, the devices group ports by the filter/interface. In others, just by the device. In some cases, the device name and the filter names are different.

So we have to do a lot of special case code.

Here are some examples of the names before the service creates ports/endpoints

Image

Image

Image

Image

Image

In any case, if I can see what the keyboard in this report is sending, I can update the code if needed.

@Psychlist1972
Copy link
Contributor

Ok. It appears that the PSR-S910 may be class-compliant. It can also run with the Yamaha MIDI driver, but that should no longer be necessary if it is class-compliant. If it can work with macOS without the custom driver, or works with iPad, then it is class-compliant.

Here's how to uninstall the Yamaha driver if you would like.
Image

I'm not sure if that will change the names.

@Psychlist1972
Copy link
Contributor

@ReinholdH In my latest PR, I changed the code so that if the device is a MIDI 1.0 device (not a UMP device), we do not append the I/O-# suffix to it.

It'll still help me if you can run the midiksinfo tool and LMK what your arranger reports for names so I can see where the "Digital Keyboard-1" type name is coming from.

It'll take a couple Canary releases before these changes are public. I'll post more when I know more. But I still have some time to look at the code and make more tweaks once I see the midiksinfo output. I'm assuming the pin/jack name is where the Digital Keyboard-1 is coming from, but need to see to be sure.

@ReinholdH
Copy link
Author

Hi Pete,

First of all, thank you very much for your immediate response and your dedication to the project.

Before responding to your questions in details please let me add some more explanation why this topic is very serious for us and others.

Good or bad, WinMM is out for ~30 years and people found very creative solutions to get the maximum out from this interface.

We at Notation Software use the propriatary .not format for saving music arrangements on a per song base and the propriatary .cf3 format to store MIDI device configurations. Both are related. A MIDI device is addressed by its name from MIDIINCAPS midiInCaps.szPname and MIDIOUTCAPS midiOutCaps.szPname. Notation Composer and Musician offer nifty routing capabilities from tracks to MIDI devices. Please see such a routing example for a song (zip from above).

Image

Explanation: The 'Staff Setup' addresses each staff (= track) of the song to a device for playing. The device names are taken from the 'MIDI Device Configuration' which are determined by midiGetDevCaps / midiOutGetDevCaps. When playing this song, the playback output of a staff/track goes to the appropriate output device which could be either any MIDI output port or the audio of the internal 'Notation Software Synth' synthesizer for various drivers (MIDI devices, audio like DirectSound, ASIO, WASAPI, JACK), or Microsoft GS Wavetable Synth. Sophisticated delay adjustment capabilities are included that all works in real-time (of course, not for DirectSound, Microsoft GS WaveTbl not). These routing capabilities provide huge options. Some customers even create separate staves/tracks where special e.g. NoteOn or CC events are added at the certain point in time of a staff/track. Playback is forwarded e.g. to MIDI controlled light devices which switch on light at a certain playback time when the NoteOn or CC events event are received. Due to the real-time capabilities, our software is used from creation of music to performances on stage.

In summary: the MIDI device names (form MIDIINCAPS midiInCaps.szPname and MIDIOUTCAPS midiOutCaps.szPname) are stored in .not files and .cf3 files. This design was created by the former CEO Mark Walsen who was a senior expert at Microsoft in the early 1990's (see https://www.oreilly.com/pub/au/3556).

We are talking here about of 10000s to 100000s .not files of songs and 1000s of .cf3 configuration files which have been created over the past ~30 years by customers. Our software is still able to open .not files from the early days when Notation was founded in 1994 using serialization methods. This is important because musicians have invested tremendous time and effort into their music arrangements over many years.

What would happen in case the MIDI device names are not preserved when Windows MIDI Services is available after an update?

Image

Because of changed names from MIDIINCAPS midiInCaps.szPname and MIDIOUTCAPS midiOutCaps.szPname the former MIDI devices are not detected and become 'Unassigned Devices(s)'. As a fall back all previous assignments which now become 'Unassigned Devices(s)' are re-directed now to the internal 'Notation Software Synth' in order to have at least a sound to be heard. Playing such a song now ends up in a mess.

In order to correct this mess the user needs to reassign all fall back connection for each song to the new names equivalent to the former assignments. E.g. the former assignment to 'Digital Keyboard-1' now need to become a new assignment to 'Yamaha USB-MIDI-1 O-1'. This has to be manually corrected for each staff/track of each song.

To be clear, these manual tasks now need to be done for each staff/track of each song of those 10000s to 100000s songs which may be impacted. We at Notation would get overwhelmed with customer complaints. It would become a disaster.

I hope this detailed explanation makes clear what problems will be created when the device names are different with Windows MIDI Services vs. WinMM. I am pretty sure other apps will run into similar problems.

To your questions:

Ok. It appears that the PSR-S910 may be class-compliant. It can also run with the Yamaha MIDI driver, but that should no longer be necessary if it is class-compliant.

The Yamaha PSR-S910 keyboard does not work without the Yamaha driver. After uninstalling the Yamaha driver, Windows does not find an appropriate driver for the Yamaha PSR-S910 keyboard. Please see

Image

(Aside: is there a reason to use the Yamaha driver in this case?)

We recently made experiences with the brand new Yamaha Genos2 keyboard family. The Windows driver was found to fit but in fact MIDI input from the keyboard only worked partly:

  • SysEx recording (Genos2 to Windows) does not really work, some events work, some don't
  • When more than one Yamaha keyboard is connected to one Windows PC only one really works

We have not found any problems when using Yamaha's drivers for the Genos2. We have not further investigated why there is a different behavior of the drivers. When customers bring up issues, we recommend to use Yamaha's drivers. Only on Linux the Linux default driver works fine.

Can you run the midiksinfo.exe tool (installed with the SDK) and paste the output here for just the MIDI keyboard?

Please see

Image

Because midiksinfo did not show where the names "Digital Keyboard-1/2" come from I ran the command

midi endpoint properties --verbose

for the Yamaha USB-MIDI Driver. Looks like "Digital Keyboard-1/2" somehow come from 'Additional Capabilities/Properties Container". Please see

Image
Image

In my latest PR, I changed the code so that if the device is a MIDI 1.0 device (not a UMP device), we do not append the I/O-# suffix to it.

This is better than today. At least the input- and output ports are grouped together but it does not solve the core problem which I outline above.

I hope that the screenshots may help to show where "Digital Keyboard-1/2" might come from. In order to be dawn sure and to address the importance of the issue, IMHO it is required to check what the 30 years old code of WinMM does for midiGetDevCaps / midiOutGetDevCaps does. It is important that other MIDI devices like Korg, Casio etc. provide the correct results for MIDI device names, too.

Other than supporting multi-client, the top feedback we've had over the years is that our MIDI port names are not good, which is why we changed them during the developer previews. It's also important to note that we now allow customers to change the names of devices and ports themselves (it's not enabled in Customer Preview 1, but the code is there).

Changing device names by users is fine but does not solve the problem outlined above

All in all, I fully understand the request to have better names detected when elaborating the connected MIDI device.

But such a request cannot be done by changing an existing interface fundamentally which is in place for ~30 years,

and by introducing such a change by a Windows update. For Windows 10 such an update comes in "the very last minute" before Windows 10 retires. Many people in particular from our customers base will stay on Windows 10 because their PCs are incompatible to Windows 11. But many customers use those PCs only in isolation where Windows 10 is good enough when not connected to the internet. A request to have better names detected can only be accomplished for the the WinMM MIDI 1.0 interface with e.g. a new call like MIDIINCAPSEX midiInCapsEx.szPnameEx and MIDIOUTCAPSEX midiOutCapsEx.szPnameEx.

Sorry, for the long comment but I hope that I made the whole situation clear.

If there are more points that I should investigate, please let me know.

Thanks

Reinhold

@Psychlist1972 Psychlist1972 changed the title Different port names for MIDI 1.0 from Windows MIDI Services vs. WinMM are problematic [AppCompat]Different port names for MIDI 1.0 from Windows MIDI Services vs. WinMM are problematic Feb 9, 2025
@Psychlist1972 Psychlist1972 added the bug 🐞 Something isn't working label Feb 9, 2025
@Psychlist1972
Copy link
Contributor

Thanks @ReinholdH

@garydan42 for awareness.

Thank you for testing the device without the Yamaha driver. It's class-compliant (works with Linux you said), so I'm surprised it didn't work with Windows without the custom driver. I will ask Yamaha about it, although the keyboard is long out of production. I'm actually super surprised that the name is coming from the device container in this instance. That's the first device I've seen like that, so all good data to have.

Thank you also for the detailed explanation of the problem.

I brought up that users can change the device names, because that will also break your app in the same way as Microsoft providing new names, so has to be considered in any solution here.

Creating an Ex function is a good idea, but is not in scope. We really don't want to add anything new to the WinMM API, but want it there just for backwards compatibility. Everything new (including MIDI 2.0) is in the new API/SDK. And adding an Ex function wouldn't meet the customer requests for lighting up all apps with updating naming, because most WinMM-using apps would not change any code.

One option here may be to offer a per-device switch which uses old naming or new naming for WinMM and would disable the ability to provide a custom name for the ports. We could default it to using old naming. This isn't work we budgeted for (and the old naming is neither simple nor centralized), but it's something I'll look into. Of course, with so many USB devices lacking any unique serial numbers, this switch could end up bouncing a lot.

Windows 10 is a partner and customer request, so this is also the first report with any potential negatives for Windows 10.

@ReinholdH
Copy link
Author

Thanks. All sounds very plausible.

One option here may be to offer a per-device switch which uses old naming or new naming for WinMM and would disable the ability to provide a custom name for the ports. We could default it to using old naming.

May be to find a 'creative way' to pass the option through the midiGetDevCaps / midiOutGetDevCaps interface. Default to using old naming would be good for existing apps to work as before.

I am looking forward for a final solution to test.

@Psychlist1972
Copy link
Contributor

@ReinholdH

As an aside, your software synth is not using DirectMusic for MIDI at all, is it? I see it uses DirectMusic for audio.

Image

That API for MIDI has been deprecated for a long time, and is unlikely to work with Windows MIDI Services (we do not test it)

@ReinholdH
Copy link
Author

As an aside, your software synth is not using DirectMusic for MIDI at all, is it?

Thanks for the side note. Yes, for 'Notation Software Synth' we use the fluidsynth libraries from https://github.com/FluidSynth/fluidsynth under the LGPL license where we are actively involved providing our input to the fluidynth community since many years. In the current version 5.1.1 of Notation Composer/Musician/Player 5 we use fluidsynth 2.3.7 from Oct. 20th, 2024.

It is not 'DirectMusic' but the 'DirectSound' settings from here
https://www.fluidsynth.org/api/settings_audio.html#settings_audio_dsound_device

@Psychlist1972
Copy link
Contributor

AFAIK see, Legacy clients use the product name from the USB device descriptor. MIDI services use the Endpoint name. Perhaps the legacy client should get the EP name in case it's an UMP device

It's much more complex than that. Some names come from iJack/Pin, but as found with WinRT MIDI 1.0, the iJack name is often not useful (eg "MIDI" in the case of some devices like MOTU MIDI Express 128), and it doesn't help that our KS stack will insert an indexed default name into the pin like Foo [2] if there's nothing else there. Some others get it from the interface descriptor that ends up as the KS Filter. Then some get it from the parent device itself. And, as we all just found out in this thread, still others get the name from the device container for some reason.

@Psychlist1972
Copy link
Contributor

@ReinholdH

If you have a moment, can you also share with me a dump of the descriptors from your Yamaha PSR keyboard?

This is the tool I recommend using for that. It's one of the easiest to use.
https://www.thesycon.de/eng/usb_descriptordumper.shtml

Pete

@ReinholdH
Copy link
Author

@Psychlist1972
Pete,

Thanks, here is the dump

Reinhold

============================================
Information for device Digital Keyboard (VID=0x0499 PID=0x1038):


Connection Information:

Device current bus speed: FullSpeed
Device supports USB 1.1 specification
Device supports USB 2.0 specification
Device address: 0x0008
Current configuration value: 0x01
Number of open pipes: 2


Device Descriptor:

0x12 bLength
0x01 bDescriptorType
0x0110 bcdUSB
0x00 bDeviceClass
0x00 bDeviceSubClass
0x00 bDeviceProtocol
0x08 bMaxPacketSize0 (8 bytes)
0x0499 idVendor
0x1038 idProduct
0x0100 bcdDevice
0x01 iManufacturer "YAMAHA Corporation"
0x02 iProduct "Digital Keyboard"
0x00 iSerialNumber
0x01 bNumConfigurations


Configuration Descriptor:

0x09 bLength
0x02 bDescriptorType
0x003F wTotalLength (63 bytes)
0x01 bNumInterfaces
0x01 bConfigurationValue
0x00 iConfiguration
0xC0 bmAttributes (Self-powered Device)
0x00 bMaxPower (0 mA)

Interface Descriptor:

0x09 bLength
0x04 bDescriptorType
0x00 bInterfaceNumber
0x00 bAlternateSetting
0x02 bNumEndPoints
0xFF bInterfaceClass (Vendor specific)
0x00 bInterfaceSubClass
0xFF bInterfaceProtocol
0x00 iInterface

Unknown Descriptor:

0x07 bLength
0x24 bDescriptorType
Hex dump:
0x07 0x24 0x01 0x00 0x01 0x2D 0x00

Unknown Descriptor:

0x06 bLength
0x24 bDescriptorType
Hex dump:
0x06 0x24 0x02 0x02 0x01 0x00

Unknown Descriptor:

0x09 bLength
0x24 bDescriptorType
Hex dump:
0x09 0x24 0x03 0x02 0x01 0x01 0x01 0x01 0x00

Unknown Descriptor:

0x09 bLength
0x24 bDescriptorType
Hex dump:
0x09 0x24 0x03 0x02 0x02 0x01 0x01 0x01 0x00

Endpoint Descriptor:

0x07 bLength
0x05 bDescriptorType
0x01 bEndpointAddress (OUT endpoint 1)
0x02 bmAttributes (Transfer: Bulk / Synch: None / Usage: Data)
0x0040 wMaxPacketSize (64 bytes)
0x00 bInterval

Endpoint Descriptor:

0x07 bLength
0x05 bDescriptorType
0x82 bEndpointAddress (IN endpoint 2)
0x02 bmAttributes (Transfer: Bulk / Synch: None / Usage: Data)
0x0040 wMaxPacketSize (64 bytes)
0x00 bInterval

Microsoft OS Descriptor is not available. Error code: 0x0000001F


String Descriptor Table

Index LANGID String
0x00 0x0000 0x0409
0x01 0x0409 "YAMAHA Corporation"
0x02 0x0409 "Digital Keyboard"


Connection path for device:
USB xHCI Compliant Host Controller
Root Hub
Generic USB Hub
Digital Keyboard (VID=0x0499 PID=0x1038) Port: 4

Running on: Windows 10 or greater (Build Version 26100)

Brought to you by TDD v2.19.0, Dec 5 2023, 12:08:38

@Psychlist1972
Copy link
Contributor

Perfect. Thank you

@sat-okada
Copy link
Collaborator

I have identified similar problems using Cubase. So comment here.

Procedure

  1. Install SevenColor4.zip in ProtoZOA

  2. Create a 4-track project in Cubase 12 as follows

  3. Set the MIDI input/output for each track
    Track1 I-1/O-1, Track2 I-2/O-2, Track3 I-3/O-3, Track4 I-4/O-4
    Image

  4. Save this project.

  5. Open the project file (Cubase12-SevenColor4.zip) in Cubase 14.
    Each port becomes Unmapped.
    Image

@sat-okada
Copy link
Collaborator

Open this project file (Cubase12-SevenColor4.cpr) in Cubase 14 for Mac, the same message "Missing Ports" appears.

Image

The picture below shows the screen where the port assignments have been changed. (Cubase14-SevenColor4.zip)
For each port name, uses I-1, I-2 ... on Windows, but not on Mac.
Image

@Psychlist1972 Psychlist1972 added the in progress Approved work in progress label Feb 16, 2025
@Psychlist1972
Copy link
Contributor

Psychlist1972 commented Feb 16, 2025

Thanks for the report and additional info @sat-okada

The I-n and O-n suffixes have been removed from the next public build.

Naming still isn't complete, however, as it's quite complex to try to replicate what WinMM was seeing before. It comes from more than one place, and varies greatly depending upon the driver.

In addition, changing our names to match the mac won't be acceptable to folks here, because that will, in some cases, differ from what the old WinMM names were.

@Psychlist1972 Psychlist1972 removed the needs-investigation 🔍 Needs to be investigated before considering or solving. label Mar 1, 2025
@ReinholdH
Copy link
Author

@Psychlist1972
Hi Pete,

Thanks for the enhancements in 1.0.3-preview-11.250228-237. This is a tremendous improvement. I can confirm that for my setup (see above) the port names are the same for:

  • WinMM interface - old software
  • WinMM interface - via Windows MIDI Services
  • UMP Midi-1.0 interface - via Windows MIDI Services

Thanks

Reinhold

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-service-or-api 🖥️ Related to the Windows Service, core API, abstractions, etc. bug 🐞 Something isn't working in progress Approved work in progress
Projects
Status: No status
Development

No branches or pull requests

4 participants