views:

266

answers:

2

Hello,

I noticed that when reading MIDI port names from MME, the names are multi-byte strings encoded using the ANSI Codepage, which my app uses by default. When receiving those names from the DirectMusic driver, the names are wide-character strings encoded with the OEM Codepage. See this article by Raymond Chen for a quick refresher on Codepages.

On my German system, this means that when using the current codepage, which turns out to be the ANSI one, I get "Audiogerät" from MME, and "Audiogeröt" from DirectMusic, the latter being wrong. This gets fixed when I treat that last name as OEM-encoded instead.

So how do I know with which codepage to decode those names? Why does the name coming from DirectMusic get encoded differently? Does it come from the USB driver? The COM framework? DirectMusic? How can I know for sure which codepage to use when reading the names of my MIDI ports?

For info:

  • I use the MultiByteToWideChar() and WideCharToMultiByte() functions to perform the conversions, with CP_ACP and CP_OEMCP as argument for the codepage to use.
  • I use midiInGetDeviceCaps() to get MIDI port information from the MME subsystem...
  • ... and convert MIDIINCAPS.szPname using the CP_ACP (ANSI) codepage.
  • I use IID_IDirectMusic8::EnumPort() to get port information from DirectMusic...
  • ... and convert DMUS_PORTCAPS.wszDescription using the CP_OEMCP codepage.
A: 

I don't know for sure why the DirectMusic framework would use one set of codepages, and MME another, but the solution here on your end is probably to build an abstraction layer and then make specific implementations for each API. That way, the higher levels of your software don't need to concern itself with details like this.

That said, the endpoint names definitely come from the OS. USB MIDI devices specify only endpoint types (ie, either input or output, and the number), but the OS is free to interpret them as it sees fit, which is why they are localized.

There is not a specific API call (as far as I know) to find out which codepage the framework will deliver its strings in. However, DirectMusic does seem to use double wide characters with OEM codepage as a general convention, though I could not find this clearly stated in any of the MSDN docs. In the MSDN DirectMusic documentation about MIDI port capability structures, the description type clearly is defined as a WCHAR, and the Game Audio Programming book seems to also indicate that this type is an API-wide convention. While it's dangerous to assume that OEM is the default encoding for these chars, I can't find anything that says otherwise (and googling for "DirectMusic codepage" now lists this page as the top hit).

Edit: Check out this stackoverflow question on determining the current OS codepage. It is possible that the DirectMusic API sets the codepage in this manner.

Nik Reiman
A: 

There isn't really an automatic way to tell what codepage is used for these types of data. See here: http://stackoverflow.com/questions/90838/how-can-i-detect-the-encoding-codepage-of-a-text-file/90967

Coding With Style
As such, no you can't. But I was hoping that this was documented somewhere, either explicitly or indirectly (e.g. because drivers always use the OEM Codepage).
Carl Seleborg