Well, if you add a name mangler that sortof imitates what linker does, then it actually is useable, for me. Otherwise you can’t include the same function more than once in the same sythdef, if it has any control args of its own. Name conflicts are horribly handled right now, by the standard SC machinery, but at lest for func args there a is straighforward fix to make them visible across lexical units. The dynamically generated names by the old Control.names
interface have rather horrible corner cases that I personally didn’t find worhtwhile supporting, rather than patching the few places in JITLib where they were still used for some reason (There also use of the NamedControls in nearly the same library, e.g. in GraphBuilder.)
Hers’s another feature to ponder: names for control busses, and perhaps for all busses.
Inside a single SynthDef you can give your controls, connecting wires and in fact all your signals, meaningful names (which pretend to be variables), at least during Synth development, except for outputs.
So a logic control synth has decent names as input and just a largish array as output. I can’t think of any EDA package or circuit (HDL) language (e.g. Verilog) from the last 40 years that was like this, where inputs in your circuit can be named, but outputs cannot.
Yeah, I’m probably going to get one of those “I’ve been using SC for 20 years and never needed this” replies or “this is music/dsp software, not circuit design, so we’re used to bus numbers because we only use a handful”.
By the way, CSound added a signal flow graph facility around 2010. And it has multiple names outputs, much a like a HDL. But it falls short of SC’s flexibility because CSound uses a syntactically specified graph, as far as I can tell, whereas in SC the graph is obtained by some OOP magic by running the user’s SynthDef function on some special objects (OutputProxies) passed as inputs. (Really, it’s the simplest way to use OOP to generate an abstract syntax tree. It was like assignment #2 in a compiler class I took 25 years ago, or so.)
Perhaps in keeping with CSound philosophy, one is expected to run an external program to generate a graph from an OOP-like paradigm, as for CScound scores in general there are (too) numerous external generators, CMask and what not. There’s some discussion on their dev list on philosophical differences in that regard, where it was even noted that “one can not define [a] Reverb instrument and use multiple instances of it with the inlet/outlet/connect [CSound] opcodes. In a system like SuperCollider, one might instantiate multiple Synth instances of SynthDefs but tell them which channels of the bus to read from/write to, and that’s done at the instance level, not the definition.” Well, if you use my fairly simple SC mangler extension, you can easily have multiple function instances compiled in the same SynthDef (without control name conflicts), so you can even have it as one SynthDef in SC.
Another thing that could perhaps be done as a UGen: some kind of address decoder, so if you have e.g. 128 synths you don’t need 128 * number of params busses to map them to some control logic. But you can have them select themselves based on an address bus (only 7-bit wide in this case) and have them only read from the data bus (the only needs to be as wide as the params) when their in-built address matches what’s on the address bus. If this sounds too “circuity” for music, just think how MIDI works: it doesn’t use hundreds of wires for interconnect, which would happen if you had one wire per instrument to select them.
Pause.kr
can do a wee bit of this as it’s the only UGen I know that can do something to another based on its id. But it’s flexible enough, because it can just turn some other node on or off.
I actually overestimated how difficult is to do this part in current SC, when I wrote the above. It turns out it’s actually fairly easy… because SC busses pass floats, not just bits… duh.