
概要 📖 – MIDI 受信メッセージをテーブル化してロギング・コールバック駆動
MIDI Event DATは、外部 MIDI 機器からの受信メッセージをテーブル行として蓄積し Python コールバックで処理する DATです。Filter Page で Message / Channel / Index / Value による絞り込みが可能で、Callbacks DAT に紐づけた onReceive(dat, rowIndex, message, ...) 内で行単位の処理を実装します。
主な用途 🎯
- MIDI コントローラ / シンセからの受信メッセージをテーブル形式でリアルタイムロギング
- Note On / Note Off / Control Change / Pitch Bend 等の MIDI イベントを Python コールバックで処理
- メッセージ種別・チャンネル・インデックス・値によるフィルタリングで特定の MIDI 信号のみ抽出
- MIDI Learn (アサイン学習) ロジックの構築 (最後に動いたコントローラを動的に取得)
- 外部 MIDI 機器のデバッグ・通信プロトコル可視化
データフロー 🔄
入力: MIDI Device (DAW / コントローラ / 仮想 MIDI)
↓
MIDI Event DAT がイベント受信 (Note / CC / Pitch Bend 等)
↓
テーブル行として蓄積 (時刻・種別・チャンネル・インデックス・値)
↓
Callbacks DAT のonReceiveで Python 処理 / 後段 OP に分配
初心者の方は、以下日本語書籍も手元にあると安心です。

実際の案件事例まで踏み込んで紹介されていて、効率よくスキルアップするなら必携の二冊です!
パラメータ解説 ⚙️
Connect Page 🔌
ロギング有効化 ✅
Active .active ✅
– On 時、MIDI イベントをテーブルに記録
– Off 時は受信を停止 (テーブルは更新されず、コールバックも呼ばれない)
Filter Page 🎛️
メッセージ種別除外 🚫
Skip Sense .skipsense 🩺
– On 時、Active Sense メッセージをログから除外
– デバイスから常時送信される keepalive のため OFF だとテーブルが急速に埋まる
Skip Timing .skiptiming ⏱️
– On 時、MIDI Clock / Timing Tick メッセージをログから除外
– DAW 同期環境では毎秒数十〜百回送信されるため、楽音情報のみ抽出したい場合は On 推奨
メッセージフィルタ有効化 🔎
Filter Messages .filter 🔎
– On 時、以下の Message / Channel / Index / Value / Dir による絞り込みパラメータが有効になる
– Off 時は全 MIDI イベントを記録
絞り込み条件 🎯
Message .message 📨
– MIDI メッセージ種別で絞り込み (例: Control Change / Note On / Pitch Bend)
– 公式例: "Control Change" を指定すると CC メッセージのみ記録
Channel .channel 🎚️
– MIDI チャンネルで絞り込み (1〜16)
– マルチティンバー音源やマルチコントローラ環境で特定チャンネルのみ取り出すのに使用
Index .index 🔢
– MIDI メッセージのインデックスで絞り込み (1〜128)
– Note number / CC number 等、メッセージ内の第 1 データバイトに対応
Value .value 📊
– MIDI メッセージの値で絞り込み (0〜127)
– Velocity / CC value 等、メッセージ内の第 2 データバイトに対応
Dir .dir ↔️
– メッセージの方向で絞り込み (input / output)
– TouchDesigner が送出した MIDI も Out 方向としてログ可能
Received Messages Page 📥
コールバック設定 🐍
Callbacks DAT .callbacks 📜
– 受信イベントごとに実行する Python コールバックを記述した DAT を指定
– 行が追加されるたびに onReceive(dat, rowIndex, message, channel, index, value, input, bytes) 等が呼ばれる
– 詳細な引数仕様は公式 midieventDAT_Class 参照
実行スコープ (Tscript レガシー) .executeloc 📍
Execute from .executeloc 📍
– スクリプトを実行する OP の場所を決定するメニュー (Tscript 専用、現代の Python コールバックでは無視可)
– Specified Operator 選択時のみ From Operator パラメータが参照される
From Operator .fromop 🔗
– Execute from が Specified Operator のときスクリプト実行元となる OP のパス (Tscript 専用)
– その OP の状態変化が DAT のスクリプト実行をトリガーする旧仕様
出力テーブル制御 📋
Clamp Output .clamp 🧱
– On 時、テーブル行数を Maximum Lines の上限で頭打ちにする
– Off 時は無制限 (長時間運用で MIDI Clock 等を保持するとメモリ圧迫リスク)
Maximum Lines .maxlines 🔢
– Clamp Output が On のときのテーブル最大行数 (デフォルト 100)
– 上限を超えると古い行から削除される
Clear Output .clear 🧹
– パルスでヘッダ行を除く全行を削除
– Python からは op('midievent1').par.clear.pulse() で発火可能
Bytes Column .bytes 🧬
– On 時、生 MIDI バイト列 (16 進) を別カラムに追加出力
– SysEx 等のメーカ独自メッセージを解析する際に必要
Common Page 🔧
Language .language 📝
DAT が動作するスクリプト言語の決定方法
| 項目 | 内部名 | 説明 |
|---|---|---|
| Input | .input |
入力 DAT のスクリプト言語を使用 |
| Node | .node |
この DAT 自身のスクリプト言語を使用 |
Edit/View Extension .extension 📄
外部エディタに公開するファイル拡張子の選択
| 項目 | 内部名 | 説明 |
|---|---|---|
| dat | .dat |
汎用的なファイル拡張子 dat を使用 |
| From Language | .language |
DAT のスクリプト言語に応じた拡張子を自動選択 |
| Custom Extension | .custom |
Custom Extension で指定したカスタム拡張子を使用 |
Custom Extension .customext 🔤
Edit/View Extension が Custom Extension のときに適用される拡張子:
- Custom Extension 文字列:
Edit/View Extensionがcustomのときに使用される任意のファイル拡張子
Word Wrap .wordwrap 🔁
ノード表示でのワードラップ (折り返し) の有効化
| 項目 | 内部名 | 説明 |
|---|---|---|
| Input | .input |
入力 DAT の Word Wrap 設定を継承 |
| On | .on |
Word Wrap を有効化 (ノード上の長い行を折り返し表示) |
| Off | .off |
Word Wrap を無効化 (折り返さずそのまま表示) |
実践アイデア 💡
Example 1: MIDI コントローラのフェーダーで TOP パラメータを駆動 🎚️
MIDI Controller → MIDI Event DAT (filter: Control Change) → Callbacks DAT (onReceive) → Constant CHOP / TOP パラメータ
外部 MIDI コントローラの CC (Control Change) メッセージを MIDI Event DAT で捕捉し、Callbacks DAT 内で対応する CHOP / TOP パラメータに値を書き込んで映像をリアルタイム操作するフロー。
- MIDI Device Mapper Dialog でコントローラをマップし MIDI Event DAT を配置
Filter Messagesを On、MessageをControl Changeに設定して CC のみ抽出- Callbacks DAT を作成し
Callbacks DATパラメータで紐付け onReceive(dat, rowIndex, message, channel, index, value, input, bytes)内でop('constant1').par.value0 = value / 127等で正規化値を書き込みActiveを On にして受信開始、コントローラ操作で TOP パラメータがリアルタイムに変化
Example 2: MIDI キーボードの Note イベントで音響合成をトリガー 🎹
MIDI Keyboard → MIDI Event DAT (filter: Note On) → Callbacks DAT → Audio Oscillator CHOP / Trigger CHOP
MIDI キーボードからの Note On / Note Off を MIDI Event DAT で受信し、コールバック内で Audio Oscillator CHOP の周波数と Trigger CHOP のパルスに変換して音響合成を駆動する例。
- MIDI Event DAT で
Filter Messages= On、Message=Note Onを設定 onReceive内で MIDI ノート番号 (index) を周波数 (Hz) に変換 (440 * 2 ** ((index - 69) / 12))- Audio Oscillator CHOP の
frequencyパラメータに書き込み - Velocity (
value) を Volume CHOP の gain に対応付け、Trigger CHOP に pulse を送って ADSR エンベロープを起動
Example 3: MIDI Learn (アサイン学習) システム 🎓
MIDI Controller → MIDI Event DAT → Callbacks DAT (learn mode) → Table DAT (アサイン保存)
Learn ボタン押下中だけ MIDI Event DAT を有効化し、最後に動いた CC を Table DAT に記録、次回以降そのアサイン情報を参照して特定の CC のみを処理するワークフロー。
- UI Button (Learn) で
op('midievent1').par.active = 1をトグル - MIDI Event DAT の
Filter Messages= On +Message=Control Change - Callbacks DAT で受信したメッセージの
channel/indexを Table DAT に追記 (アサイン情報) - Learn 完了後は
Activeを Off に戻し、運用時は Table DAT を参照して特定 CC だけにルーティング
関連オペレータ 🔗
類似機能OP 🔍
- MIDI In CHOP — MIDI メッセージをチャンネル化して CHOP として受け取る版
- MIDI In Map CHOP — MIDI Device Mapper Dialog のマッピングを CHOP として読み込む版
- MIDI Out CHOP — MIDI メッセージを送信する出力側 CHOP
組み合わせ推奨OP 🔄
- MIDI In CHOP — イベントログ (MIDI Event DAT) と CHOP 値 (MIDI In CHOP) を併用して状態と履歴の両方を扱う
- Table DAT — MIDI Learn のアサイン情報やフィルタ設定の保存先
- Trigger CHOP — Note On 受信時に ADSR エンベロープを起動して音響合成や演出に接続
- Constant CHOP — コールバックから書き込んだ CC 値を後段の CHOP ネットワークへ供給
前処理・後処理DAT 🎯
- 前処理: Text DAT、Table DAT
- 後処理: Select DAT、Convert DAT、Null DAT
Info DAT情報 📊
MIDI Event DAT は Info DAT による詳細情報取得に対応しています。
DAT 固有情報 📋
num_rows: DAT の行数num_cols: DAT の列数type: DAT の型 (table / text)is_table: テーブル形式の場合 1、テキスト形式の場合 0
汎用オペレータ情報 🔄
total_cooks: プロセス開始からのクック回数cook_time: 最後のクック時間 (ミリ秒)cook_frame: 最後にクックされたフレーム番号warnings: 警告数errors: エラー数
トラブルシューティング ⚠️
よくある問題と解決策 🔧
❌ Problem: MIDI メッセージを受信してもテーブルに行が追加されない
✅ Solution:
Activeパラメータが On になっているか確認- MIDI Device Mapper Dialog (Dialogs → MIDI Device Mapper) でデバイスが正しくマップされているか確認
Filter Messagesが On のとき、Message/Channel/Index/Valueの条件が厳しすぎて全件除外されていないか確認Skip Sense/Skip Timingを一時的に Off にして任意のメッセージが入るか診断
❌ Problem: MIDI Clock / Active Sense でテーブルが瞬時に埋まる
✅ Solution:
Skip SenseとSkip Timingを共に On にして keepalive 系メッセージを除外Clamp Outputを On +Maximum Linesを 200〜500 程度に設定して履歴長を制限Filter Messagesを On にして必要なMessage種別 (Note / CC 等) のみを記録
❌ Problem: Callbacks DAT の onReceive が呼ばれない
✅ Solution:
Callbacks DATパラメータに Text DAT へのパスを正しく設定し、関数名がonReceiveであるか確認- Callbacks DAT 内に構文エラーがないか Textport / Console でスタックトレースを確認
Active= On かつ Filter で全件除外されていないかを再確認- 公式 midieventDAT_Class の引数仕様に従っているか照合
❌ Problem: Pitch Bend / SysEx 等の値が想定と違う
✅ Solution:
Bytes Columnを On にして生バイト列を取得し、メッセージ構造を 16 進で確認- Pitch Bend は 14 bit 値 (2 バイト) を組み合わせる必要があるためコールバック内で再構築
- SysEx は Vendor ごとにフォーマットが異なるため公式仕様書を参照しながらパース
参考資料 📚
その他 🔗
- TouchDesigner Wiki — DAT 概要
- TouchDesigner Wiki — Category:DATs
- TouchDesigner Wiki ホーム
- TouchDesigner 公式 Forum
- Facebook — TouchDesigner Help Group
公式リソース 📖
- TouchDesigner公式ドキュメント – MIDI Event DAT
- TouchDesigner公式ドキュメント – MidieventDAT Class
- MIDI Device Mapper Dialog 解説

