はじめに
しゃんぺんです。こんにちは。
趣味でTouchDesignerを楽しんでます。
今年は素敵なAudio Visual Liveを沢山浴びる機会があり、勢いで「Audioもやりたい!」となり、TidalCyclesに手を出し始めました。
この記事ではTidalCyclesとTouchDesignerを連携させる方法について紹介します。
アドベントカレンダーの記事に貼るやつ😉#tidalcycles #touchdesigner pic.twitter.com/oVBDZSdTCa
— Shampagne (@Shampedelica) December 17, 2021
サンプルファイルはこちら。
https://github.com/thinpedelica/tctd
補助テキスト
本稿ではTidalCyclesについてはほとんど説明しません(できません)。
別途以下を参考にしてTidalCyclesを始めてください!!
- 演奏するプログラミング、ライブコーディングの思想と実践
https://www.amazon.co.jp/dp/4802511043 - moistpeaceさんのブログ
https://moistpeace.com/ - インストールハマりログ
https://shampagne.hatenablog.com/entry/20211023/1635000341
音をTouchDesignerに入力する
TidalCycles/SuperColliderが出力する音をTDに引き回すために、「VoiceMeeter Banana」という仮想ミキサーを利用しました。
選択理由は、「特殊な機材が不要&無料」です。ただ、申し訳ないのですがWindows専用ツールでした。
VoiceMeeter Bananaの詳細は[こちら](link https://ordinarysound.com/voicemeeter-banana/#index_id0)が詳しいです。
VoiceMeeter Bananaをインストールすると、仮想オーディオデバイスとして認識されるようになります。
これにより、TidalCycles(SuperCollider) -> VoiceMeeter Banana -> TouchDesignerと入力できるようになります。
手順は以下のとおりです。
- VoiceMeeter Bananaをインストールする
https://vb-audio.com/Voicemeeter/banana.htm - VoiceMeeter Bananaを起動する
- SuperColliderが認識しているデバイス一覧を取得する
以下のコマンドをSuperColliderで実行すると、一覧が取得できます。
ServerOptions.devices;
-> [ MME : Microsoft Sound Mapper - Input,
MME : VoiceMeeter Aux Output (VB-Audi,
MME : マイク配列 (Realtek(R) Audio),
MME : ライン (NewTek NDI Audio),
MME : VoiceMeeter Output (VB-Audio Vo,
MME : Microsoft Sound Mapper - Output,
MME : スピーカー (Realtek(R) Audio),
MME : VoiceMeeter Aux Input (VB-Audio,
MME : VoiceMeeter Input (VB-Audio Voi,
Windows DirectSound : プライマリ サウンド キャプチャ ドライバー,
Windows DirectSound : VoiceMeeter Aux Output (VB-Audio VoiceMeeter AUX VA...etc...
- SuperColliderの音の出力先にVoiceMeeter Bananaを指定する
上記の一覧から、「VoiceMeeter Input」もしくは「VoiceMeeter Aux Input」を指定して、以下のようにコマンドを実行します。
o = Server.default.options;
o.outDevice_("MME : VoiceMeeter Aux Input (VB-Audio");
画像のオレンジ色の枠で囲んだ部分が出力先のOn/Offの指定になります。
A1が物理出力、B1/B2が仮想出力(VoiceMeeter Output, VoiceMeeter AUX Output)です。
実際に音を鳴らすには、A1の物理出力先を赤枠の部分から選択する必要があります。
B1/B2はどちらか片方だけがOnであればよいです。
- TDのAudioDevice inでVoiceMeeter Bananaから音の信号を取得する
ここまでのステップが出来ていれば、TDのAudioDeviceIn ChopでVoiceMeeter OutputもしくはVoiceMeeter AUX Outputを選択すると、音の信号を得ることができます。
これでAudioVisualやり放題です。
コーディング画面をTouchDesignerに入力する
TidalCyclesで演奏するなら、当然コーディング画面もスクリーンに映したくなりますよね。
なんならTDに入力して、映像と重ねたくなりますよね。
ということで、OBSでエディタをキャプチャしてNDIでTDに引き回しました。
手順はこちらを参考にしました。
いちおう私が実施した手順を記載しておきます。
- OBSStudioをインストールする
https://obsproject.com/ja - NDIプラグインをインストールする
https://github.com/Palakis/obs-ndi/releases - 「ソース -> 追加 -> ウィンドウキャプチャ」で、エディタを指定する
- 「ツール -> NDI Output settings」で、適当にNDI出力に名前をあてる
- 「右クリック -> 変換 -> 画面に合わせて置く」を選択
- 「右クリック -> フィルタ -> クロップ/パッド」で上下左右の余計な部分をカット
- TDのNDI In Chopでエディタ画面を入力する
- Composit Chopの「screen」でよしなにする
OSCをTouchDesignerに入力する
TidalCyclesとSuperColliderはOSCで通信しているのですが、SuperColliderに一筆加えてやると、TidalCyclesからのOSCメッセージを外部に中継してくれるようになります。
TidalCyclesのコマンドで映像の制御が出来たら便利という噂(from moistpeaceさん)、、ということで、やってみました。
OSCメッセージの構造
まず、TidalCyclesが出力しているOSCメッセージの構造を解析しました。
TidalCyclesのコマンド構文
d9
$ sound "yeah yeah yeah yeah" # gain 0.0
# note 1
# resonance 0.5
# speed 0.3
# distort 0.8
出力されるOSCメッセージ
/dirt/play
_id_
9
cps
0.5625
cycle
26.0
delta
1.7777
distort
0.8
gain
0.0
note
1.0
orbit
8
resonance
0.5
s
yeah
speed
0.3
OSCアドレス
- /dirt/play
TidalCyclesのバージョンの差分なのか、ここが"/play2"となっていることもあるようです。
OSCデータ
データは、パラメータ名と数値のペアになっているようでした。
-
トラック:_id_, orbit
TidalCyclesはd1,d2,d3,,,と複数のトラックがあり、複数のトラックを並行して鳴らすことができます。
このトラック数、諸説あるのですが手元で確認した限りd1~d16まで利用可能でした(過去はd9が最大だった模様)。
OSCメッセージを調べた限り、どのトラックのメッセージかは、_id_とorbitに反映されているようです。
_id_は1オリジンの値(d9なら9)、orbitは0オリジンの値(d9なら8)といった具合でした。 -
音のタイミング関連:cps(cycle per second),cycle,delta
映像の制御には使わない情報だと思うので説明は割愛します。 -
音の種類:s
sはsoundの略で、上記例では"yeah"という名称のsoundを使用しています。 -
エフェクト:note, resonance, speed, distort, gain
エフェクト名と数値の順で送信されます。
OSCメッセージの送信タイミング
TidalCyclesからSuperColliderへのOSCメッセージは、音を鳴らすタイミングで毎回送信されていました。
例えば、"bd bd bd bd"といった「バスドラを1cycleで4回」というコマンドの場合、1cycleで4回のOSCメッセージが送信されます。
OSCメッセージを作るうえでの注意点
- 文法エラーの場合、OSCメッセージは送信されない
実在するエフェクトやパラメタ値を使用してメッセージを構成する必要があります。
Myコマンド構成
上記の特性を踏まえ、以下のようなメッセージで映像制御することにしました。
d9
$ sound "yeah yeah yeah yeah" # gain 0.0
# note 1
# resonance 0.5
# speed 0.3
# distort 0.8
-
sound
なんでもよかったのですが、ごきげんな雰囲気にしたくて"yeah"を選びました。 -
gain
実際に音が鳴っては困るので、gain 0を指定することで音量0にしました。 -
note
映像の切り替えに使用しました -
resonance, speed, distort
映像に入力するパラメータとして使用しました。
選んだエフェクト名はなんとなくです。
SuperColliderの設定
以下のコマンドをstartup.scdに書くか、IDE上で記述し実行します。
(
var addr = NetAddr.new("127.0.0.1", 7000);
OSCFunc({
arg msg;
if(msg[2] == '9', {addr.sendMsg("/tidal", *msg)}, {});
},'/dirt/play').fix;
)
OSCFuncは、指定のOSCアドレス(ここでは/dirt/play)を受け取ったときに実行するコールバック関数を登録するもののようです。
上記では、受信したOSCメッセージ内容を'/tidal'というOSCアドレスとして丸ごと「"127.0.0.1":7000」に送っています。
msg[2] == '9'は_id_の値を見ており、負荷軽減のためにd9の場合のみTDに送信するようにしました。
OSCメッセージのパース
argsを全チェックして、TABLE_INDEX dict内のキー名と一致したら値を抜く、みたいなのです。
TABLE_INDEX = {"note" : 0, "resonance" : 1, "speed" : 2, "distort" : 3}
COL_VAL = 1
def onReceiveOSC(dat, rowIndex, message, bytes, timeStamp, address, args, peer):
table_params = op("table_params")
args_index = 0
args_index_max = len(args)
while args_index < args_index_max:
if args[args_index] in TABLE_INDEX:
target_raw = TABLE_INDEX[args[args_index]]
target_val = args[args_index + 1]
table_params[target_raw, COL_VAL] = target_val
args_index += 2
else:
args_index += 1
return
これでTC->TDできますね。
おわりに
TouchDesignerのTipsが全くない記事になってしまいましたが、音楽も鳴らせるようになったらTouchDesignerをより一層楽しむことができる、と思っています。
また、TidalCyclesを使っている方たちにも、ぜひTouchDesignerとつなげて楽しんでもらいたいです。