VJコントローラを作る記事第2回です。
第1回はこちら。
Novation LauchpadとopenFrameworksを使ってResolumeのVJコントローラを作る: セットアップ編 - アールテクニカ地下ガレージ
さっそく簡易的なコントローラを作っていきます。
今回作るのはResolumeのレイヤーの不透明度をLaunchpadでコントロールするものです。
Launchpadのパッドの縦方向をレイヤー番号、横方向を不透明度とします。
レイヤーの不透明度に合わせてLEDが光り、パッドを押すとレイヤーの不透明度が変化するという操作にします。
図にすると、こういうレイアウトです。
OSCアドレス取得
ResolumeのOSCアドレスの調べ方は、
・ResolumeのApplication OSC Mapで調べる
・Resolume OSCアドレス一覧 - アールテクニカ地下ガレージを参照する
です。
レイヤーの不透明度のアドレスは以下です。
/layer1/video/opacity/values Int
レイヤー番号はアドレスに組み入れられており、レイヤー2は/layer2/video/opacity/values
となります。
このOSCアドレスを送受信することでレイヤーの不透明度を操作できるようになります。
OSCの送受信
ResolumeとのOSCの送受信方法です。
OSCの通信はofxOSCアドオンを使います。
OSC受信
ofxOscReceiverクラスでOSCメッセージを受信します。
setup() でResolumeのOSC出力ポート番号を設定しておきます。
ofxOscReceiver receiver; receiver.setup(PORT);
以下のようにイテレータを回し、OSCメッセージ(ofxOscMessageクラス)の取得ができます。
while (receiver.hasWaitingMessages()) { ofxOscMessage m; receiver.getNextMessage(m); // アドレスを取得 string address = m.getAddress(); // 0番目のInt型の引数の値を取得 int arg = m.getArgAsInt32(0); }
OSC引数の値は型ごとに取得メソッドが違うので、型に合ったメソッドで取得します。
getArgAsInt(index); // Int型の値を取得 getArgAsFloat(index); // Float型の値を取得 getArgAsString(index); // String型の値を取得
取得したいOSCアドレスは文字列マッチで補足します。
正規表現でレイヤー番号も取得可能です。
std::regex re("/layer([0-9]+)/video/opacity/values");
OSC送信
ofxOscSenderクラスで送信します。
ofxOscSender sender; sender.setup("localhost", 7000);
setup()でホスト名・IPとポート番号を設定します。
setAddress()でアドレスを指定し、addFloatArg()で引数の値を設定してsendMessage()でメッセージを送信します。
ofxOscMessage m; m.setAddress("/layer1/video/opacity/values"); m.addFloatArg(0.5); sender.sendMessage(m); m.clear();
引数の値の設定も型ごとにメソッドが用意されています。
addIntArg(int); // Int型の値を追加 addFloatArg(float); // Float型の値を追加 addStringArg(string); // String型の値を追加
MIDI送受信
次はLaunchpadとMIDIの送受信をします。
MIDIの通信はofxMidiアドオンを使います。
MIDI受信
ofxMidiInクラスでの接続は以下のようになります。
ofxMidiIn midiIn; midiIn.listPorts(); midiIn.openPort("Launchpad"); midiIn.addListener(this);
openPort() にポート番号もしくはポート名を指定してLauchpadに接続します。
MIDIデバイスのポート番号とポート名の調べ方は、listPorts() を実行すると、MIDIデバイスのポート番号とポート名がログに出力されるので、それを使います。
addListener() で受信側のオブジェクトをリスナに登録します。
また、midiIn.setVerbose(true) をしておくと、受信したMIDIメッセージがログに出力されるようになります。
MIDIメッセージの受信は、
ofxMidiListenerクラスを継承し、
class ofApp : public ofBaseApp, public ofxMidiListener { ... ofxMidiIn midiIn; void newMidiMessage(ofxMidiMessage& msg); };
newMidiMessageメソッド内で受け取ります。
void ofApp::newMidiMessage(ofxMidiMessage& msg) {
ofxMidiMessage::getStatusString(msg.status)
msg.pitch;
msg.velocity;
msg.channel;
msg.control;
msg.value;
msg.deltatime;
}
ピッチやベロシティなど各種パラメータが受けとれます。
msg.bytesで生のバイトデータを取得することも可能。
msg.deltatime は前のメッセージからの経過時間。
MIDI送信
MIDIメッセージの送信はofxMidiOutクラスを使います。
MIDI受信の時のようにopenPort()でMIDIデバイスに接続します。
ofxMidiOut midiOut; midiOut.openPort(port);
MIDIメッセージの送信はノートオン・オフなどのメッセージが用意されています。
sendMidiByte()で生バイトを送ることも可能。
midiOut.sendNoteOn(channel, pitch, velocity); midiOut.sendNoteOff(channel, pitch, velocity); midiOut.sendProgramChange(channel, value); midiOut.sendControlChange(channel, control, value);
実際にLaunchpadのパッドを押してMIDIメッセージを受信すると、以下のようにノート番号が振られているのが分かります。
これでどのパッドが押されたか判別可能となります。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |
112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
逆にノートオンする信号を送ればパッドのLEDを光らせることができます。
左下のパッドを光らせるには、
sendNoteOn(1, 112, 127);
パッドのLEDを消すには、
sendNoteOn(1, 112, 0);
といった具合です。
これでResolumeの操作とLaunchpadの操作が可能になったので、あとは片方の操作がもう片方に反映されるようにコードを繋いでいって出来上がりです。
という訳で今回のコードはこちら。
Simple VJ Controller: Resolume + Launchpad + openF ...
とべっち
ART Teknika佐賀スタジオマネージャ、プログラマ。WebプログラマからiOSプログラマへ転身。VJとしても活動中。