blog.monophile.net

Takaaki Yamamoto

東京工業大学において計算機科学と応用数学を学び、情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 現在は digitiminimi Inc. において、インフラエンジニアとして生計をたててている。 また、計算を主題に制作を行い、現代音楽作品や公共インスタレーション作品など技術提供を行う。 三輪眞弘に師事する。

List

SuperColliderでOSC

SuperColliderはクライアント側sclangとサーバ側scsynthがお互いにOSCを利用して通信しています。 しかし、sclangもscsynthもまた違うOSCクライアントからのメッセージを受け付けることができます。 当たり前っちゃ当たり前ですが。

しかし、scsynthよりもsclangの方がメッセージに対して柔軟な対応ができます。 なので、sclangの方でOSCのメッセージを受け取ることを考えてみます。

addOSCRecvFunc / removeOSCRecvFunc

MainクラスのインスタンスメソッドであるaddOSCRecvFunc/removeOSCRecvFuncという2つを理解すればOKです。 以下のメッセージを叩き、ドキュメントを読んでみましょう。

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(f)というので登録するということだけですね。

ここで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(smalltalk系)の言語は初めてなので、 if,switch,forなどの制御構文の特殊さにちょっと苦しみながら、今回の実験用のコード書いてました。 一応動きますが、作法的に合っているのかどうかはわからないですね。