
DIY MUSIC on DESKTOP - 演奏環境編
こんにちは。瀧本です。最近は青じそが食べたいです。
先日、Maker Faire Kyoto/Tokyoのスピンオフ企画、"DIY Music on DESKTOP"にてライブをしました。今回はそのライブで使ったシステムの裏側、主に遠隔での演奏システムについて話したいと思います。
なお、全体のまとめとか基板とかの開発についてはQuxのノートにリンクされていますのでぜひそちらも御覧ください。
概要
演奏のインターフェイスには皆さんも大好きなAbleton LiveとMax for Live (M4L)を使用しています。Live/M4Lでは主に演者間のデータ共有とシンセのパラメータの制御と、そしてサーボモータとLEDにデータの送信をしました。また、それぞれのシンセをシミュレーションしたM4Lデバイスを作ることで、シンセの音を実際に聞かずとも擬似的に練習ができるようにしました。
今回のパフォーマンスでは、遠隔でシンセを制御した上で、前回のライブでできなかった「リズム」の要素を取り入れたい、という私の気持ちがあり、Ableton Liveのセッションビューを演奏に使うことにもしました。
演者間のデータ共有
演奏者が遠隔4拠点(横浜、町田、川崎、ニューヨーク)に点在しているため、WAN超えで様々な情報を共有する必要がありました。複数のAbleton Liveで同時に演奏するためにはAbleton Linkという仕組みも有るので、「VPNを立ち上げて演者感で擬似ローカル環境を作り、そこでやればいいのかな?」とも思いましたが、どうやらLinkはVPN上では動かないらしいということで、Linkを使うのは見送りました。「もしかしたらVPNでもちゃっかり動いたりするんじゃ?」という淡い気持ちもありましたが、VPN用のサーバーを立ち上げるのが面倒だったのと、やってみてやっぱり動かなかったら悲しくなるのでやめました。
というわけで、演者間のデータ共有には、MaxでNodejsが走らせられるNode for Maxを使用しました。具体的にはNode for Maxでsocket.ioを走らせ、演奏に必要なパラメータをTCPでVPS(自前サーバー)経由で共有するという具合です。パラメータはすべてOSCと同様の記法でやりとりしました。
そして、ClipSyncというデバイスをつくり、セッションビューのクリップに記録されているノートも共有可能にしました。方法としては、
1. 現在再生されているMIDIクリップのすべてのノートを選ぶ
2. 選択したノートを取得する
3. replace_notesですべてを置き換える
のような流れで現在再生されているMIDIクリップの情報を他の演者と共有することを可能にしました。そうすることで、サーボを制御するマシン上ではトラック間の遅延がない状態で演奏情報をサーボに送る事が可能になりました。
また、各プレイヤーの演奏タイミングをなるべく近づけるために、MaxのオブジェクトをC++で記述できるmin-devkitを用いてht.alarmというオブジェクトを作り、時刻を設定して時が来たらLiveの演奏が始まる(厳密にはbangを出してLive APIで演奏を開始する)ようなオブジェクトを作成しました。まだオブジェクトは多くありませんが、私がmin-devkitを使って作ったオブジェクトはGithubで公開しています。これによって遠隔地にいても「よーいドン」の形で遠隔で演奏を開始することができるようになりました。
パラメータの制御
まず、演奏で使うシンセサイザーをモデリングしたMax InstrumentsとMax Audio Effectsを作成しました。そして、各デバイスのパラメータ情報をNode for Max経由で他のプレイヤーと共有可能にしました。
それぞれのデバイスは音響的にもシミュレーションされており、遠隔地でのシンセが起動していなくてもローカルで音を擬似的に制御することができます。当初の計画では、ローカルでいい音をつくり、リモートに適用するというGitのローカル/リモートレポジトリのような管理形式を取ろうと思っていたので、パラメータは即座にリモートに反映されず、Syncボタンを押すことでリモートに反映される設計になっていました。
ですが、私たちのシンセはアナログであることに加え、サーボ(SG90)の仕様上つまみは180度しか回せないため、シミュレーションからなる音と実際の音は大きく乖離しており、製作が進むにつれてシミュレーションはあまり使わなくなった上、連続的に値を同期し続けるAuto Syncモードを頻繁に使うようになりました。
ループやノートオンメッセージに合わせてオートメーションをかけたりもしたかったのですが、Liveのクリップに書かれたエンベロープカーブを取得する方法がわからなかったので、Liveの拍にあわせてパラメータにエンベロープをかけられる、EnvelopeShare/TriggeredEnvelopeというM4Lデバイスを作成しました。どのパラメータにマッピングされているかなども共有されるようにしています。この実装はすこし頑張りました。
サーボとLEDへデータの送信
サーボとLEDは以下のルールでOSCのメッセージが作成され、制御されていました。
サーボ:UI上のつまみの開度(live.dialのparameter raw value)がサーボの角度(0.0~180.0度)に変換される。
LED : 各プレイヤーごとに、MIDIノートのon/offがLEDの光量に、それぞれのつまみの角度がLEDの色相に変換される。
サーボとLEDはRaspberry Pi上で動くPythonで制御されていたわけなのですが、OSCでサーボの角度変更を大量に支持するとRaspberry Piが処理落ちする(I2Cでの通信におけるレイテンシーが影響?)ことがわかったので、30ミリ秒間隔に値を間引いて送信することにしてみました。
サーボとLED側に関する詳細は別の記事があるので、そちらを参考にしていただければと思います。
終わりに
今回のパフォーマンスで使用したほぼすべてのファイルはGithub上で公開しているので、中身に興味の有る方は是非見てみてください。作りっぱなしなので見にくいところや謎のコメントなども残ってるかも知れませんが、そこらへんはご容赦ください。
ライブのための制作費の補填とこれからの制作のためにも、サポートいただければ幸いです。