10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TidalCyclesとToudhDesignerをつなげる

Last updated at Posted at 2021-12-18

はじめに

しゃんぺんです。こんにちは。

趣味でTouchDesignerを楽しんでます。
今年は素敵なAudio Visual Liveを沢山浴びる機会があり、勢いで「Audioもやりたい!」となり、TidalCyclesに手を出し始めました。

この記事ではTidalCyclesとTouchDesignerを連携させる方法について紹介します。

サンプルファイルはこちら。
https://github.com/thinpedelica/tctd

補助テキスト

本稿ではTidalCyclesについてはほとんど説明しません(できません)。
別途以下を参考にしてTidalCyclesを始めてください!!

音をTouchDesignerに入力する

TidalCycles/SuperColliderが出力する音をTDに引き回すために、「VoiceMeeter Banana」という仮想ミキサーを利用しました。
選択理由は、「特殊な機材が不要&無料」です。ただ、申し訳ないのですがWindows専用ツールでした。

VoiceMeeter Bananaの詳細は[こちら](link https://ordinarysound.com/voicemeeter-banana/#index_id0)が詳しいです。
VoiceMeeter Bananaをインストールすると、仮想オーディオデバイスとして認識されるようになります。
これにより、TidalCycles(SuperCollider) -> VoiceMeeter Banana -> TouchDesignerと入力できるようになります。

手順は以下のとおりです。

以下のコマンドを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");

audio_in_1.png

  • VoiceMeeter Bananaの出力先を設定する
    audio_in_2.png

画像のオレンジ色の枠で囲んだ部分が出力先の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を選択すると、音の信号を得ることができます。
    audio_in_3.png

これで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」でよしなにする
    editor_in_7.png

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メッセージのパース

OscIn Datでパースしました。
osc_in_1.png

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とつなげて楽しんでもらいたいです。

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?