まえがき
コードとは関係ない話ですが、最近VRCがアップデートされてMIDIデバイスを選べるようになりました。
https://docs.vrchat.com/docs/vrchat-202111#midi-system
そのときに渡すMIDIデバイス名をなんとなくC#から取得したかったので書きました。
しくみ
Win32API に入ってる winmm.dll の midiInGetDevCaps を DllImport で C# に持ってきて叩いてるだけです。
https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/nf-mmeapi-midiingetdevcaps
もとが C++ なので、Midiデバイス名を格納する struct とかをドキュメントに合わせて用意しています。
コード
GetMidiDeviceNames.cs
using System;
using System.Runtime.InteropServices;
class GetMidiDeviceNames
{
[StructLayout(LayoutKind.Sequential)]
public struct MidiInCaps
{
public ushort wMid;
public ushort wPid;
public uint vDriverVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szPname;
public uint dwSupport;
}
[DllImport("winmm.dll")]
extern static uint midiInGetNumDevs();
[DllImport("winmm.dll")]
extern static uint midiInGetDevCaps(uint uDevID, out MidiInCaps pmic, int cbmic);
static void Main()
{
uint midiInNumDevs = midiInGetNumDevs();
Console.WriteLine("midi # of devs: {0}", midiInNumDevs);
for (uint i = 0; i < midiInNumDevs; i++)
{
MidiInCaps midiInCaps = new MidiInCaps();
midiInGetDevCaps(i, out midiInCaps, Marshal.SizeOf(typeof(MidiInCaps)));
Console.WriteLine("#{0}: {1}", i, midiInCaps.szPname);
}
}
}
コンパイルして実行
$ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe GetMidiDeviceNames.cs
$ GetMidiDeviceNames.exe
midi # of devs: 2
#0: Steinberg UR44C-1
#1: Impact GX61
あとがき
素のWin10でもC#のコンパイラ(csc.exe)が入ってるんですね~!おどろき。パス通ってないけど。
今回は練習もかねて自分で書いたんですが、検索したら案の定いい感じのラッパーを書いてくれてる人がいたので、普通にこれ使えばいいと思います。
https://github.com/colgreen/Redzen.Midi