blog.monophile.net

コンピュータに関するメモ。

著者

山本一彰(Takaaki Yamamoto)

東京工業大学において計算機科学と応用数学を学び、 情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 2015年にコンビネータ論理を基に計算完備な計算手法 "論理珠算"を開発し、 それを含む体系である"算道"を構成した。 その成果により、2016年に 第19回 文化庁メディア芸術祭 アート部門 新人賞 (文部科学大臣賞) を受賞。 現在はSRE(サイト信頼性エンジニア)として生計をたててている。

投稿

SuperCollider で OSC のメッセージ通信

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

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

addOSCRecvFunc / removeOSCRecvFunc

Main クラスのインスタンスメソッドである addOSCRecvFuncremoveOSCRecvFunc の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 という引数を取るような関数であることと、 その関数 fthisProcess.addOSCRecvFunc で登録するということだけですね。

ここで msgsclang: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 など)の特殊さにちょっと苦しみながら、今回の実験用のコード書いてました。 一応動きますが、作法的に合っているのかどうかはわからないですね。