Change export destination dynamically ? programmatically?

Hi there,

still building the piece of network I need for parsing, scaling and routing my midi flows to many parameters.

I’m thinking about making something that could change the export destination dynamically.

preset 1, that node export to THIS parameter
preset 2, that same node export to THAT other parameter.

I could switch. That would do my dynamic routing.

Is it possible to change export destination programmatically ?

I checked the documentation and only saw export flag that can be set/get.

There are other alternative, as I could have my preset designed explicitely with nodes. I mean, that preset is that midi flow until Nulls (all parameters needed to be controlled by exporting would get a null which would export ALWAYS to each parameter) and then I’d need big part of the network on and off… but that way would involve a lot of nodes/connections.

As always there are many possible ways to the goal in TD :wink:

First, you should always export from a Null, always. This way you can always add a switch or a filter or whatever before the Null without having to redo any export.
So this is already one answer, before the Null CHOP one or multiple Switch CHOPs with multiple inputs, maybe some Merge CHOPs and whatnot, now you you only have to control the Switch CHOP(s) to control which data ends up in the last Null CHOP from which you export to your parameter(s).

Furthermore you can go the other way around, and use Python scripts to set the reference in each parameter as often as you like. So now you don’t export from a CHOP to a parameter, but you type the reference in the parameter value. (for instance op("mychop")["bass"][3] to get the 3rd sample from the channel named “bass” in a node called mychop)
These Python scripts can be executed for instance if you press a preset GUI button (use the CHOP Execute DAT for this) or if a specific midi signal comes in (use the Midi In DAT).

This tutorial from Matthew is an oldie but still very useful: Understanding Referencing | TouchDesigner – Matthew Ragan

1 Like

I got it.
The idea of having everything in a script is really interesting.

I’d have my midi flows (I mean: Midi In CHOP → my bunch of Select CHOPs → scaling → Nulls) and I’d have script that could “link” all my nulls to these or that parameters. ok

But, what if I wanted to go “further” and scripting everything ?
I mean, same as before BUT without the bunch of Select CHOPs->scalings> Nulls segments ??

MIDI In DAT could do it no? And that way, I could also put everything in the MIDI In DAT ? from Midi select (CC, notes etc) for parsing, to scaling, to routing to this parameters or not ?

I mean, considering performance

Yes you could certainly skip the CHOPs and only use Python code. This depends on the project, what needs to happen with the incoming data, but also each developer has their own preference (I’m more of a Python guy myself). Usually ‘analog’ stuff like Filter CHOPs, Lag CHOP and any ADSR curves are better done in CHOPs. But you can mix and match any way you prefer, for instance do it all in single Python script and add CHOPs where needed.

Actually, scripting is nice as it would provide the all in one place. but instead of addressing the constant before my nulls themselves, I could put something between my constants and my null like Lag, Trigger CHOPs etc.

I was just “afraid” of node performance.
CHOPs are channels (what I was calling flows of data sometimes) and DAT are more like event/individual bits.

I’d just be afraid that MIDI In DAT would be less fast than DATs which it is probably a stupid believe.

it’s true that numbers (more specifically, floats) are native to CHOPs so they perform faster than DATs which have to convert every number to strings and back again. Also CHOPs are compiled C++ which is always faster than Python script. There will be a time you’ll notice that, but for handling incoming midi messages at 60 FPS I’d say Python scripts are fast enough.

1 Like

Something to think about when you’ve got a data source and a secondary source that controls the data’s destination:

  • what happens to destination A when your control destination changes to B? What is the value of parameter A? Does it go back to some default value? Does it keep the last value it had? How can you ensure that just because you’re no longer actively controlling A that A’s setting isn’t visible in the output somewhere?
  • if I inherit your setup, do I have a chance in hell of figuring out what’s going on? If it’s just yourself, if you get sidetracked for a month on another project, can you easily re-figure out what’s going on?

It’s a lot cleaner to have a 1:1 mapping between CHOP channels and exports, i.e. do not randomly change what gets exported to where – every channel gets exported always to the same parameter.

This requires making a unique channel for each destination, and to do the switching upstream from that. I should be able to get a comprehensive overview somewhere of what data is going where, i.e. I should be able to figure out what data stream is heading for any particular parameter.

Achieving this entails doing the switching of source data → CHOP channel all in CHOPs. Said another way, if I have 30 different parameters I want to control, I should have 30 CHOPs channels that then export to the appropriate parameters (doesn’t have to be a single CHOP node, but the collection should be proximate). I can then inspect the 30 channels and see if the values contain what I expect them to contain without having to jump to all ends of the setup to see if a particular parameter is getting what I expect.

The elegant part of this is that if you add a 31st parameter, all the work to do this is in one place.

1 Like