2011年11月3日木曜日

node.jsとMIDI信号でHTMLをいじる

準備

node.jsでMIDIを拾うには、node-midiを使います。RtMidiというOSごとの差異をうめるライブラリを呼び出しているので、MacでもLinuxでも、もちろんWindowsでも大丈夫なようす。npmにはもうひとつPure JSでMIDIを扱えるものがありますが、こっちはサンプルを見たところLinux依存のようです。


MIDI信号をひろう

とりあえずサンプルのとおりに。

var midi = require('midi');
var input = new midi.input();

// MIDI INの信号を拾ったら実行する
input.on('message', function(deltaTime, message) {
  console.log('m:' + message + ' d:' + deltaTime);
}); 

// ポートを読み始める
input.openPort(0);

実行結果は以下の動画で。引数にファイル名を指定していないのは、どういうわけか実行ができなかったから。ノブをぐりぐりしたりキーを叩いたりすると、ターミナルに表示されているのがわかりますね。



HTMLに送る

node.jsでつかまえられるということはあれこれいじれますな。せっかくシンセサイザーにノブが3本ついているので、それぞれをRGBとしてSocket.IOでHTMLの背景色をいじってみます。コードはgithubに。


コードのなかでは何をやっているのか。MIDI信号を拾ってからの処理のうち、前半はこのシンセサイザーのための処理をやっています。XYZ3個のつまみがついているのですが、つまみを回した瞬間に「どのつまみを回した」という名刺がわりの信号がとび、そのあとに回し具合の信号がずらずらつづきます。回し具合の信号は3つのつまみで共通なので、「いまどのつまみを回したのか」を正しく知るための処理ということになります。

後半は、つまみの回し具合をカラーコードの文字列に変換しているところです。ここもハードウェアの縛りがあって、Xだけが127(実際はもっと大きい)、それ以外は100が最大値という仕様らしいので、それを255(0xFF)が最大になるように計算しています。この計算だと#FFFFFFにはできないんですけど、そこは手をぬきました。

最後にio.sockets.emit()で、Socket.IO経由でつながっているHTMLにカラーコードを送ります。HTML側では、受け取ったカラーコードをそのまま背景色につっこんでいるだけですね。