外部との連携(OpenSound Control:OSC)

OSCを使って、様々なアプリケーションの間で通信、連携することができる。
対応ライブラリの一覧 http://opensoundcontrol.org/implementations
対応アプリケーションは多岐に亘るが、今回はpdとSuperCollider(sc)との連携例を考える。


pdでは拡張オブジェクトを用いてOSCメッセージを扱うことができる。
pd-extendedでは拡張オブジェクトをそのまま使うことができる。
OSCに関するオブジェクトは、sendOSC、dumpOSC、OSCrouteの3種。


始めにpdからscへの送信、


SuperCollider側(予め実行しておく)

OSCresponder(nil, '/boo', { |t,r,msg|
msg.postln;
s.sendMsg(\s_new, "boo", -1, 0, 0, \freq, msg[1], \amp, msg[2]);
}).add;

SynthDef("boo", {|freq=1000,amp=1|
var
a = EnvGen.ar(Env.perc(0,1),doneAction:2);
b = SinOsc.ar(freq,0,a*amp);
Out.ar(0,b!2);
}).load(s);


pd側

#N canvas 0 0 852 623 12; #X obj 49 287 sendOSC; #X msg 152 245 disconnect; #X msg 49 37 connect localhost 57120; #X msg 133 204 send /boo \$1 \$2; #X msg 133 86 100; #X msg 144 120 800; #X msg 200 86 1; #X msg 211 120 0.5; #X obj 133 165 pack f 0.5; #X obj 48 548 sendOSC; #X msg 106 506 disconnect; #X msg 85 415 send /s_new boo -1 0 0 freq 300 amp 0.7; #X msg 48 362 connect localhost 57110; #X msg 86 453 send /s_new boo -1 0 0 freq 350 amp 0.2; #X text 243 36 <-- to SCLang; #X text 236 361 <-- to SCSynth; #X obj 528 120 dumpOSC 8000; #X msg 512 307 1 \, 0 1000; #X obj 512 354 line~; #X obj 441 307 osc~; #X obj 442 354 *~; #X obj 443 398 *~; #X obj 559 450 dac~; #X obj 528 192 OSCroute /moo /noo; #X obj 460 192 print; #X obj 441 263 unpack f f; #X msg 730 307 1 \, 0 1000; #X obj 730 354 line~; #X obj 659 307 osc~; #X obj 660 354 *~; #X obj 661 398 *~; #X obj 659 263 unpack f f; #X text 641 120 <-- from SC; #X connect 1 0 0 0; #X connect 2 0 0 0; #X connect 3 0 0 0; #X connect 4 0 8 0; #X connect 5 0 8 0; #X connect 6 0 8 1; #X connect 7 0 8 1; #X connect 8 0 3 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 12 0 9 0; #X connect 13 0 9 0; #X connect 16 0 24 0; #X connect 16 0 23 0; #X connect 17 0 18 0; #X connect 18 0 21 1; #X connect 19 0 20 0; #X connect 20 0 21 0; #X connect 21 0 22 0; #X connect 23 0 25 0; #X connect 23 1 31 0; #X connect 25 0 19 0; #X connect 25 0 17 0; #X connect 25 1 20 1; #X connect 26 0 27 0; #X connect 27 0 30 1; #X connect 28 0 29 0; #X connect 29 0 30 0; #X connect 30 0 22 1; #X connect 31 0 28 0; #X connect 31 0 26 0; #X connect 31 1 29 1;


sendOSCオブジェクトは、pdからOSCを送信する。
「connect localhost 57120」をクリックしてSCLangに接続する。
(SCLangのポート番号は通常57120)


次にpackの上の「100」「800」をクリックするとscから音が出る。
また「1」「0.5」で音量が変わる。
「send /boo $1 $2」のsend以降がOSCメッセージの内容になる。
sc側のsynthにOSCメッセージとして周波数と音量を送っている。


送られたOSCメッセージはscのコンソールに表示される。
sc側はOSCresponderでメッセージを受信している。
msg[n]で値を取り出している。受けた値を用いてs.sendMsgでSCSynthにメッセージを送信。


「disconnect」をクリックして接続を解除する。


scの場合、SCSynthで直接メッセージを受けることもできる。
(SCLangとSCSynthとの通信にもOSCが使われている)
「connect localhost 57110」をクリックしてSCSynthに接続する。
(SCSynthのポート番号は通常57110)
メッセージの書式はscのコマンドに合わせる必要がある。


次にscからpdへの送信。scで以下を実行する。

~pd = NetAddr("localhost", 8000);

OSCresponder(nil, '/foo', { |t,r,msg|
msg.postln;
~pd.sendMsg("/moo",msg[3],msg[5]);
~pd.sendMsg("/noo",msg[4],msg[5]);
}).add;

SynthDef("foo", {
var
a = Impulse.kr(1);
b = { Latch.kr(LFNoise0.kr(1,300,400),a) };
c = Latch.kr(LFNoise0.kr(1),a);
SendReply.kr(a,'/foo',[b.(),b.(),c]);
}).play;

dumpOSCオブジェクトでOSCメッセージを受信する。引数はpdのポート番号(通常は8000)。
OSCrouteオブジェクトでメッセージを振り分けている。
routeと同様に先頭の値で出力先を決定。


sc側では、まずNetAddrで送信先アドレスとポート番号を指定し、sendMsgで送信している。
synthを用いてメッセージを送出するには、まずSendReplyでOSCresponderに値を送り
OSCresponderから外部へ送信する、という2段階になる。