Data Racket | Ethno Tekhを使用すれば解析された音声データをOSC(Open Sound Control)で簡単に受け取ることができます。



Common Lispにはcl-oscというOSCをデコードするライブラリがあります。OSC自体はUDPのプロトコルなので、UDP通信するためのコードを書かなくてはなりません。cl-oscのサンプルではsbclに依存したコードが載っています。僕が使っていた処理系はClozureCLなので、処理系ポータブルな通信ライブラリusocketを使用してOSCを受信するコードを紹介します。

usocketを用いてUDP通信を行うサンプルコードを書いている方がいたので、参考にさせてもらいました。

Short guide to UDP/IP Client/Server programming in Common Lisp using usockets · GitHub

OSCを受信するサンプル

( ql:quickload '( :usocket :osc )) ( defparameter *port* 9000 ) ( defun create-server ( port ) ( usocket:socket-connect nil nil :protocol :datagram :element-type '( unsigned-byte 8 ) :local-host "127.0.0.1" :local-port port )) ( defparameter *osc-sock* ( create-server *port* )) ( defun start-receiving ( socket buffer ) ( format t "start server~%" ) ( unwind-protect ( multiple-value-bind ( buffer size client received-port ) ( loop do ( usocket:socket-receive socket buffer 1024 ) ( let (( message ( osc:decode-bundle buffer ))) ( format t "received -=>~S~%" ( osc:decode-bundle buffer )) ( if ( string= ( car message ) "stop" ) ( return ))))) ( usocket:socket-close socket ) ( format t "exit~%" ))) ( start-receiving *osc-sock* ( make-array 1024 :element-type '( unsigned-byte 8 )))

起動して、DataRacketからOSCが入ってくると以下のように出力されます。

received -=> ( "/audio/bright" 0.017748356 ) received -=> ( "/audio/noise" 0.32115465 ) received -=> ( "/audio/loud" 0.43585107 ) received -=> ( "/audio/fft" 0.31239712 0.270671 0.5963343 0.5104574 0.4887981 0.5261438 0.55091 0.21614692 0.20689762 0.17976543 0.08880567 0.13944802 0.124899484 0.12268175 0.13263442 3.1389509E-4 0.045346215 0.031639766 0.014442262 0.008829511 0.025995951 0.012009757 0.0 0.0 0.0 )

cl-oscの仕事はdecode-bundleでデコードすることのみです。

気になるのが終了時の処理ですね。外側から

( usocket:socket-close *osc-sock* )

を呼び出してやるとエラーが発生してしまいます。以下のようにサーバーを止めるクライアントを作成し、stopメッセージを送る関数を作成してみました。