How do you disable/enable various samplers for keyswitching?
-
How do I, in the master container script, disable/enable the various samplers so I can make a keyswitch behavior? I know you can right-click on the sampler and "create script variable declaration" and I get something like this:
Container:
CloseMic = Synth.getChildSynth("Close Mic"); MidMic = Synth.getChildSynth("Mid Mic"); FarMic = Synth.getChildSynth("Far Mic"); ```Sampler in each container:
hardM = Synth.getChildSynth("hardM");
tradM = Synth.getChildSynth("tradM");
softM = Synth.getChildSynth("softM");How do I, in the master container script, disable/enable the various samplers so I can make a keyswitch behavior? btw, it looks like you can have two things with the same name. I guess I need to do something like "C_tradM" for "close mic traditional mallet." An aside: what happens if you have two things with the same name and attempt to do things with them in scripting?
-
The most efficient approach would be using MIDI channels to switch between the articulations. This way you don't need to have scripting callbacks for every sampler which could result in a performance penalty. This preset sketches this:
[attachment=0:td8adkgf]keyswitch.xml[/attachment:td8adkgf]
You have one global MIDI channel setter and a MIDI channel filter in each sampler that is set to its articulation index (1,2,3).
In the script processor of the global container, you have this code:KeyswitchSetter = Synth.getMidiProcessor("Keyswitch Setter"); function enableHardM() { KeyswitchSetter.setAttribute(0, 1); } function enableSoftM() { KeyswitchSetter.setAttribute(0, 2); } function enableTradM() { KeyswitchSetter.setAttribute(0, 3); }
You can now implement the keyswitch behaviour by using these functions in your onControllerCallback. However, this concept is not really bullet proof: if you change articulations while some notes are playing, the MIDI channels of the note on / off events won't fit and you will get stuck notes. I think I'll add an option to the filters to only filter note ons - note offs would be received by all samplers and prevent the stuck note problem.
Until then, you could also use this ScriptProcessor instead of the MIDI channel filter that implements this logic:
<processor type="ScriptProcessor" id="NoteOnChannelFilter" bypassed="0" script="// [onInit] // =============== // onInit Callback channelFilter = Content.addKnob("Channel", 0, 0); channelFilter.setRange(1,16,1); // [/onInit] // [onNoteOn] // ================= // onNoteOn Callback function onNoteOn() { if(Message.getChannel() != channelFilter.getValue()) { Message.ignoreEvent(true); } } // [/onNoteOn] // [onNoteOff] // ================== // onNoteOff Callback function onNoteOff() { } // [/onNoteOff] // [onController] // ===================== // onController Callback function onController() { } // [/onController] // [onTimer] // ================ // onTimer Callback function onTimer() { } // [/onTimer] // [onControl] // ================== // onControl Callback function onControl(number, value) { } // [/onControl] "><editorstates bodyshown="1" visible="1" solo="0" oninitopen="0" onnoteonopen="1" onnoteoffopen="0" oncontrolleropen="0" oncontrolopen="0" ontimeropen="0" contentshown="1"> <childprocessors><content> <channel value="1" visible="1" rangemin="0" rangemax="1"></channel> </content></childprocessors> </editorstates></processor>
@td8adkgf:
btw, it looks like you can have two things with the same name. I guess I need to do something like "C_tradM" for "close mic traditional mallet." An aside: what happens if you have two things with the same name and attempt to do things with them in scripting?
Yes, if you rename a module it doesn't check if the name already exists. If you add a module from the clipboard, it searches all modules and tries to give it a unique name (eg. "DefaultEnvelope32"). But it currently looks only for the module itself - child modules will not be renamed by default.
If you end up with multiple modules with the same name, the first one of the child modules will be used - this could lead to unexpected behaviour. I suggest you name all modules you want to use in scripting like variables - something like your "C_tradM".
-
It seems to me that the simplest method would be to toggle the bypass button of the sampler. How is this done via script?
I've also thought of another way to do this. How about a global variable that keeps track of which articulations are active and when a note plays each sampler can check this variable to see if it should ignore the note or not?
The problem I see with using MIDI channels is that limits us to 16 articulations.
-
The problem I see with using MIDI channels is that limits us to 16 articulations.
Yes Elan also complained about this a while ago. But with the new event system the channel amount is 256, so this should not be a bottleneck anymore.
Bypassing is a bit harsh, because it doesn't fade out anything and will produce clicks. However, if you don't bother, this is how you do it:
const var synthToBeBypassed = Synth.getChildSynth("SynthName"); // must be the ID of the synth / sampler module synthToBeBypassed.setBypassed(true);
I would recommend this solution: Use a MidiMuter on every channel and set its first attribute:
HiseSnippet 1148.3oc6Y00SiaDEcbRrVvrg1UcenO5F0GBRzPry1OTWsh.YIUTH.BSQUppZ6D6IjQXOS53w.gU7er+T3eP6L1Nw1fIjPaWwxlHPh49wjybuy8brEGvn1HeeJCnrzQCGf.JOW0ZHg2uUeHl.19s.kuPcGzP+ywb695acAzafKBr4vAPeejCPQo3OICTYwRfvOWu9lPWHwFkXB.NlhsQ6h8v7Dq+QycvttsgNnivdoh9UM21lRZQcoABPUTsNX.z9T3In8fxvJnBNCiN2GnTWsgYM1oFcubiZ0pcY2gcLmzu6BrCXLDgerHcfhpxeK9nntkClSYVbHGI1yRaRcFZ0mdNI5q9XrOtq37JVX.rDXJxbapqi7vK+aPq9XWmCFUG8A.kmcPRUsXTU8kpcvN3w1SptednC8jLRWZUJLI3Y7.gmRJ3UJBduP0xlgGvS7Hw1RIc9LvJJVPgAET0D8Jet9YPltUzUj2n2hR3h5bMniyNDZ2pUh7TYU85heV40Zqsl9u8yV6uWbJ+t1nL7QRDL.w3XjeaF0SFUp7eeYMc8JdvKp7i5lqFtvmiFXguDIrTwnRYsqh2+0R+ETVqbJfJK3cB3Hl.qg20qcBhmo8Tsx3XprxqyMWyoIYy6J6FSS1MDY2KfXywThNkrGki1mTcEs2qsn1UZ2zSud44RVYYTWWDKOuxIO1DRqJIvqKhsp.7tAnv3FiNYyZCNmg6JVUsdbL5e0ajs3xoBz7tizHajMt6HMEs0qzDWoyNPnMcCD1Q2uREHkrMAy2e.JdPeT48VV50KsojxYZqgkwbBKwzsmBAw24kyiwgKBkGNMtb7znkK1Aw.XwP2BpQWkAgUjTbqMA2dZVvoPcBbg7rDMRh5XGhtblI5skXwGyGllHeFXepmK6iQdm6oDtuP8.44Me7VHG7JJj+ei2Xt7xpa0qGxlm.1Rps+0GJw8CCJKGAkkTsvDTHSRHPVHbstwDDn+q+6En22lCOCcDCR7GP8yrwVHO7QThrFjX7W7QsYn+7PYeMs8VTHKWWWudawwJ2brf7.V3EjM7nADdlKDEePp6YmSR00xQKszGOR8EGckYLearHex5L.5FEuhSGflHSWg6hoay.NWLhKY5VVEeBgxPwltAe20qClh83yT6guvhGXepjC2OmM4CFoYwoax+d5cOaDFsvxm+dKxYHWwyIEyT9VTOXfKer06EjBMVwyTmX4kMOD4hfoGc+5l6JF4fLwYG8.OeFS+4aR8fuTMBt5RZH8mFBXE+zT.6PZ.GSNoCT7HdWHdGr8B7rDpH1HARHDjqu78xJHoLhVWWtNRFg3TezKsE6zPtVI1owHmSuHo4iDQxqWetH4icQxmmr17otJYXSbt93b8w45ieRqO13wxKQ17Qk9n5+R8w6QL5IkVYiOBzJi2t4Zky0JmqUNWqLiV4GhuCOnMi9N6HJH4c4EBsHN2jv+gmKp1QtV2HgyoNvSvv9NaaYw9aDUm7yvblynwLmwql4L91YNiualy36m4L9gIjgTNai.N0KZzC.9GnjBhkO
-
Thanks Christoph, I'll give it a try
-
The MidiMuter works really well, thanks for the demo.
I've not seen the
!=
operator used in that way before, took me a moment to work out how it worked, a very clever and efficient solution. -
Hello!
Sorry to bump up this old topic, but I couldn't make a keyswitch, maybe I'm missing something important, I am not a programmer, so for people like me it would be AWESOME if one of you would make a short YouTube tutorial on how to make a very simple library with 2 articulations and how and where exactly to write those 2 keyswitches scripts.
Thank you for your help!
(It might not be the most important thing for now, but I guess knowing and teaching everyone how to do the keyswitches is still pretty important IMHO. :) )
-
Oh, by the way, is there an option to color the key for the keyswitching notes?
-
Take a look at my github repo, I have some modules for colouring keys (the playable range script) and switching articulations. You can use these as is or use them as a jumping off point for your own scripts. - https://github.com/davidhealey/HISE-Scripting-Framework/tree/master/v3/modules