Request: ScriptNode Direct Access
-
I'm now working on a large 16x16 matrixed network with a whole bunch of interconnect, and most of it needs to be controlled from script. I'm talking way more 30 parameters, mostly because of EQ, which is 15 controls per module, and I have... you guessed it.
Managing the main network parameters for UI access becomes a nightmare once you go past 30.
I recently figured out you can fetch values for node parameters directly from the interface script using references: https://forum.hise.audio//post/92587
So I'm asking for a way to be able to set them directly. Seeing how there's already API in place for getting node references and pulling parameters, I have a feeling this could be easy to add, but I'm source-illiterate so I could as well be wrong.
This would require easy navigation through the network tree given the current state of identification where ID is hidden (and unchangeable other than by editing the XML directly). So perhaps getting the parameter would involve daisy chaining get calls for nodes which can be got with Name only by looking at children nodes. So:
network.get("FXChain").get("Split").get("PMA Factoring").set("Value", 0.5);
Set obviously still works on parameter IDs because the node parameters are still using the ID property, but getting a node via the name property should be possible. This enables very easy iteration over large matrices or trees because you can just duplicate the whole tree, rename the topmost container, and have the rest of it stay like it is, without having to track hidden ids (which would now include manually going over each node's name and putting it down). The whole thing is now ready for your
for
loop in the interface script.The only problem could be multiple nodes within the same container sharing the name, in which case I see a couple of options:
- the get attempt for getting the node by name returns a warning and the script execution stops
- it returns a warning and returns the first node in the chain that matches the name
- it returns an array of references (this would be perfect as you can add trees and the script adjusts dynamically by using
length
, instead of having to hardcode the count).
In case of number 3, if there was previously only 1 node with the name and the get method used to return a single reference, allowing for
node.get("ChildChain").get("PMA").set("Value", 0.5);
if you now add another node, the get return for
get.("PMA")
would be an array, but ideally it would not break the scripting, allowing for the codenode.get("ChildChain").get("PMA").set("Value", 0.5);
to still set the Value parameter of the first node, instead of now having to call
node.get("ChildChain").get("PMA")[0].set("Value", 0.5);
This would prevent regular code breaking when iterating and having to do constant back and forth, of course while being conscious that the old node with the same name needs to stay the first in the chain. Maybe this then allows for the get method's return to always be an array, as calling
set
on the array reference always targets its first element anyway.Given how there's a lot of string operations here (with the implied use of the methods to do dynamic iteration for matrices using even more string operations when targeting nodes), it's clear that this would not be realtime-safe. But it doesn't need to be: it just needs to enable reasonably sane implementation and iteration for UIs that need to interact with a lot of network elements where a reasonable number of primary network parameters is not nearly enough.
Thanks for reading.
-
@aaronventure Agreed.
-
Came back to this and went digging a bit.
Relevant hidden class:
https://github.com/christophhart/HISE/blob/df56b2fca6839d0e29ffc1efbde4e6b8b6825da4/hi_scripting/scripting/scriptnode/api/NodeBase.h#L119The parameter reference is obtained from a node reference.
setValueAsync()
orsetValueSync()
is used to set a value of the target parameter.Range can be set with
setRangeFromObject()
A Range object is
{ "MinValue": -100.0, "MaxValue": 0.0, "SkewFactor": 5.422270774841309, "StepSize": 0.1000000014901161, "Inverted": false }
This works perfectly even in exported plugins, unless AllowCompilation is enabled for the network, but that may have something to do with the current state of ScriptNode export when AllowCompilation is enabled.
@Christoph-Hart do you have anything to add to this? Would this ever be possible with AllowCompilation or does it fundamentally collide with the concept?
-
@aaronventure nope, all this is gone when you compile a node.
Have you thought about using a slider pack for controlling the parameters? This translates well into compiled nodes.
-
@Christoph-Hart I haven't - isn't it limited to like 16 ? I need around 200 parameters for this one network.
It's loaded with Faust stuff so if you can tackle the Faust compilation issues, it may be that this network doesn't need to be compiled so this method can be used, as it would barely benefit from it due to how much of it all is Faust.
More about that on the appropriate thread, which I'll update as this has given me an idea...
-
@aaronventure It shouldn't be limited to 16, but there's still a bug with the number of sliders an ExternalSliderPack can handle.
This might be of interest to you: https://forum.hise.audio/topic/11411/externaldata-sliderpack-seems-to-be-limited-to-128/13?_=1743103883757