SuperCollider のログ
SuperCollider のサーバは OSC メッセージを受け取って動作する。
OSC通信のログを取るコマンドがあるようだ。
Server Architecture | SuperCollider 3.10.0 Help
scscynth -u 57117 >synth_log &
Accept commands via UDP on port 57117.
Send output to file "synth_log"
Run asynchronously: &.
Server Command Reference | SuperCollider 3.10.0 Help
/dumpOSC
Display incoming OSC messages.
int | code |
Turns on and off printing of the contents of incoming Open Sound Control messages. This is useful when debugging your command stream.
The values for the code are as follows:
0 | turn dumping OFF. |
1 | print the parsed contents of the message. |
2 | print the contents in hexadecimal. |
3 | print both the parsed and hexadecimal representations of the contents. |
SonicPiが内蔵している SuperCollider に対し、ログを取るように設定できたら、SonicPiのサーバに対して OSCメッセージを投げ、SonicPiのサーバがSuperColliderのサーバにどんな OSCメッセージを投げているのか確認できる。
そうすれば、SonicPiのサーバを介さずにアプリケーションから直接 SuperCollider のサーバにOSCメッセージを投げることができるようになる。そうすると更に応答性が良くなるはず。
SuperCollider の サーバが受け取るコマンド
Sonic Pi で利用されている SuperCollider のサーバについて、コマンド一覧を発見した。
このコマンドを OSC なメッセージとして、クライアントプログラムから送信すればよいはず。ruby な Sonic Pi のサーバを介さずに SuperCollider のサーバに送信することによって、応答速度は上がるのか?
Server Command Reference | SuperCollider 3.10.0 Help
Sonic Pi の場合、内部の SuperCollider のポート番号は 4556 らしい。
sonic-pi/sonic-pi-server.rb at master · samaaron/sonic-pi · GitHub
scsynth_port = ARGV[3] ? ARGV[3].to_i : 4556
scsynth_send_port = ARGV[4] ? ARGV[4].to_i : 4556
oscpack を断念して liblo を使ったら成功!
C/C++で OSC(Open Sound Control) の送受信を行おうとしていた。それは、Sonic Pi をC/C++プログラムから操作するため、C/C++のクライアントプログラムから Sonic Pi のサーバへ OSC メッセージを投げたい。
oscpack の SimpleSend だとなぜだか SonicPi で音が鳴ってくれなかった。
そこで、C/C++で使える OSC のライブラリを探したところ、 liblo を発見。
liblo: Lightweight OSC implementation
liblo を使うと、無事に Sonic Pi と OSC な通信をして音をならすことができた。
system()関数を使うより、キーを押してから音がなるまでのタイムラグをだいぶへらすことができた。
まだすこし時間がかかっている。本来ならばどこで時間がかかっているのか計測するのが先だが、計測の精度も必要。SonicPi のサーバ側のソースを修正して計測するのが厄介。
推測だが、SonicPiサーバの処理が ruby で書かれているので、そこが遅いかもしれない。内部的には SuperCollider をシンセサイザーとして利用しており、SuperCollider のメッセージも受け付けるらしいのでそちらを採用すると早くなる?
oscpack
Sonic Pi のサーバと osc で通信したい。ruby では成功。
require 'osc-ruby'
include OSC client = OSC::Client.new('localhost', 4557)
message = OSC::Message.new('/run-code', 'sonic-pi-cli', 'play :C4') client.send(message);
import time
from pythonosc import osc_message_builder
from pythonosc import udp_client
client = udp_client.SimpleUDPClient("localhost", 4557)
msg = osc_message_builder.OscMessageBuilder(address="/run-code") msg.add_arg("PYTHON")
msg = msg.build()
client.send_message(msg,"play(C4)")
#include "osc/OscOutboundPacketStream.h"
#include "ip/UdpSocket.h"
#define ADDRESS "127.0.0.1"
#define PORT 4557
#define OUTPUT_BUFFER_SIZE 1024
int main(int argc, char* argv[])
{
(void) argc; // suppress unused parameter warnings
(void) argv; // suppress unused parameter warnings
UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );
char buffer[OUTPUT_BUFFER_SIZE];
osc::OutboundPacketStream p( buffer, OUTPUT_BUFFER_SIZE );
p << osc::BeginBundleImmediate
<< osc::BeginMessage( "/run-code" )
<< "sonic-pi-cli" << "play :C4" << osc::EndMessage
<< osc::EndBundle;
transmitSocket.Send( p.Data(), p.Size() );
}
Sonic Pi のサーバ側でOSC通信のログをみて比較したい。