Calling functions in midi processors...
-
@d-healey said in Calling functions in midi processors...:
It does mean that in some instances you'll be duplicating GUI controls
OK so in the end you are saying I should include the View/Controller with the Model....Ok, but now I have a dynamically loadable set of (say) 30 fx's - now we are saying every one of these effects MUST have its own set of widgets? - ugly ugly ugly.
-
@Stroggan OK.. so can you demonstate that then.
-
OK so in the end you are saying I should include the View/Controller with the Model....Ok, but now I have a dynamically loadable set of (say) 30 fx's - now we are saying every one of these effects MUST have its own set of widgets? - ugly ugly ugly.
I haven't worked with adding/removing effects dynamically so I might be missing something but effects don't have MIDI processors so I'm not sure why the number of effects you add will affect the number of widgets. Widgets are no different to having a script full of variables, a widget is just a holder for a value.
I think you need to give a more full explanation of what you are trying to achieve so that I can see the bigger picture and how HISE's way of working can be used for your project.
-
@Stroggan said in Calling functions in midi processors...:
You could store all required info for the samplers in global variables and act on that information in the specific samplers midiprocessors.
That's what I suggested earlier, but things will get messy and it's really not the "best" way to do it if you can avoid it.
-
@Lindon Well what i wanted was perfect control over which note ID got played by which sampler so I set a constant variable identifier in each sampler's midiprocessor:
const var identifier = 0;
And when I trigger a note I store it's ID in a multi dimensional array [sampler ID][noteID].
which then gets ignored or played in the sampler midiprocessor:function onNoteOn() { input_id = Message.getEventId(); local i; for(i = 0; i < 8; i++){ if(Globals.SamplerNoteIds[identifier][i] === input_id){ Globals.SamplerNoteIds[identifier][i] = -1; return; } } // if loop doesn't find id, ignore event Message.ignoreEvent(true); }
This is indeed a bit messy as @d-healey said, but plain midimuters did not provide that amount of control.
-
@d-healey OK here it is: (but this is just one instance of a problem....)
An instrument has 4 samplers, 3 play chromatically assigned notes (drum sounds)
1 plays an enhancement sound.
Th user selects an enhancement sound from a drop down list of 40 potentail sounds. - Lets say they select sound "sub001" which we know is assigned to midi note number 60 in Sampler4
The user press midi note number 45 on their keyboard:
Sampler 1 plays the close-mic-ed snare sound (which is "under" note 45)
Sampler 2 plays the over-head mic-ed snare sound
Sampler 3 plays the room -mic snare sound
Sampler 4 plays sub001-- it doesnt matter which "sound"/note the user plays - the instrument ALWAYS plays Sub001 along with the other midi-mapped sound, until the user selects another "enhancment" sound
-
Meanwhile the level of frustration just gets higher and higher. I loaded your snippet Dave... OK I can work with that (except I cant as we will see).
I add a knob01 to my samplers on init midiprocessor:
const var Knob1 = Content.addKnob("Knob1", 0, 0);
--- but of course when I go to my interface its nowhere to be seen....how do I make it show up in my interface? how do I even edit it.
-
@Lindon that could be solved easily with Globals.subNote = 60;
and in Sampler 4 use:
Message.setNoteNumber(Globals.subNote);
-
@Stroggan yes I'm sure and thanks for that but Dave and I (I think) are trying to work out the Correct way to do this....
-
I'm looking forward to learn the correct way as well then
-
I cant even get the "interface" to show up any more - all I get is Canvas:ScriptProcessor1
-
@Lindon said in Calling functions in midi processors...:
const var Knob1 = Content.addKnob("Knob1", 0, 0);
heres the snippet now.... it all seems broken to me
HiseSnippet 1581.3oc6X0raaaDDdokYhsZTQSZNzC8.gQKfCpqgj0eIsnHx+GiDGqJ4DzCFHcM4J6ElbWVxkNQIH25ySQQeAZu0mi9Fj2f1YWRZtJV1gLINQso5f.2Ymg6Ly2ty7sra.2lDFxCPFyt6PeBx3Jl8GxDGt5gXJCs0ZHiOxTPBE83QBBZkg93vPhCxvnzlRELlcZj52Kt8JXWLyljIBgdHmZStG0iJxj1sycottafcH6R8zztQmsr4rU4t7HvYJYVE4isOBe.49XoZSYhLtz5NTAOnu.CdDxX5U3NC6eH+wrX8eHMjtuKQNnFpO7hhEuA20Q5wRonUOj55zMMnCQHCytYofRwofqatM0gdh7rTwmnlvJyB87gwTmm6US28ple2yPy8lN18tpYe6.puHalXXZKlfDL.aOJLEqKZpJFlqxAMXhE8vGQ1H.FbhEy2pZ0ErZVs5M91JkqTdPDyVP4LKN69bAYG172nR4mUorE7K9e3UExcIK5GPYh4mixr4dT1AyIse1Wx8psnuKd31CkuJXgVnV7x77SuNCFL+MJ+rxyV945SIc6.tqKIXbyJ2EEbNlMOKxaeRvBVGiciHo5AIyQQKyyFsz2LYGmB0Tjy1hQE63SXmEFhRx6vSOXq0vBrDVSjA54SBDToKXrF4X37RLHOq4ZjviDbe3Dyo1A.6C4NQtXwnaNkmHSl.RAirKPhzrPpXn9I1Kjcr40cupYWpv9vw6uSMF+ExZWz9ax4+JlqOX.wVj4rSatwObweXW2Ul4LpFOiopnZs2Fkh8ycoXiRugkdq9uuRu++4tODO284wtx0L6KBHXYOs9XOen2ixepn3BkJ4LNB9ie+C9s29GA6FPb4Xm9zmpo1ezYkHHkELpzesiZoV1iGwFYsRb7dDeBV.6.zrYlN85sY.Ox+ks5E2VseY2.fMFjMzmXGFAR8B8Xb0.dX3.HbTuqP8o5FEbfLWkIoG4XRP3nxtejG.+LFwU1T1vP1zLjHgap81XQ.8I5ZqVkp6hUP9WZtTiEG82w6.+M3qjOdqUUiiMoVwMYohaR8haRihaRyhaRqhaR6BYhg4nGSub9XWsM1uKFfdMMWglb.DlKVhdSkS1to7NsFRioayktn51TJeA2aB49OMQZlGUabj7M9SSnpQn.35FXcWFe+ZVemUJqeriiTz7yolXtEr.F+.Q7wv0+zboeeyNu7aK14oAYpjpnSBNcQYAktTUvLF0xDcdj+i47CpCpJTX8Gmfp8coNP6DJ.kW1TgNHU5PuR2q0UGj554yYx023JuxEMqzZ2epyHL.BECkY6KoTD4QcbbIc4.OAI+grNB+dnf3m1K5YW+W17ud5OeaOctoHjG9I58PBg9WxZ5v86GPc8BgJ79a4AW6W1CFp7a4PFfibEVgP2GjKkcDwYWtR+2cDzJkOVFuhS3yl5i8oxBZqyNF5nCRj930.LSEmoRG8781bF2+PNiZOZ+SHacvAj.ceerAzxBAz9NSx06zi3RvgZaw9hN2ixH3fQoETnbQwq1MV75yLicWK44Mq+aPrtzG7DqOuTGTSR0i2BV8.wDNNeESEgHKIo82Wtp7qwBjwSIDaBrl6C2TvlnycdJY2m3wUkikNTeByQM3ugeISVKknsbxZoShrSeUPrk7rpCjQIBSx1RceQWfBu6HcJxpmiBUfpGPbC5fGO.YLSOt7JCSa1nE5d76RFpdtA5NzzmuIH+gx2pLQbGp5QSyZK0FkbEkDdfT2juMrq4ZeydKG4P46kDR836yE6IKkEvngh81zkaeD.N9ThalXKKc4Vw6ACylWMKTUzA3TYUsQqEeL9XzZQ9tTa.LkgO5TQUyZZQ0sxhpl0mLipl0xUTogUM0vplSnXUybgUszvplZXUqITrpUtvpVZXUKMrp0DJV0JWXUaMrpkFV0dBEqZmKrpsFV0VCqZOghUsyEVUWCqVRCqpOghU0yEVUWCqpqgU0mPwp54BqZngU00vpFSnXUiwgUuKnC8tXM7v1A7GYG+YBjDulQIAxzLUJdVyskisN46CHwF313zGYaKAsutFBMdKVpvVTuvVznvVzrvVzpvVztvVbyywB4mEb4HA2K9FdfftqGyJ1X8SXEWB8O.k21wZ
-
const var Knob1 = Content.addKnob("Knob1", 0, 0);
--- but of course when I go to my interface its nowhere to be seen....how do I make it show up in my interface? how do I even edit it.
Controls should only be added this way to MIDI processors that aren't the user interface script. Is that the interface you are talking about? If so did you click the interface button (the one to the left of the callback buttons)?
-
heres the snippet now.... it all seems broken to me
There are no controls on the main interface. Did you add any in the interface designer? Or did I lead you to believe they were added by the other script?
-
@d-healey yes thats what you led me to belive I think...
OK what is the process of adding a slider to the midi processor of a sampler and have it show up in the main interface?
-
@Lindon You have to add them to each separately.
For example I have an instrument and it has a sampler with a MIDI processor for handling legato, and another MIDI processor for handling round robin (nice and modular).
On my user interface I want to give the user a control to bypass the round robin script and to adjust the xfade time of the legato. But I don't want them to have access to the other controls of those scripts such as setting the playable range or the legato volume etc. So on my user interface I add a button and I connect this via parameter ID in the interface designer to the bypass button of my RR script, I also add a knob which is connected to the xfade knob of my legato script.
It seems like more work duplicating controls and I was put off at first, but actually it's very fast to do and allows me to easily create scripted modules that can be used in different projects and with entirely different interfaces.
I have a load of modules here you can play with - https://github.com/davidhealey/HISE-Scripting-Framework/tree/master/modules - I use the
Connect to external script
option from the context menu that appears when right-clicking on a MIDI processor's header. -
@d-healey OK, thanks.
-
So then just the one outstanding question:
why oh why cant I say this in my main interface script:
const var myScriptProcessor = Synth.getMidiProcessor("myScriptProcessor"); myScriptProcessor.myFunction(param,param);
instead of this I have to create a set of interface widgets in myScriptProcessor, one for each param of myFunction then call another widget to execute the logic in myFunction
What is wrong with exposing the method(sorry Function) and allowing me to call it from somewhere else?
Surely we can all agree the current approach (if it is all we have) is a bit broken?
-
@Lindon said in Calling functions in midi processors...:
So then just the one outstanding question:
why oh why cant I say this in my main interface script:
Because scripts can't talk to each other directly. You can do that using Global variables but it really isn't necessary.
instead of this I have to create a set of interface widgets in myScriptProcessor, one for each param of myFunction then call another widget to execute the logic in myFunction
Create your module and get it to work exactly how you want (makes it really easy to test the code is working) then add the controls to your UI that you want the user to have access to and link them together in the interface designer. It's a 10 minute job...
What is wrong with exposing the method(sorry Function) and allowing me to call it from somewhere else?
I can see this being useful and can't see a downside to it (maybe Christoph will see a pitfall) but it will kind of collapse the tree paradigm.
Surely we can all agree the current approach (if it is all we have) is a bit broken?
I haven't encountered any problems with it so far. Just requires a different way of thinking about problems.
-
It‘s definitely not broken, it enforces encapsulation and moves the responsibilty to operate on data to where it belongs.
If you want to avoid multiple controls, store them in a global data object (or multiple variables) and use a single button in your target script that fetches all values and do the appropriate thing.