2017年1月28日土曜日

OSXでMIDIキーボードの入力信号を取得する方法(完結編)

前回と前々回の記事の続きです。

簡単におさらいしておくと、
・前々回:MIKMIDIを使えば実現できそうだと理解。
・前回:MIKMIDIを使ってnanoKEY2のデバイス情報が取れることを確認。
という感じで、今回はMIKMIDIを使って、nanoKEY2の入力信号をハンドリングする方法の解説です。

先に回答を書くと、以下のような感じで実装すれば、「★ココで捕捉」の箇所で入力信号を捕捉できます。

    MIKMIDIDeviceManager* dm = [MIKMIDIDeviceManager sharedDeviceManager];
    NSArray<MIKMIDIDevice*>* devices = [dm availableDevices];
    for (MIKMIDIDevice* device in devices) {
        NSArray<MIKMIDIEntity*>* entities = device.entities;
        for (MIKMIDIEntity* entity in entities) {
            NSArray<MIKMIDISourceEndpoint*>* sources = entity.sources;
            for (MIKMIDISourceEndpoint* source in sources) {
                NSLog(@"source: %@", source);
                [dm connectInput:source error:nil eventHandler:^(MIKMIDISourceEndpoint * _Nonnull source, NSArray<MIKMIDICommand *> * _Nonnull commands) {
                    // ★ココで捕捉
                    NSLog(@"detected commands: %@", commands);
                }];
            }
        }
    }

以降は、上記の実装をザックリと解説するだけなので、コードだけ見れば分かる人は読まなくても、もう自分のプログラムでMIDIキーボードを入力機器として使うことができますね。

まず、MIKMIDIDeviceManageravailableDevicesで接続されているデバイスの一覧を取得します。
デバイスの実体(MIKMIDIDeviceMIKMIDIEntity)には、
・source endpoint
・destination endpoint
という2種類の情報があり、入力信号を捕捉するにはsource endpointの方を使います。

入力信号の捕捉は、MIKMIDIDeviceManagerconnectInputで対象のsource endpointを指定してあげれば、入力信号が発生した時にeventHandlerがコールバックされるという感じです。

簡単ですね。

で、このプログラムを動作させた状態で、nanoKEY2の「ド」のキーを押してみると、押したタイミングで、XCodeのconsoleに

2017-01-28 18:41:57.014351 VGSKeyboard[36587:9378038] detected commands: (
    "<MIKMIDINoteOnCommand: 0x600000024aa0> time: 18:41:57.013 command: 159 channel 0 note: 48 velocity: 118 \n\tdata: <903076>")

という感じのMIDIイベント(MIKMIDICommand)が発生します。
そして、キーを離してみると、

VGSKeyboard[36587:9378038] detected commands: (
    "<MIKMIDINoteOffCommand: 0x608000029860> time: 18:41:57.549 command: 143 channel 0 note: 48 velocity: 64 \n\tdata: <803040>")

というMIKMIDICommandが発生しました。

つまり、キーボードのキーを押すとcommand 159が発生して、離すとcommand 143が発生するという感じでしょうか。そして、noteで対象の音階が分かるという感じです。

いやー、簡単ですね。このMIKMIDIというライブラリはCore MIDIというframeworkを使っているのですが、直にCore MIDIを叩くよりは大分楽な感じではないでしょうか。

しかも、OSXだけでなくiOSにも対応しているので、入力機器としてブルートゥースMIDIキーボードを使うiPhoneアプリなんかも作れてしまうのではないでしょうか。(今回はスマホ関連のことは未調査ですが)