最近VJ的なパフォーマンス用ソフトを作ったりしていたのですが、その過程でMIDIコントローラを使いたいと思い、評判が良くて、手ごろな値段のKorg nanoKONTROL2を購入しました。
ジャバは標準でMIDIが扱えますが、MIDIコントローラを扱う情報が少なく、見つけづらかったのでメモしておきます。
ジャバのMIDI関連に関しては以下のブログエントリが詳しいです。
http://blog.bonar.jp/entry/20090322/1237711377
このエントリでは自作Receiverを定義して、MIDIキーボードから受け取ったMIDIの演奏情報にフィルターをかけるようなことをしているみたいですね。
このサイトだけで大体は分かったのですが、コントローラにReceiverを登録する際にひっかかりました。僕の環境では以下のような機器が検出されていたのですが、僕は最初、External MIDI Portの方に接続しようとして失敗していました。nanoKONTROL2が二つ検出されているのがよくわかりませんが、External MIDI Portの方にはReceiverを登録できないみたいですね。
Gervill -- Software MIDI Synthesizer nanoKONTROL2 -- No details available Microsoft MIDI Mapper -- Windows MIDI_MAPPER Microsoft GS Wavetable Synth -- Internal software synthesizer nanoKONTROL2 -- External MIDI Port Real Time Sequencer -- Software sequencer
とりあえず以下のstackoverflowの回答のコードを使えば検出され、使用できるMIDI機器全てにレシーバーを追加することができます。
http://stackoverflow.com/questions/6937760/java-getting-input-from-midi-keyboard
検出されたMIDI信号はReceiverのsend関数で処理されます。僕はとりあえず以下のような関数を用意しました
public void send(MidiMessage message, long timeStamp) { if (message instanceof ShortMessage) { ShortMessage sm = ((ShortMessage)message); switch(sm.getCommand()) { case ShortMessage.CONTROL_CHANGE: System.out.println(sm.getChannel()); System.out.println(sm.getData1()); System.out.println(sm.getData2()); break; case ShortMessage.NOTE_ON: System.out.println("note on"); break; default: System.out.println("default"); break; } } System.out.println("midi received"); }
ShortMessageは信号の種類ですが、MIDIコントローラでは全てCONTROL_CHANGEになるみたいです。getData1でMIDIコントローラにおけるつまみやボタンのid、getData2でコントローラの0から127までの値が取得できます。
ちなみにボタンは押されたときに127、指が離されたときに0が返るようになっています。
残念なことにidからはどれがつまみでどれがスライダーかはわからないので自分で調べる
必要があるみたいですね。
nanoKONTROL2に関しては自分で調べて以下のようなEnumを定義しておきました。
このIDをキーにして処理を呼び出すようにすればよいのではないでしょうか。
public interface MidiController { public int getId(); } public enum KorgNanoControl2 implements MidiController{ SLIDER1(0), SLIDER2(1), SLIDER3(2), SLIDER4(3), SLIDER5(4), SLIDER6(5), SLIDER7(6), SLIDER8(7), KNOB1(16), KNOB2(17), KNOB3(18), KNOB4(19), KNOB5(20), KNOB6(21), KNOB7(22), KNOB8(23), BUTTON_S1(32), BUTTON_S2(33), BUTTON_S3(34), BUTTON_S4(35), BUTTON_S5(36), BUTTON_S6(37), BUTTON_S7(38), BUTTON_S8(39), BUTTON_M1(48), BUTTON_M2(49), BUTTON_M3(50), BUTTON_M4(51), BUTTON_M5(52), BUTTON_M6(53), BUTTON_M7(54), BUTTON_M8(55), BUTTON_R1(64), BUTTON_R2(65), BUTTON_R3(66), BUTTON_R4(67), BUTTON_R5(68), BUTTON_R6(69), BUTTON_R7(70), BUTTON_R8(71), BUTTON_PREV_TRACK(58), BUTTON_NEXT_TRACK(59), BUTTON_CYCLE(46), BUTTON_MARKER_SET(60), BUTTON_MARKER_PREV(61), BUTTON_MARKER_NEXT(62), BUTTON_BACKWARD(43), BUTTON_FORWARD(44),BUTTON_STOP(42), BUTTON_START(41), BUTTON_REC(45); private final int id; private KorgNanoControl2(final int id){ this.id = id; } @Override public int getId(){ return id; } }
実際に操作に使用してみると、結構便利で面白いです。しかし、描画するもののパラメータに0から127までの値をうまく対応付ける事が難しいですね。