Feature request: subpatcher invocation from within codebox / GenExpr
Currently, composing gen~ algorithms from reusable abstractions requires working at the visual patcher level. It would be very useful to be able to invoke a gen abstraction as a function call from within a GenExpr.
gen (which loads a .gendsp abstraction) and setparam (which drives named parameters inside a subpatcher) are both exclusively visual objects. There is no equivalent within GenExpr codebox code. The only related construct in GenExpr is Param (capital P), which declares an externally-drivable parameter, but requires passing params via setparam in the parent patcher.
This means that if you're authoring a complex algorithm inside a codebox, you cannot call out to an abstraction. You have to either inline everything, or split your design across mixed codebox/visual-patcher layers, which can get unwieldy.
Something along the lines of this would be cool, no need for complex import statements:
out1, out2 = gen("example.filter", in1, freq: cutoff, q: resonance);This would allow building modular, composable DSP algorithms entirely within the codebox authoring context, treating abstractions as first-class callable units rather than requiring a context switch to visual patching just to wire in a subpatcher.
Hi Dan,
Actually this already works, but the syntax is a little different.
Let's say you save a gen patcher as "supadupa.gendsp", either in the same folder as your main Max patch, or in some searchable path, then you can invoke it as if it was a function inside a codebox, e.g. :
out1 = supadupa(in1);
The only thing to watch out for is to not use characters in the gendsp file name that would not be valid characters for a function name in GenExpr. It should start with a letter, then can have letters, numbers and underscores in the name -- but not a "." character for example. (Oh, and also make sure not to use a file name that is a built-in gen operator!)
If the gendsp has Param objects, you can also address these in the function call, e.g.:
out1 = supadupa(in1, myparam=74);
If there is any embedded state, such as history or data, or any stateful operators such as phasor, cycle, delta, etc. , then each literal instance of the supadupa() call in your codebox will create a new instance of all the state. (Note that this does not apply to multiple calls within a for loop, as these are only a single literal instance.)
This has always been a very rarely-used feature -- I'm not sure how many people even know about it.
Graham