MIDI入力をキー入力に変換し、ペイントソフトのブラシサイズ変更を行ってみた例

# 概要
ペイントソフトで絵の練習をしている最中
ブラシサイズをプルダウンメニューで選んでいたが
そのときにブラシサイズを素早く変えたいなと思ったことがはじまり

使っていないMIDI機器を左手入力デバイスの代わりに使えるようにしたいと思って、
プログラムの作成に取り掛かった

結果、2つのプログラムを作成
MIDI入力部はMax/MSPを使用し、キー入力変換部は.NETを使用した

動作確認も行った

最後に、既にこういうソフトはあるのかもしれないなと思った
また、さっきできたばかりで、はこれから使っていくので活用できるかは分からない
発見や進展があったらまた続きを投稿したいと思う

# ブラシサイズを素早く変える方法
## これまでのやりかた
調べた中では下記のようなやりかたがあった
- キーボードショートカット : ']'と'['を使う
- 左手(利き手の反対)入力デバイスを使う : ゲーミング用のキーボードがその一例
- テンキーを使う : 比較的安価に入手できるテンキーを左手入力デバイスの代わりに使う

## 今回やってみたやりかた
今回思いついてやってみたやりかたは
- スライダーやつまみ（ボリューム）を備えたMIDI機器を使う
こと。

詳細：
1. MIDI機器からパソコンにControl ChangeのMIDI信号を入力
2. Control Changeの値の変化を監視
3. 変化が一定より大きい場合、キー入力']'(または'[')に変換する

MIDI入力部は今回は別の機会に購入済みだったMax/MSPを使用

キー入力変換部は.NETで簡単に実装できることが分かった
Max/MSPでのやり方は分からなかった

MIDI入力部とキー入力変換部のプログラムが分かれてしまうので
プロセス間通信が必要

Max/MSPでUDPの送信ができるため、UDPを使用することにした
Max/MSPでの他のやり方はわからなかった

# 作成
## Max/MSPでのMIDI入力部の作成
### 構成
1. ctlin : 右から「チャンネル」「Control Change番号」「値」を取得
2. gateと == 1 : 「チャンネル」のフィルタリング
3. gateと == 11 : 「Control Change番号」のフィルタリング
4. 赤・黄・青のLED :　それぞれ「MIDI入力の通知」「チャンネルが一致した通知」「UDP送信する通知」を示す
5. udpsend : 指定アドレス・ポート番号へUDP送信

### ソースコード(Max/MSP)
![image](https://qiita-image-store.s3.amazonaws.com/0/173331/fc669ab8-470a-05d4-2b98-d2f178e48175.png)

## .NETでのキー入力変換部の作成
### 使用言語
 -C#
※.NETのキー入力変換を使いたいだけなのでC#の必要はないが、Visual Basicを使ったことがないのでC#にした。

### 構成
1. delegate void SendKeysDelegate(string) : デリゲート
2. Send(string) : キー入力関数
3. backgroundWorker1_DoWork(object, DoWorkEventArgs) : バックグラウンド処理関数
4. 起動時の処理

### ソースコード(C# - Windowsフォームアプリケーション)
```csharp:Form1.cs
delegate void SendKeysDelegate(string a);

void Send(string a)
{
    SendKeys.Send(a);
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    IPAddress localAdr = IPAddress.Parse("127.0.0.1");
    IPEndPoint localEP = new IPEndPoint(localAdr, 50000);
    UdpClient udpClient1 = new UdpClient(localEP);
    int last_value = 0;
    IPEndPoint remoteEP = null;
    byte[] rcvBytes = udpClient1.Receive(ref remoteEP);
    last_value = rcvBytes.Last() / 8;

    for (;;)
    {
        rcvBytes = udpClient1.Receive(ref remoteEP);
        int diff = rcvBytes.Last() / 8 - last_value;
        if (diff != 0)
        {
            if (diff < 0)
            {
                //ブラシサイズを小さくする
                Invoke(new SendKeysDelegate(Send), new string('[', -diff));
                //Console.WriteLine(new string('[', -diff));
            }
            else
            {
                //ブラシサイズを大きくする
                Invoke(new SendKeysDelegate(Send), new string(']', diff));
                //Console.WriteLine(new string(']', diff));
            }
            last_value += diff;
        }
    }
}

//..(省略)..
// 起動時の処理
backgroundWorker1.RunWorkerAsync()
//..(省略)..
```
# 動作確認

## Max/MSP Runtimeでの事前確認
1. メニューバーより「Options」＞「MIDI Setup」を選択
2. "Type"の欄に"input"が表示されていることを確認
3. 作成したプロジェクトを開く
4. MIDI機器から入力すると、作成したプログラムの赤・黄・青のLEDが全て点滅する

## アプリケーションでの確認
### notepadでの確認
1. Max/MSPのプログラムが起動した状態で、キー入力変換部のプログラムも起動する
2. notepadを起動し、notepadの画面をアクティブにする
3. MIDI機器から入力すると、notepadにキー入力される

![image](https://qiita-image-store.s3.amazonaws.com/0/173331/84c7e401-8a1e-86e1-abbd-352f007f9770.png)


### ペイントソフトでの確認
色んな太さの線が描けました

![image](https://qiita-image-store.s3.amazonaws.com/0/173331/421a6d84-476f-2737-3219-f7c35bdd630a.png)

作ってみて、既にこういうソフトはあるのかもしれないなと思った
また、さっきできたばかりで、はこれから使っていくので活用できるかは分からない
発見や進展があったらまた続きを投稿したいと思う

# Misc.
 各種バージョン
 Max/MSP : 6.0.8
 Visual Studio : Version 14