Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?
-
@aaronventure said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
Also you can hardcode your matrix in the script if it helps.
That's what I am doing. I've built an extremely elaborate module tree using a script. As soon as I load a sample map, a bunch of it is reset. Booooo hisss.
-
Hmmmm. I'll take a look. The typo is indeed a typo, but it came from the autocomplete! Most strange.
BTW, my code already does:
slot_data['sampler'] = builder.get(sampler, builder.InterfaceTypes.ChildSynth);
And that also returned the same error. So I guess I need to try a few of these suggestions out.
-
Right, yes... you were totally spot on. This worked:
// Creates the sampler var sampler_name = slot_name + "_sampler"; var sampler = builder.create( builder.SoundGenerators.StreamingSampler, sampler_name, slot_data['module_index'], builder.ChainIndexes.Direct); // Gets the sampler routing matrix and sets up the slot_data references var sampler_routing_matrix = Synth.getRoutingMatrix(sampler_name); slot_data['sampler_index'] = sampler; slot_data['sampler'] = builder.get(sampler, builder.InterfaceTypes.ChildSynth); var as_sampler = Synth.getSampler(sampler_name); as_sampler.setUseStaticMatrix(true);
The key lines being the last two.
-
Ah spoke too soon. It works, as in... when I load the sample map, it doesn't reconfigure the output mappings.... but I stop hearing all of the channels. I'll dig into it, but it may be that I have to bite the bullet and write a function to load the sample map and then re-create the routing for me immediately after.
-
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
var as_sampler = Synth.getSampler(sampler_name);
as_sampler.setUseStaticMatrix(true);You can use the childSynth reference with
asSampler()
For example
const mySampler = Synth.getChildSynth("mySamplerId"); mySampler.asSampler().doSamplerThing();
You should use
const
instead ofvar
- avoidvar
in general unless you have no other option. -
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
You should use const instead of var - avoid var in general unless you have no other option.
All this code is in a set of functions, and whenever I try to use const it says const can only be declared on a global level, so I was holding off optimizing it for now. I'm assuming it is going to be a case of putting all my functions into some namespaces and then using 'reg' ?
-
You should use inline functions rather than functions where possible.
Within inline functions variables need to be declared as
local
You should declare component and module references within
on init
asconst
. Generally you shouldn't declare them within functions - the only time I think you would is when using a widget factory which returns the reference to be stored in aconst
.I recommend reading this post from Christoph about best scripting practices, if you haven't already.
-
I'd clean forgotten about inline functions! haha. Silly me.
-
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
You should declare component and module references within on init as const. Generally you shouldn't declare them within functions - the only time I think you would is when using a widget factory which returns the reference to be stored in a const.
What about in cases where you're doing the following?
-
Helper functions to create a sub-tree for your main module tree. Necessitates declaration of components within a function.
-
Helper functions to modify elements of a tree. Necessitates creating a reference to an object; either using the built in get methods, or by storing your declarations from step 1 in a global const tree, and then parsing that tree in step 2 helper functions.
???
-
-
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
Helper functions to create a sub-tree for your main module tree. Necessitates declaration of components within a function.
This is what I meant by widget factory. At the end of the function you can return the widget to store it in a const if you need to refer to it in other parts of your script. If you don't need to refer to it outside the function then no need to return it.
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
modify elements of a tree.
I'm not sure what you mean by tree.
-
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
This is what I meant by widget factory. At the end of the function you can return the widget to store it in a const if you need to refer to it in other parts of your script. If you don't need to refer to it outside the function then no need to return it.
Right, yes. That's basically what I'm doing. I'm inserting data into a global const, and not returning anything from the function.
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
I'm not sure what you mean by tree.
I just mean a sub-section of the main module tree; a container and all of its sub modules.
-
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
global const
Do you mean an actual global variable, or just a const that you declared in on init?
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
I just mean a sub-section of the main module tree; a container and all of its sub modules.
Ah I haven't done anything with adding modules via scripting yet so I'm not sure of the best practices there. But in general if you have a reference to a module or component that you are using throughout your script you should get it into a const - the widget factory method might be suitable here, I'm not sure.
-
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
Do you mean an actual global variable, or just a const that you declared in on init?
Yeah, sorry. That is what I mean. I tend to think of anything setup in on init as being global.
@d-healey said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
Ah I haven't done anything with adding modules via scripting yet so I'm not sure of the best practices there. But in general if you have a reference to a module or component that you are using throughout your script you should get it into a const - the widget factory method might be suitable here, I'm not sure.
I'll have a sweep through my code and have a think how/if some of it could be modularized and refactored to follow this suggestion. Not seeing any detrimental effects right now, and none of this code will be running at runtime anyway once the plugin is built, because the builder isn't accessible in the VST plugin, iirc.
-
So back to the core issue.
I have a Sampler with 10 outputs. The sampler sits in a container with 20 channels.
I send each of the 10 outputs to channels:
0, 2, 4, 6, 8, 10, 12, 14, 16, 18
I then insert 5 send effects into the sampler FX block. These are setup to route 1+2, 3+4, 5+6, 7+8, 9+10 to a send container.
The routing for the send container takes the signals and routes them to:
1, 3, 5, 7, 9, 11, 13, 15, 17, 19.In this way, I get the mono multi-mic signals from my sampler, duplicated and turned into dual-mono signals.
This all works fine and I have sanity checked it to death. At the container I have 0+1, +2+3, 4+5, 6+7, 8+9, 10+11, 12+13, 14+15, 16+17, 18+19 ... and each pair is essentially exactly the same signal.
I won't belabour the point as to why I'm doing this, just that I need to. And it works fine.
The problem is, when I load a sample map, the sampler configuration is completely reset. I want to preserve the routing I have setup.
However when I do this:
var as_sampler = Synth.getSampler(sampler_name); as_sampler.setUseStaticMatrix(true);
If I do it the other way, I get the same thing:
var this_sampler = Synth.getChildSynth(sampler_name); this_sampler.asSampler().setUseStaticMatrix(1);
I'm only getting the first two channels from the multi-mic samples in the Sampler. I'm not getting the full range of samples.
It does not seem to matter if I declare setUseStaticMatrix(true) before or after the routing config. It simply seems to lock me to the first two outputs.
Anyone got any ideas?
-
Right, I guess what I'm gonna do is learn broadcasters, then use the attachToSampleMap function, and use that to rebuild the routing matrix for the sample after a sample map loads.
Wish me luck!
-
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
I guess what I'm gonna do is learn broadcasters
This is such a core HISE Script concept and class (also among the best documented classes) that it should be the first thing anyone learns when they decide to do more advanced scripting.
You're scripting the entire module tree build but you're sleeping on broadcasters?
Yeah, you're about to unlock another dimension
-
@aaronventure said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
@Orvillain said in Is there any way to disable routing matrix reset behaviour when loading a sample-map or when creating a multi-mic set of samples?:
I guess what I'm gonna do is learn broadcasters
This is such a core HISE Script concept and class (also among the best documented classes) that it should be the first thing anyone learns when they decide to do more advanced scripting.
You're scripting the entire module tree build but you're sleeping on broadcasters?
Yeah, you're about to unlock another dimension
Yeah just had it on my list, but only just now finding a reason to prioritise it!
-
Blooming blooms of bloomington! That was a lot easier than I had thought it was going to be! More or less the example in the documentation was all I needed to do. Here's the code for setting up the broadcaster. This happens in the main interface onInit function.
const var b = Engine.createBroadcaster({ id: "sampleListener", args: ["eventType", "samplerId", "data"] }); b.attachToSampleMap("Kick_sampler", "SampleMapChanged", ""); b.addListener("", "funky", function(eventType, samplerId, data) { build_sampler_routing(samplerId); });
This triggers a function called build_sampler_routing, which takes the samplerId in as an argument:
inline function build_sampler_routing(sampler_id) { local parts = sampler_id.split('_'); local slot_name = parts[0]; local routing_matrix = slots[slot_name]['sampler_routing_matrix']; routing_matrix.setNumChannels(sampler_channel_count); local slot_default_routing_data = default_channel_data[slot_name]; for (channel in slot_default_routing_data) { local channel_data = slot_default_routing_data[channel]; routing_matrix.addConnection(channel_data['source_idx'][0], channel_data['sampler_output_idx'][0]); if (channel_data['source_idx'].length > 1 && channel_data['sampler_output_idx'].length > 1) { routing_matrix.addConnection(channel_data['source_idx'][1], channel_data['sampler_output_idx'][1]); } } }
That's how I needed it to work for my script anyway. Your mileage may blooming well very.
Also shout out to @d-healey - signed up to your patreon guv, and learnt about broadcasters from your video. Would definitely love to see more there. Seems like broadcasters can handle a lot of the heavy lifting when it comes to communicating between different parts of a plugin.