Calling functions in midi processors...
-
OK so here's my snippet
HiseSnippet 1586.3oc6X8tbaSDDWxNpD61.zRYF9.LHxTfjoAOxM+ok1oScbbRHz3DicZF9PlobU5ryMQ9NMRmRqgggWIFdB3Ifmk9F.6cRN5jiqqTIzZJ3Ojna+yo82t6c6tpkOyFGDv70zKcv.Orl9UL5LfxOdiiQDp1NMzzurAGGvayB4Xs5C7PAAXGMc8haKDPuzLZxeO+A0QtHpMNgjl1gLhMdWReBOgZqZOj35tExAe.ouhzqTaGaFcClKKDLlhFVZdH6SP8v6gDhUvPS+Ra5P3L+NbDXQZ5yTm4LnywrmRij+PR.4ItXwhpZcfMJh7VLWGgEKnpswwDWmVCAcflltQqDWPwHWv0MZRbHmQOwU79RFlIZn5OzKLIyq5K27rFm4oqXdyDYdW0nisOwimvIJLsCki86hrSGlhjUqvenarACjfxqzGcBdKeXwYZrvZVVKYtpk0h2atxyUFBDAbySQ9lhPeGTeOWru48MkYFU5g4R6TtZg4UDYdg5IJmxKppdJFKLeZm5HaxHXs5D1mHQS1opvV0MjZyILpIitGii2mtvhk+o4JaB+.2Q.yEWwymP4KLOgZy5Sn8.kJWZz2ZEOWzflCDaA3qVppvSU9mKO5t2sqX6KWJMKge2m4BNnwwUbLveBps.Mr+Sv9KAdC2P7P4frgzoaWJaoa1Q4.JBxn6PI788vwqm74Es3jH3oGsSCDGIxQioAx4g84Dg4n2.eJb3OJisjQCbvIblGb7+boyvgJlSnKhm9jl35kXFf6HUJsHskFP3CTu9IGG+rx7sCY0bupQKB293wauEFi8Bds+os23KylyXytcw17DicFis99W0atd0LkYeAkVl0PVgn5EQcEuLWWQu3ey5HVSK0Qt3Sj++ycuMct6iiLkqYzg6iQhhawEpk1ybFJkteQGA+gu6Q+1E+QvV9XWFxoC4GUD62qUODbY9oo9q0jup06yBoodWwFdarGFwgL.EclsV61a6yB8FUqm+.Y9xA9Pqkf2Pkw9TL354pXbCeVPPW.Nx8JPkUqP+dBeUBk13Sw9AoosWXeH7SoXWPYCccQQy.rHbSrah39jmoJs7sXc.RFx+biasRkz+Nce3Ocuo3wudC45HUpleUtU9UY47qxJ4WkUyuJqkeUtctTQ2H8wz2IacZ0D40BAgdEIqShO.B7FsYKqjzMo0oTPZLUatzz8TKENu4cYoUzDlhL51mqjrNc8+IWdt5q1XdIsspWHtuZPTtzxd234opGx4PEDhifDoGk4iiII67V8xBsLrGumQWxy5vCsOQLZPvnaxXKxM9Q69.iyMYyXGw6C0MNa7Ak4U5K+GbWzRlQOdHb46hieHHgZvEilHSJHnbTLgTQSbIXNgcDFHZrSaM5bMuomTp7E0jRCA4PJVZmANURIfRkpDLiQrDR+Kd3qhYqSlWx26nzParCQbo4lzSgzLfhvFuFfptnPW9PpoORzjQYdGynD6z0ngZt85g8Us8wBn04bnEgDJWuVarKFEnb.9F01kPwH+zsdjKeQ0r6KlT75iLhLWSQNk4aGMuW7+7MuOIWGTtQ1GgI7184S4w4qXHa5xTLXvaJSU74qg5ZCa51.pc0AlFwFq1edAwMrQqsDqEFTGL0Qt3OgewLqNrYdAypCYpYObq.rE+r7NZ8hXpniN4LotvXBtpozAvLOBSpfA7rLn1GZNDpREsPSe11LwXIF5U.o2k8P7.whkfEeCIdgkjyghMNxp+FR7heQf8nYgFZzaQbi+l5tFMt6QqG5PXGEir1rmv3GItQymRB3GssKy9DHF4QvtIjMMUoaFkJFjvWxEtbzA5svzZk0p7TzoZMB8bI1PLUD40NG3VVEbUUA2pSyfa0pYAb2QEbqoBt6NUCtLE4tuJ3tmJ3dvzL3VKSQt5pfqlJ3ZLUCtLE41VEbapBtcllA2syTjaWUv8spfauoZvkoH2mpBtOQEbe1zL3VNSQtanBt4UA2WLUCtLE4VTEbeoJ3t4TcQ7wE4dczT0qi2QejsO6w1QyeKZeaVIEnwMpzEWxnoXsY0geCGQCm8INjGaaKlL3qf9UFuF2J2Zrbt0Xkbqwp4Vi0xsF2N2ZbmIng3SEtdHm0OZNQfPqMi5sVeyy5stn1eA70uDRO
What I'm trying to do is call a function in a Samplers midi processor from my main UI script, but clearly I dont know what I'm doing.
How do I reference(call) functions in my samplers midi processor?
While we are here...
As you will see this example is a lot of brute force(there's a MidiMuter at the top of the Sampler) approach to controlling how (and when) a Sampler plays a note, so I'm stopping all midi notes arriving a the Sampler - clearly I would like it to be more nuanced than this - say stopping only notes that are not in the user-selected key - so what I need is ignoreNote() but I cant find it in the on-line or in-app documentation.. is there such a thing?
Edit: noteOff() wont work I think because it will play the release of the note...or am I (as usual) wrong about that?
Edit again: Oh hang on ignoreEvent is in Message? - woah...
-
@Lindon I wanted this same functionality (calling a function in another script) when I first started with HISE, I had a KSP way of thinking. Although it is possible using Global variables (I think) I have found there are usually better ways to do things in HISE and I have never needed this functionality since. (I'll take a look at your script now and see if I can suggest anything).
Since you only want to mute on certain notes you'll want to write your own MIDI muter.
ignoreEvent()
is correct, you'll want to place it in an if or switch statement probably for your purposes. -
I think it's good practice is to defer all callbacks in your UI script, this has no benefit unless you are updating the UI from within a MIDI callback but it I've found that it puts me in a different mind set when I know I can't do any real-time stuff in the UI script. It encourages me to separate the different jobs into dedicated scripts.
I need a bit more context for what you're trying to achieve in order to make some useful suggestions. So far it just appears you want to trigger a specific note in the onNote callback.
-
@d-healey thanks, yes I have the igonereEvent process working now - its just that I dynamically want to set the (replacement) note to be played. So I assign a variable to my Sampler or I'm trying to - mybe my OO background is getting in the way _ I think that there should be some level of encapsulation in a Sampler - it should have its own variables and functions - and I should be able ot call these functions from somewhere else... how is that bad practice?
and..
So far it just appears you want to trigger a specific note in the onNote callback.yes lets start with that.
-
I think that there should be some level of encapsulation in a Sampler - it should have its own variables and functions - and I should be able ot call these functions from somewhere else... how is that bad practice?
Samplers don't have variables. MIDI processors have variables which are encapsulated, and Samplers can have MIDI processors. If you want several MIDI processors to share a bunch of variables you could use a global object (I think) and just use it for those samplers (in reality any script could access it but in practice you would be able to treat it like a namespace for specific MIDI processors).
So far it just appears you want to trigger a specific note in the onNote callback.
Why does the UI script need to be involved in this?
-
@d-healey
"Why does the UI script need to be involved in this?"-- Because the end user will decide which note gets played....the sampler will hold a set of "enhancement sounds" that get played alongside the melodic/tonal component. So the UI will need to "tell" the sampler which note the play.
-
@Lindon said in Calling functions in midi processors...:
-- Because the end user will decide which note gets played....the sampler will hold a set of "enhancement sounds" that get played alongside the melodic/tonal component. So the UI will need to "tell" the sampler which note the play.
This is like my early KSP influenced thinking ;) You need to seperate the user's interaction with the UI from the MIDI logic. Your user will change a setting on the UI script and your UI script needs to change the same setting on the sampler's MIDI processor so it can do it's job, and you can probably connect this up using parameter IDs in the interface designer rather than scripting it.
So you have to think of everything as a module and then you link those modules together. It does mean that in some instances you'll be duplicating GUI controls but it's not really any different to duplicating variables and it's much faster to implement.
Here's a little demo
HiseSnippet 1268.3oc4X8zaaaCEmJNJs1KqXsKG1kAHTrAjhkUXmljtggg3Dm+.iVmXXkVraELRz1DQhTfhJKtE61tsuKC69NrcaeG1s8MneC1djRxhNSH0JnqqqyGBHe78H+w2e36mReA2iDGyEHq5mLIhfrV11cBSNtyXLkg5tGx5V18vwRhvIUztShvwwDejkUsCUBrpuHR+6kauKN.y7HEhPnmxodjGSCoxBo8a+HZPvAXexIzPCs2ncWONqCOfm.3olcSTD16L7HxQXkZKXirVZeepjKbkXIIFYs3tb+Iti4eKKU+mRiomFPTSZgbgMJU7A7.eEhUiQcFSC76meuiQHK69EdgZodgUr6Q8oSkW3M9.8BNEVX5OrV3pfWqqI7rLf2hov611tdBZjrXEE1dO6tLHPMDCg.SXkpKx5ms6vAEXx6GhOibf.lL0fU2pYy0b1rYy68UCSXdRJm4vYGwkjiYqduFunQ8FeWiKuxvgksj5PD7f.hnrUUgbwUX1prjvSIh0bNGGjPx0Ct4y5ZWZ9bsdoWXCE4rtLp73HR17BmeqRb9nLOlJLjAPPUoNHbqrffa.0mHPTXStg8iX7SagzX2rL.8jt6gk37sA1Q3ThHBIUcYr1ibNTljFaqauGI9LIORqaXDmoNeqkdkG5EPlr0uCm0D0fe.FDkeS5Bp8gYVVj61BpuDPoEjBz0XeP+87MHqm6mDfkyVJnp+yV.hgyjyoRrXwT4Dy2GpP8QyRqOJMDMmv8118oRuwki2EJAuPv5eZ7l8Zy6au+vgDOYAXWz9fu459zx0CJebJTtisqTPvgT1HWbXDTDqwSC6rYsdcz.HZta.zWPB3XeW5yMT6WauaB3uDyJ8mZqOpcB4IrYNqLjOfDQvRH7aXyMaOXvgBdRzks5kaqSVNQ.Mf.Wg4BGyHfeWZdG6H3wwCgqiduhMWpehXjxWUHY.4bhHdVYGkDBwdFiDDqpcsTOXDSTwZpWOrTPuvTa8oz7DrNd+o1quw8m824GC+Y3moF9kczySMoU0MY8paxCptIaTcS1r5lrU0M4gUxjzDsd3HUEihsxk5Yci4isBrA8wPpfQ08tzQS27TIy9zqgpSyE0P23zJgYwRuiP7orVakQ.52rgmWhk.0BgitWmyW6jSIB66qDs5c0Kb20b.5P+WgLTiWWjgxuj4RZhld4LEUboLkpuLknVgn2l4Ws77wuBkyuRMHVNQ4kWRq.Jj56GP5yAVDJ1EEsL9E3ymhxaV8hU9wC+im+8aGZ14DgBwWX1jIFZvodzGdEYHMHLFZAD0MD9THUGZn0fiOYHNIP5DCsmPAT1YD+S3Z8eyQeq17wA4UTYWOGitT0Kb6yNGZ4CRTX7NPrReOykNaccONiGMlyndy1fE7ViFQDlXuzKzNRIzeuPxJsGPBH3XiTqOo8ioLBVLKugJ4KZM+9hqJd8Q1ov0QUm47tAs6Z+um18U45tUFoaG3zEx2xiyKaqYL4nX0+uETGvSj.a8bFy1.sZW3SI7HljqWP00Icdy7GxcILe8j+D9ksXqbl3pEakuHxKeqf6V1XcmGqZDlhwk9qIC.N9AlozFum+FAkgXOA+YdocTUX8lZI.JY5+WZ0s6ol6LsUpx6BMvnOyySUF74sPnxsX8JawCprEaTYK1rxVrUks3gU1hu3JrPwldmDIOL8QQPP+8SSjr1eZhTMzeAbjOzNO
-
This is back from my early days with HISE when I wasn't familiar with the modular paradigm and was asking a similar question. Also seems like you were around then too - https://forum.hise.audio/topic/46/calling-child-functions
-
You could store all required info for the samplers in global variables and act on that information in the specific samplers midiprocessors.
-
@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