SonicPi?
SonicPiはSuperColiderという音響合成用エンジンを利用したアプリケーションで、簡単なコードでたのしく音が鳴らせるし、プログラミングの勉強もできる!というツールだ。もともとRaspberry Pi用に作られたもののようだが、Windows版やMacOSX版も用意されている。
SonicPiの何が良いのかというと教育用のものなので、開発環境を起動して簡単なプログラムを書けばそれ単体でいい感じの音が鳴らせるということ。開発環境内にはサンプルもドキュメントもあり、ほとんどそれだけで完結している。プログラム自体の書き方はちょっぴり理解する必要はあるが、だれでも1時間も教育を受けられれば単純な音楽を鳴らせるようになるだろうし、またこれのサンプルをいじることでプログラミングそのものの習得にもつながるだろう。
音楽をプログラムから触ることについては、私は音響関係のプログラムについての本は持っているけど、音楽のプログラミングってのは私のようなアホには難しい。音楽をデジタルな環境でやるというのは数学である。音響関連の本では、アナログの音は連続する波形であり、デジタルの音はそれを量子化したものであり、これこれこういう方法で量子化ができて、そのときの問題はこうで、という話が延々続く。
また鳴らすにしても、wavのフォーマットとか、それをいかにリアルタイムで流し込むかみたいな話があり、音量調節やエフェクトをかける方法はわかるようになってきても、イカすアンビエントな音がみょーんみょーんつって鳴る電子おもちゃを作りたいだけだった私は、サンプルを打ち込んだ時点でもうへとへとである。
レゴでおうちをつくりたい、程度の考えだったのが、「ではまずそのブロックの構成要素であるプラスチックの作り方だが」という話が始まった感じある。しかもこれが数冊読んで一番わかりやすくて、一番実用的な本であっても、まあそれくらいのイメージだ。難しいほうの本なんて「そのプラスチックの化学式ですが」という感じの話が本の大半になる。それが悪いというわけではなく、自分の求める用途にはあっておらず、またその用途に使えるものがこれまでなかなか見つからなかった。
SonicPiはまさにレゴだ。
細かく波形を計算によって変えるなんてことはできないが、「ドをならせ」なんてことはすぐにできるし、ドミソの音をどれかひとつ、0.5から1.0秒の間でランダムに鳴らし続けるなんてことはごく容易にできる。
loop do
play [:C,:E,:G].choose
sleep rrand(0.5,1.0)
end
音にはさまざまな音色、サンプリング音源、エフェクトが揃っていて、それらがループとか、ランダムとか、ちょっとした分岐なんかでプログラムのように書いていくことができる。ドラムをループ、適当な和音をランダムで鳴らす、ランダムな休符、たまたま一定時間空いた場合はジャーンって音を鳴らす、なんていうものがさくさく書くことができる。 大変簡単なので公式サイトのサンプルを起動してみると良い。
プログラムからの利用
そういうわけでSonicPiは大変良い感じなのだけど、そうなるともちろんみんなプログラムから起動できないのか、ということが気になるはずだ。RaspberryPiで動くなら、たとえば今日の湿度や天気とかに合わせた音色を出かけるときに鳴らしてくれる玄関ベルとか、風が吹くとランダムな音を鳴らす電子風鈴とか、自分オリジナルの楽器とかそういうものを作れるってことだからだ。いいニュースとしては、方法はちゃんとあるってことだ。
SonicPiはSuperColiderという音響合成エンジンをコアにもっていて、そこに独自の記法の言語やプリセットなんかを追加するように作られたもので、SuperColiderと同じくOSCという音楽用の通信プロトコルでの通信が可能だ。というかそもそもたぶんGUI側からServer側にOSCで通信しているだけなので、GUIを無視してOSCでサーバーにメッセージを投げれば狙った動作が可能だ。このあたり公式のリファレンスにも、それ以外でも基本的にまとめたものが見当たらないのでコードを読むほかないが、とりあえずnode-oscというライブラリなどを使い、localhostの4557ポートに向けてOSCで通信をするサンプルは以下の様な感じになる。
もちろん先にSonicPiを動作させておく必要はある。
var osc = require('node-osc');
var client = new osc.Client('127.0.0.1', 4557);
//第二引数に開発環境で書いてたのとまったく同じ感じで書く
client.send('/run-code', 'play :C');
上記以外のはこのあたりを読めば良いだろう。ちなみに、RaspberryPiのステレオミニジャックではなく、USBスピーカーを使っている場合、なぜか起動時にサウンド関連の設定が初期化されるため、音量がゼロになるという問題があった。この場合、SonicPiを起動してからalsamixerなどから音量設定を元に戻せば問題なく動いた。
私だけかもしれないが、RaspberryPiのステレオミニジャックはホワイトノイズがかなりうるさく感じたので、USBスピーカーとかで利用できないとそもそも作品を作るのは無理かと思っていたが、ちゃんと動作してほっとした。
ターミナルから利用する(暫定)
多くの人がRaspberryPiをどのように使っているのかは知らないが、私はSSHで接続してターミナルから使うことがほとんどである。ただSonicPiはXWindowが起動時に必要なので仕方なくxrdpとリモートデスクトップで接続してSonicPiを起動したりしていたが面倒くさく、また上述のような起動のたびに音量を調節するのもなんだかなぁという感じだった。で、どう考えたってこんなもんサーバー単体で起動できるようになっているはずだと思って調べてみた結果、あまり綺麗ではないが雑に動かしてみることまでは成功した。私自身よく理解できていないのですごく飛ばして書くが、音のミックスに利用しているjackdがRaspberryPiではデフォルトdbusというプロセス間通信を利用していて、dbusがXWindowに依存しているから通常では起動できないのだ。SonicPiを単体で起動する方法、というのでは該当の記事を見つけることができなかったが、jackdをXWindow無しで起動するという記事はいくつか見つけられた。
How do you really start JACK server before X?(+ my own ugly solution)
Solution for jackd2 and dbus without X session
私は前者の方法で起動することにした。記事内にあるとおり、DISPLAYを0にして、よくわからんが起動中のdbusのセッションIDとかを環境変数に展開するとjackdが起動できる状態になるので、ruby /opt/sonic-pi/app/server/bin/sonic-pi-server.rbでサーバーが起動するようになった。ちなみにjackdを先に起動してもsonic-piのサーバー起動時に落とされてしまうので、あくまでも環境変数を展開して、起動できる状態にしておくだけでよい。ちなみにそのあたりのコードはこのあたりである。
ただ、これはすごい雑によく調べもせずにとりあえず動かしたというだけのものなので、一時のデモなんかに使う以外では真似しないほうが良いかもしれない。音は正常動作してはいるが、サーバーの起動時にも、メッセージの受信時にもエラーが見える。これが正しい手段なのかどうなのかもよくわからない。
しかしこれでプログラムから音を鳴らすことができるようになった。普通に使うと反応速度が遅いので、楽器を作ったりするのは苦労するかもしれないが、いろいろ面白いことができそうだ。
*
青木 直史
オーム社
売り上げランキング: 29,937
オーム社
売り上げランキング: 29,937
実際すごいわかりやすい本。
Raspberry Pi
売り上げランキング: 396
売り上げランキング: 396
超はやい。