DataRacketというソフトウェアがあります。これは音声データをリアルタイムに解析し、各種データをOSC(Open Sound Control)プロトコルで送信してくれるという優れものです。このソフトを使うことで簡単に音に反応するようなプログラムが作れます。
さて、ジャバでOSCを扱うライブラリにJavaOSCが存在します。このライブラリを使用すればジャバで簡単にOSCを扱うことができます。
サンプルコードが見つかりにくかったので使用法と共にメモしておきます。
受信
受信は以下のようなコードでできます。当然ですが終了時にreceiverをcloseするのを忘れるとreceiverが残り続けるので注意してください
OSCPortIn receiver = null; try { //9000番ポートで受信 receiver = new OSCPortIn(9000); } catch (SocketException e2) { e2.printStackTrace(); } OSCListener loudListener = new OSCListener() { public void acceptMessage(Date time, OSCMessage message) { System.out.println("loud received!"); System.out.println(message.getAddress()); for(Object ob : message.getArguments()){ System.out.println((float) ob); } } }; OSCListener fftListener = new OSCListener() { public void acceptMessage(Date time, OSCMessage message) { System.out.println("FFT received!"); System.out.println(message.getAddress()); for(Object ob : message.getArguments()){ System.out.println((float) ob); } } }; receiver.addListener("/audio/loud", loudListener); receiver.addListener("/audio/fft", fftListener); receiver.startListening();
リスナーを定義し、receiverに加えるだけですね。addListenerの第一引数はデータに指定されているアドレスです。今回はDataRacketからloudとfftを取得しています。message.getArguments()には受け取ったデータが詰まっています。loudに入っている値は一つですがfftには複数の値が入っています。また、DataRacketから送信される値はfloat型なので取得時にキャストしてやります。
送信
あまり使わないかもしれませんが送信も。
OSCPortOut sender = null; try { //ローカルホスト、9001番ポートへ送信 sender = new OSCPortOut(InetAddress.getLocalHost(), 9001); } catch(Exception ex){ ex.printStackTrace(); } Object args[] = new Object[1]; args[0] = "hello"; OSCMessage msg = new OSCMessage("/sayhello", args); try { sender.send(msg); } catch (Exception e) { e.printStackTrace(); } sender.close();
"/sayhello"アドレスに"hello"というメッセージを送っています。
Midi2OSC
JavaOSCを使用してMIDIメッセージをOSCに変換して送信するプログラムを作成しました。
soma-arc/Midi2OSC · GitHub
見た目からして酷いですし人様に使ってもらうようなものではないのですが、Common LispでMIDIコントローラを使用するために作成しました。Common LispでMIDIファイルを扱うライブラリは見つけられたのですが、MIDIポートに接続してコントローラからの値をリアルタイムに取得するようなライブラリは見つからなかったので、ジャバで受け取ってOSCで送信してしまうことにしました。ジャバならポータブルになるでしょうしね。
使用すると/midi/midiチャンネル/コントロールidというアドレスに対してコントローラの値が送信されます。あとはCommon Lisp側でcl-osc、usocketを用いてoscの受信、デコードをするだけです。これは次の記事になるかと。