Loading...
Please wait while we prepare your experience
Loading...
Please wait while we prepare your experience
Event-based control for real-time visual performance inside TouchDesigner.
Most audio-reactive systems rely on continuous sound analysis — volume, frequency bands, or envelopes driving SOP parameters directly. This project aims for something more musical: event-based geometry control, where individual MIDI notes trigger discrete SOP events, toggles, and modulations in sync with performance gestures.
The system is designed as a modular, event-driven architecture combining CHOP Execute callbacks, table-driven mappings, and a centralised SOP pool.
Every MIDI note routes to a parameter update or switch event without hard-wiring SOP paths. This enables rapid reconfiguration and scalable performance setups.
Core layers:
MIDI Input Layer
• Captures note-on/off events with velocity and channel data.
• Routes note information to the midi_reactive_mappings table.
• Executes callbacks to trigger parameter updates dynamically.
Parameter Mapping Layer
• Each note links to a specific SOP path and parameter.
• Table rows define toggle states and optional min/max ranges.
• Missing parameters or invalid paths log safely without breaking runtime.
SOP Pool & Modular Rendering
• A reusable SOP pool feeds the modular render network.
• SOPs are switched, toggled, or modulated via mapping data.
• Complex geometry systems remain decoupled from input logic.
Parameter Resolution – SOP parameters sometimes failed to resolve dynamically; null checks and attribute access validation fixed this.
Mapping Integrity – Early tables missed min/max columns, causing modulation errors; default fallback values were added.
Callback Synchronization – Parallel CHOP Exec nodes created duplicate triggers; logic consolidation in one callback improved consistency.
| note | sop_path | parameter | toggle | min | max |
|---|---|---|---|---|---|
| 36 | /project1/modular_render/geo1/switch1 | input | 1 | 0 | 1 |
| 37 | /project1/modular_render/geo1/switch1 | input | 2 | 0 | 1 |
def apply_toggle_modulation(note, velocity):
table = op('/simple_midi_mapper/midi_reactive_mappings')
for i in range(1, table.numRows): # skip header
if int(table[i, 0].val) == note:
sop = op(table[i, 1].val)
param_name = table[i, 2].val
param = getattr(sop.par, param_name, None)
if param:
param.val = table[i, 3].val # toggle or set value
print(f"[TOGGLE] Note {note} -> {sop.path}.{param_name} = {param.val}")
else:
print(f"[ERROR] Missing parameter '{param_name}' in {sop.path}")
This function forms the backbone of MIDI-driven SOP modulation, translating note events into parameter updates as defined by the mapping table.
The system now supports:
• Event-based SOP toggling and modulation via MIDI.
• Centralised callback logic with improved modularity.
• Table-driven configuration for rapid prototyping.
• Reliable runtime logging for live debugging and feedback.
The modular rewrite simplifies extending functionality — each layer operates independently, allowing flexible expansion of the control network.
1. Add velocity-based modulation for dynamic range control.
2. Introduce temporal smoothing for parameter fades.
3. Expand the SOP pool for multi-geometry performance control.
4. Create a visual GUI to monitor active mappings.
5. Implement preset management for mapping recall.
6. Explore generative behaviours — spawning and destroying SOPs dynamically via note sequences.
Technical Stack: TouchDesigner, Python (callbacks & parameter control), CHOP Execute, Table DAT, SOP switching, modular render pipeline.