.net c#でmidiの送受信をする (おーぷんMIDIぷろじぇくと)
.net frameworkでmidiの送受信を行うには直接WindowsAPIを呼び出す必要があります。
ですが、かなり面倒になるので、今回はc++用のライブラリを使用してmidiの送受信を実現してみます。
この記事では自分用のメモでもあるため、詳しい説明をいれません。
当方プログラミング初心者のため間違いが多いと思います。
.net framework 4.7.2でうまく動くと思います。(まあ、別のバージョンでも動くでしょう)
MIDIメッセージ入出力用ライブラリ『MIDIIOライブラリ』(DLL)
まず、MIDIIOライブラリ バージョン1.2をダウンロードし、「MIDIIOLib1.2」→「Release」内にある「MIDIIO.dll」を実行ファイルと同ディレクトリに配置します。
今回は.net c#フォームアプリケーションでmidiの送受信を行いたいと思います。
下記のコードをnamespace内に記述します。コードの内容は「DllImport」で検索するといろいろ出てくると思います。
public class Open_midi_project
{
//インストールされているMIDI入力デバイスの数を調べる。MIDI入力デバイスが何もインストールされていない場合0を返す。
[DllImport("MIDIIO.dll")]
public static extern int MIDIIn_GetDeviceNum();
//MIDI入力デバイスの名前を調べる。lIndexには0以上、MIDIIn_GetDeviceNumで得られた値-1以下の値を指定すれば、正常にMIDI入力デバイスの名前を取得することができる。その他のインデックスを指定した場合、この関数は失敗し、0を返す。 なお、MIDI入力デバイスの名前は通常32文字以下(ヌル文字含む)であるので、バッファとしては32文字のTCHAR型配列を用意しておけば十分である。
[DllImport("MIDIIO.dll")]
public static extern int MIDIIn_GetDeviceName(int lIndex, IntPtr pszDeviceName, int lLen);
//MIDI入力デバイスを開く。
[DllImport("MIDIIO.dll")]
public static extern IntPtr MIDIIn_Open(string pszDeviceName);
//MIDI入力デバイスを閉じる。
[DllImport("MIDIIO.dll")]
public static extern int MIDIIn_Close(IntPtr pMIDIIn);
//現在使用しているMIDI入力デバイスを閉じ、新しいMIDI入力デバイスを開く。
[DllImport("MIDIIO.dll")]
public static extern IntPtr MIDIIn_Reopen(IntPtr pMIDIIn, string pszDeviceName);
//MIDI入力デバイスをリセットし、MIDI入力デバイスを開いた直後の状態に初期化する。
[DllImport("MIDIIO.dll")]
public static extern int MIDIIn_Reset(IntPtr pMIDIIn);
//MIDIメッセージをひとつ取得し、実際に取得したMIDIメッセージのバイト数を返す。
[DllImport("MIDIIO.dll")]
public static extern int MIDIIn_GetMIDIMessage(IntPtr pMIDIIn, IntPtr pMessage,int lLen);
//インストールされているMIDI出力デバイスの数を調べる。MIDI入力デバイスが何もインストールされていない場合0を返す。
[DllImport("MIDIIO.dll")]
public static extern int MIDIOut_GetDeviceNum();
//MIDI出力デバイスの名前を調べる。lIndexには0以上、MIDIOut_GetDeviceNumで得られた値-1以下の値を指定すれば、正常にMIDI入力デバイスの名前を取得することができる。その他のインデックスを指定した場合、この関数は失敗し、0を返す。 なお、MIDI入力デバイスの名前は通常32文字以下(ヌル文字含む)であるので、バッファとしては32文字のTCHAR型配列を用意しておけば十分である。
[DllImport("MIDIIO.dll")]
public static extern int MIDIOut_GetDeviceName(int lIndex, IntPtr pszDeviceName, int lLen);
//MIDI出力デバイスを開く。
[DllImport("MIDIIO.dll")]
public static extern IntPtr MIDIOut_Open(string pszDeviceName);
//MIDI出力デバイスを閉じる。
[DllImport("MIDIIO.dll")]
public static extern int MIDIOut_Close(IntPtr pMIDIOut);
//現在使用しているMIDI出力デバイスを閉じ、新しいMIDI出力デバイスを開く。
[DllImport("MIDIIO.dll")]
public static extern IntPtr MIDIOut_Reopen(IntPtr pMIDIOut, string pszDeviceName);
//MIDI出力デバイスをリセットし、MIDI出力デバイスを開いた直後の状態に初期化する。
[DllImport("MIDIIO.dll")]
public static extern int MIDIOut_Reset(IntPtr pMIDIOut);
//MIDIメッセージをひとつ送信し、実際に送信したMIDIメッセージのバイト数を返す。
[DllImport("MIDIIO.dll")]
public static extern int MIDIOut_PutMIDIMessage(IntPtr pMIDIOut, IntPtr pMessage, int lLen);
}
これで.netでおーぷんMIDIぷろじぇくとのMIDIIOライブラリを使う準備が整いました。
「MIDIIOLib1.2」→「docs」内にある「MIDIIO.html」(MIDIIOライブラリ公式ガイドブック)とほぼ同じ使い方ができます。
上記コードではMIDIIOライブラリ内のすべての関数を記述していません。使いたい関数がある場合は個別に追加してください。
・MIDI IN コード例
コンソールにインストールされているMIDI入力デバイスの数を表示
//インストールされているMIDI入力デバイスの数を表示
Console.WriteLine("MIDIIn_GetDeviceNum:"+Open_midi_project.MIDIIn_GetDeviceNum());
デバイスID "num" のMIDI入力デバイスの名前を表示
//デバイスID "num" のMIDI入力デバイスの名前を表示
IntPtr openmidi_in_dev_name = new IntPtr();
openmidi_in_dev_name = Marshal.AllocHGlobal(32); //32バイトのメモリ確保
Open_midi_project.MIDIIn_GetDeviceName(num, openmidi_in_dev_name, 32);
Console.WriteLine("DeviceName:" + Marshal.PtrToStringAnsi(openmidi_in_dev_name));
Marshal.FreeHGlobal(openmidi_in_dev_name); //メモリ解放
コンボボックス"midi_in_comboBox"にmidi入力デバイスを列挙する
※フォーム内にmidi_in_comboBoxが必要です。
//コンボボックス"midi_in_comboBox"にmidi入力デバイスを列挙する
midi_in_comboBox.Items.Clear();
midi_in_comboBox.Items.Add("選択してください");
for (int openmidi_device_id=0;openmidi_device_id< Open_midi_project.MIDIIn_GetDeviceNum(); openmidi_device_id++)
{
IntPtr openmidi_in_dev_name = new IntPtr();
openmidi_in_dev_name = Marshal.AllocHGlobal(32); //32バイトのメモリ確保
Open_midi_project.MIDIIn_GetDeviceName(openmidi_device_id, openmidi_in_dev_name, 32);
midi_in_comboBox.Items.Add(Marshal.PtrToStringAnsi(openmidi_in_dev_name));
Marshal.FreeHGlobal(openmidi_in_dev_name); //メモリ解放
}
コンボボックス"midi_in_comboBox.Text"のMIDI入力ポートを開くor閉じる
//コンボボックス"midi_in_comboBox.Text"のMIDI入力ポートを開くor閉じる
IntPtr openmidi_in_hd = new IntPtr();
openmidi_in_hd = Open_midi_project.MIDIIn_Open(midi_in_comboBox.Text);//開く
Open_midi_project.MIDIIn_Close(openmidi_in_hd);//閉じる
MIDIメッセージ受け取り(逐次読み出しが必要)
//MIDIメッセージ受け取り
IntPtr openmidi_rx_buf = new IntPtr();
byte[] openmidi_in_data = new byte[256];
int openmidi_rx_buf_size = Open_midi_project.MIDIIn_GetMIDIMessage(openmidi_in_hd, openmidi_rx_buf,256);//受信バッファに溜まっているバイト数取得
Marshal.Copy(openmidi_rx_buf, openmidi_in_data, 0, openmidi_rx_buf_size);
//openmidi_in_data配列に受信データが格納される
・MIDI OUT コード例
コンソールにインストールされているMIDI出力デバイスの数を表示
//インストールされているMIDI出力デバイスの数を表示
Console.WriteLine("MIDIOut_GetDeviceNum:" + Open_midi_project.MIDIOut_GetDeviceNum());
デバイスID "num" のMIDI出力デバイスの名前を表示
//デバイスID "num" のMIDI出力デバイスの名前を表示
IntPtr openmidi_out_dev_name = new IntPtr();
openmidi_out_dev_name = Marshal.AllocHGlobal(32); //32バイトのメモリ確保
Open_midi_project.MIDIOut_GetDeviceName(num, openmidi_out_dev_name, 32);
Console.WriteLine("DeviceName:" + Marshal.PtrToStringAnsi(openmidi_out_dev_name));
Marshal.FreeHGlobal(openmidi_out_dev_name); //メモリ解放
コンボボックス"midi_out_comboBox"にmidi出力デバイスを列挙する
※フォーム内にmidi_out_comboBoxが必要です。
//コンボボックス"midi_out_comboBox"にmidi出力デバイスを列挙する
midi_out_comboBox.Items.Clear();
midi_out_comboBox.Items.Add("選択してください");
for (int openmidi_device_id=0;openmidi_device_id< Open_midi_project.MIDIOut_GetDeviceNum(); openmidi_device_id++)
{
IntPtr openmidi_out_dev_name = new IntPtr();
openmidi_out_dev_name = Marshal.AllocHGlobal(32); //32バイトのメモリ確保
Open_midi_project.MIDIOut_GetDeviceName(openmidi_device_id, openmidi_out_dev_name, 32);
midi_out_comboBox.Items.Add(Marshal.PtrToStringAnsi(openmidi_out_dev_name));
Marshal.FreeHGlobal(openmidi_out_dev_name); //メモリ解放
}
コンボボックス"midi_out_comboBox.Text"のMIDI出力ポートを開くor閉じる
//コンボボックス"midi_out_comboBox.Text"のMIDI出力ポートを開くor閉じる
IntPtr openmidi_out_hd = new IntPtr();
openmidi_out_hd = Open_midi_project.MIDIOut_Open(midi_out_comboBox.Text);//開く
Open_midi_project.MIDIOut_Close(openmidi_out_hd);//閉じる
MIDIメッセージ送信
//MIDIメッセージ送信
IntPtr openmidi_tx_buf = new IntPtr();
byte[] openmidi_out_data = new byte[256];
int byte_size_midi = 3;//送信するデータサイズ
byte[0]=0x90;
byte[1]=0x64;
byte[2]=0x7F;//ch1,vel:127,note:100ノートオン
Marshal.Copy(openmidi_out_data, 0, openmidi_tx_buf, byte_size_midi);
Open_midi_project.MIDIOut_PutMIDIMessage(openmidi_out_hd, openmidi_tx_buf, byte_size_midi);
//openmidi_out_data配列のデータ送信される
各関数の使い方はこんな感じです。
0 件のコメント:
コメントを投稿