SuperColliderのアーキテクチャ

SuperColliderの全体像について書きます。

SuperColliderとは

SuperColliderは、James McCartneyによって開発されたリアルタイム音響合成・アルゴリズム作曲のための環境です。1996年に発表され、2002年にGPLの下でオープンソース化されました(現在のバージョン系列はSuperCollider 3)。音響合成エンジンとプログラミング言語がクライアント/サーバーとして分離されている点が最大の特徴で、この設計により、ライブコーディングによる即興演奏から、非リアルタイムでの高品質なレンダリング、他言語からのリモート制御まで、幅広い用途に対応できます。

SuperColliderのコンポーネント構成

SuperColliderは3つのコンポーネントから構成されます。

SuperColliderのサーバー/クライアントはOSCプロトコルで通信します。 sclangはOSCメッセージをscsynthに送り、scsynthがそれを解釈して音響を生成します。

音響合成エンジン(scsynth)とその制御言語(sclang)が別プロセスとして独立している点がSuperColliderの設計上の核心です。両者はOSCという言語非依存のプロトコルでしか結びついていないため、sclangの代わりにPythonやHaskell、SuperColliderとは無関係な外部アプリケーションからscsynthを制御することも可能です(後述の「エコシステムと他クライアントとの連携」を参照)。逆に、sclangは音を出さずにscsynthへメッセージを送るだけのクライアントとして振る舞うこともできます。

クライアント/サーバー間通信: OSC

sclangとscsynthは、OSC (Open Sound Control) メッセージをUDP(既定)またはTCPで送受信することで通信します。scsynthはローカルホスト上のプロセスとして起動されるのが一般的ですが、OSCはネットワーク透過なプロトコルなので、原理上は別マシン上のscsynthをリモートから制御することもできます。

scsynth側からsclang側へも、/n_go(ノード生成完了の通知)や/tr(トリガー通知)のようなメッセージが送られます。sclangはこれをOSCFunc/OSCdefで受信し、サーバー内部の状態変化に応じてクライアント側の処理を実行します。

scsynth: 音響合成サーバー

scsynthはC++で実装された、音を生成すること専任のリアルタイムオーディオエンジンです。GUIや言語処理系を一切持たず、OSCメッセージで指示された通りにオーディオグラフを構築・実行するだけの軽量なプロセスとして設計されています。内部状態は主に次の4種類のオブジェクトで構成されます。

ノード(Node): SynthとGroup

scsynthが管理する再生中の処理単位はNodeと呼ばれ、Synth(実際に音響を生成する単位)とGroup(複数のNodeをまとめるコンテナ)の2種類があります。すべてのNodeは木構造(ノードツリー)として管理されており、ルートには常にID 0のGroup(root node)が存在します。

ノードツリー内での並び順は単なる管理上の順序ではなく、実際の音響信号処理の順序を意味します。scsynthはツリーの先頭から末尾へ向かって各Nodeを順に実行するため、たとえばリバーブなどのエフェクトSynthを音源Synthより後ろ(ツリーの末尾側)に置くことで、前段の出力をBus経由で後段が受け取って処理する、という典型的なシグナルチェインが実現できます。/s_newではaddAction引数(addToHead・addToTail・addBefore・addAfter・addReplace)で、生成位置をツリー内のどこにするかを指定します。

バス(Bus)

Busはscsynth内部で信号やコントロール値をやり取りするための名前付きチャンネルで、audio bus(オーディオレート信号用)とcontrol bus(コントロールレート値用)の2種類があります。Synth同士がBusを介して信号を送受信することで、ノードツリーの順序と組み合わせたシグナルルーティングが可能になります。

audio busのうち、先頭のoptions.numOutputBusChannels個は物理出力(スピーカー)に、続くoptions.numInputBusChannels個は物理入力(マイクなど)に直結しています。それ以降のインデックスは内部的な信号受け渡し専用の「プライベートバス」として自由に使えます。

バッファ(Buffer)

Bufferはサンプルデータを保持するためのメモリ領域です。サウンドファイルの読み込み(/ballocRead)、波形テーブルの確保(/balloc)、録音先(/b_writeと組み合わせた録音)、FFT処理の中間データなど、単発の音響イベントを超えて保持しておきたいデータ全般に使われます。Busがリアルタイムのストリームであるのに対し、Bufferはランダムアクセス可能な配列データという位置づけです。

UGen(Unit Generator)

UGenはscsynthにおける最小のDSP処理単位で、正弦波発振器のSinOscやフィルタのLPFなど、個々の演算をC++プラグイン(.scxファイル)として実装したものです。scsynth起動時にプラグインディレクトリから動的に読み込まれるため、標準UGen以外にもサードパーティ製・自作のUGenを追加できます。

UGenにはそれぞれ計算レートがあり、用途に応じて使い分けます。

SynthDef

scサーバーが音響合成をするために、SynthDefクラスでシンセ定義をします。 シンセ定義の構文は次の通りです。

SynthDef.new(\name, {UGens})

定義したSynthDefは.addメソッドでサーバーに送信されます。

SynthDefは、UGenをつなぎ合わせたグラフ(UGenグラフ)を、名前付きの再利用可能な設計図としてコンパイルしたものです。関数内でUGen同士をつなぐと、sclang側でその接続関係が解析され、scsynthが解釈できるバイナリ形式のSynthDefファイルに変換されます。主な特徴は次の通りです。

sclang: プログラミング言語とクラスライブラリ

sclangはSmalltalkの影響を受けたオブジェクト指向言語で、独自のインタプリタ(sclangプロセス)上で動作します。すべての値がオブジェクトであり、クラスライブラリ(標準で用意された.scファイル群)自体もsclangで書かれています。主な役割は次の通りです。

クラスライブラリはユーザーが独自のクラスを追加・拡張することも前提とした設計になっており、コミュニティが開発した拡張ライブラリはQuark(パッケージ)という単位で配布され、Quarksクラスを通じてインストール・管理できます。

scIDEと開発環境

scIDEはQtベースのクロスプラットフォーム統合開発環境で、コードエディタ・ポストウィンドウ(実行結果やログの表示)・ヘルプブラウザなどを1つのアプリケーションにまとめたものです。内部的にはsclangプロセスをサブプロセスとして起動し、エディタ上で選択したコードをsclangへ送って評価する、という形でsclangと連携しています。

scIDEは公式に提供される標準の開発環境ですが、sclang自体はコマンドラインからも起動できるため、Emacs(scel)やVim、Atom/VS Code向けの拡張機能など、サードパーティ製のフロントエンドで開発することも可能です。いずれもscIDEと同様、内部ではsclangプロセスを起動してコードを送信するという同じ仕組みに依っています。

OSCメッセージ

scserverには組み込みのOSCメッセージがあります。 リファレンスはServer Command Reference

代表的なメッセージには次のようなものがあります。