🎹

TouchDesignerでMIDIのデータを加工してOSC通信する

2024/07/28に公開

ARドラム(#さくたまDrums)でOSCを使っているさくたまです。

MIDIデバイス-MIDI->TouchDesigner-OSC->どこか
ということをしたかったので備忘録です.

https://zenn.dev/sakutama_11/articles/799d5f5a9af4fc
この記事を書いたときはTouchDesignerなんもわからんで諦めたのですが,ちょっとだけ仲良くなれたのでTouchDesignerで同じことをします.

  1. MIDI Deviceを認識させる
  2. MIDI受信用ノードをセットする
  3. OSC送信用ノードをセットする
  4. Pythonでカスタムする

1. MIDI Deviceを認識させる

Dialog > MIDI Device MapperでMIDI Mapperウィンドウを開きます.

Create New Mappingでデバイスの枠を作ります.
MIDIデバイスをUSBなどでPCに繋ぎます.
In Deviceに認識させたいMIDIデバイスを選択します.
複数のMIDI Deviceを一番左のカラムのIDで識別することができます.
MIDIコンを操作すると,MIDI Consoleの欄が更新されます.

2. MIDI受信用ノードをセットする

Tabキーでノードを追加します.
DAT > MIDI In を選択します. ※CHOPにもMIDI InありますがDATタブのピンクの方を選んでください.

midiin1midiin1_callbacksができます.

midiin1では,認識するデバイスを指定します.
認識したいMIDI DeviceのDevice IDを入れます.

MIDIコンを操作するとノード内にログが出ます.

midiin1_callbacksではPythonスクリプトでMIDIを受信した時の挙動を設定できます.
4で説明します.

3. OSC送信用ノードをセットする

Tabキーでノードを追加します.
DAT > OSC Out を選択します. ※CHOPにもOSC OutありますがDATタブのピンクの方を選んでください.
CHOPとDATが違うと,4のsendOSCメソッドがないというエラーが出ます.

  • CHOPは,毎フレーム何かの値を監視してその値を使ったstaticな処理を行う仕組み.
  • DATは,デバイスや外部通信で送られてくるデータを処理する仕組みで,Pythonコードで制御できます.

↓Kodaiさんの記事を読んで, 違いをそう解釈しました.
https://qiita.com/kodai100/items/5b614fed5f3e17b7f8f6

さくたま勘違いポイント

CHOP=ChannelOperatorとDAT=Dataで,CHOPの方がカスタマイズした処理が挟めそうな雰囲気出てませんか?
Operatorが「演算子」という意味しかもたないとしたら, if文とか実行内容が変わるような処理は挟めないということも理解できますが.
理解が間違っていたり命名の由来や文化がわかる人いたら教えてください.

DATとCHOPの違いがわからず,そもそもどちらにも同じ名前のノードがあることも知らず,「記事の通りにやっているのに💢」と思ってつまづきました.
↓sendOSCメソッドある
https://derivative.ca/UserGuide/OscoutDAT_Class
↓sendOSCメソッドない
https://derivative.ca/UserGuide/OscoutCHOP_Class


OSC Outノードの設定をします.

Network AddressとPortには送信先のアドレスとポート番号を入れます.
今回はiPhoneとProtkolというアプリを使って確認しました.
iPhoneのプライベートIPアドレス確認方法.

ProtkolのPort番号を入れる.
https://apps.apple.com/jp/app/protokol-midi-osc-monitor/id1451570764

4. Pythonで送信する

midiin1_callbackノードでPythonを編集します. ノードの詳細ウィンドウの方のEditを押すとエディタが開きます.


Pythonエディタのカスタマイズ方法は
TouchDesigner > Preferences > DATs > Text Editorです.

onReceiveMIDIに任意の処理を書き込みます.

midiin1_callback
def onReceiveMIDI(dat, rowIndex, message, channel, index, value, input, bytes):
    if (message != "Note On" or value == 0):
        return
    print(message, channel, index, value)
    
    osc_out = op("oscout2")
    # address: OSCAddress 例:"/hoge/fuga"
    address = "/test"
    # args: 変数のリスト 例:[0,0,1]
    args = [float(index-1), value / 128.0]
    osc_out.sendOSC(address, args)
    return

↓こちらを参考にしました
https://qiita.com/iwaken71/items/f4c9e1c3b789d19657ae
今回は,ノーツのたたき始めだけを通知したり,0-128で飛んでくるvelocityを0-1にまとめたりといった処理をしています.よしなに.
op("oscout2")は,TouchDesignerのノードを名前で引っ張ってくる関数です.
printデバッグをするには, Dialogs > Textport and DATs でコンソールを開けます.

以上でMIDIからPythonで整形したOSCを送信することができました. (OSC Outノードの見た目は変わりませんでしたがちゃんと動いていました)

おわりに

DATノードだとPythonがかけるということがわかってちょっとTouchDesignerと打ち解けた気がした.

Discussion