SuperCollider で OSC のメッセージ通信
SuperCollider はクライアント側 sclang とサーバ側 scsynth がお互いに OSC を利用して通信しています。 しかし、sclang も scsynth もまた違う OSC クライアントからのメッセージを受け付けることができます。
しかし、scsynth よりも sclang の方がメッセージに対して柔軟な対応ができます。 したがって、sclang で OSC のメッセージを受け取ってみます。
addOSCRecvFunc / removeOSCRecvFunc
Main
クラスのインスタンスメソッドである addOSCRecvFunc
と removeOSCRecvFunc
の2つを理解できれば良いので、以下のメッセージを叩き、ドキュメントを読んでみましょう。
Main.openHelpFile;
すると addOSCRecvFunc
に以下のようなサンプルコードがあります。
(
f = { |msg, time, replyAddr, recvPort|
if(msg[0] != '/status.reply') {
"At time %s received message % from % on port%\n"
.postf( time, msg, replyAddr, recvPort )
}
};
thisProcess.addOSCRecvFunc(f);
);
重要なのは f
という関数が msg
, time
, replyAddr
, recvPort
という引数を取るような関数であることと、 その関数 f
を thisProcess.addOSCRecvFunc
で登録するということだけですね。
ここで msg
は sclang:57120
に送られてきた OSC のメッセージの内容が入っています。 関数fの2行目にif文がありますが、msg[0]
が /status.reply
っていうのはserverが “生きてるよ” というビーコンを発したときのメッセージらしいです。 したがって、その情報がいらない時はif文を使ってフィルタリングをすればいいみたいですね。
要らなくなった関数 f
の登録を解除する場合は以下のようにすればOK。
thisProcess.removeOSCRecvFunc(f);
OSCのメッセージを受信して音を鳴らしてみる
/Synth/new
というメッセージが来たら音を鳴らし、/Synth/stop
というメッセージならば止める、 ということをやってみみます。
関数の登録
まずはじめにメッセージが来た場合の動作を記述した関数を登録します。
(
f = { |msg, time, replyAddr, recvPort|
if(s.addr != replyAddr,
switch( msg[0],
'/Synth/new', { s.sendMsg("/s_new", msg[1], msg[2]); },
'/Synth/stop', { s.sendMsg("/n_free", msg[1]); }
).value
);
};
thisProcess.addOSCRecvFunc(f);
)
メッセージの送信
次のコードでメッセージを送信してみます。 すると音がなります。
NetAddr.localAddr.sendMsg( "/Synth/new", "default", 9999 );
次のコードでなった音が止まります。
NetAddr.localAddr.sendMsg( "/Synth/stop", 9999 );
メモ
SuperCollider の言語は初めてなので、 制御構文(if,switch,for など)の特殊さにちょっと苦しみながら、今回の実験用のコード書いてました。 一応動きますが、作法的に合っているのかどうかはわからないですね。