# Undocumented control params



## tonewill (Oct 31, 2011)

Hello All,
It's a real pain making scripts backward compatible with K3.5. Having no control ids is causing a lot of hassle at the moment. I'm just wondering against all odds whether there is any undocumented method of getting an id for a control in V3.5. Or any other interesting things for that matter.

I thank thee,

Barry.


----------



## mk282 (Nov 2, 2011)

I don't think so. This was introduced in K4.


----------



## Big Bob (Nov 2, 2011)

Yes indeed. Control IDs have opened up a lot of code simplification possibilities. Before their introduction, the only rough equivalent was to use a lot of lengthy select case constructs because every control had to be addressed by 'name' for each type of operation to be performed. :cry:


----------



## tonewill (Nov 2, 2011)

Thanks a lot Bob, I expected as much.

One other thing I've been wondering: Is there a way to trigger a control callback from a script? Now you probably want more info :wink:. You can assign a CC to a control to control it. When you do so any code in your callback is executed. However, if someone changes the CC then that would mess things up.

If however you set a knob position (say) from your script the code inside the callback isn't executed, so you have to move it from on ui_control() to a function and call that. Now you call your function from on ui_control() and soon you have lots of additional function plus the original callbacks.

I expect you'll say it isn't possible (if I made sense at this late hour when I should be in bed), but it's worth asking.

I thank thee,
Barry


----------



## Big Bob (Nov 3, 2011)

> If however you set a knob position (say) from your script the code inside the callback isn't executed, so you have to move it from on ui_control() to a function and call that. Now you call your function from on ui_control() and soon you have lots of additional function plus the original callbacks.



Hi Barry,

The problem you are describing has been with us for some time. When a change in a control's value requires a fair amount of algorithmic code to condition or format it properly, formerly, we would collect this code together in a KS function. But, of course, the problem is that this KS function needs to be referenced from multiple places and thus increases the overall script size.

The way we used to handle this situation when the needed code was rather lengthy was to use a form of pseudo subroutine calling (or task triggering) using the old play_note 0 triick. However, with the introduction of KN functions (native Kontakt user functions) with K4, the solution is much simpler. Specifically, code your KS functions as KN functions and then you can actually 'call' them from multiple places with very little code increase.

Unfortunately, one of the places this kind of UI function often needs to be called is during initialization and KN functions cannot be called from the ICB. However, there is a simple work-around for that. We simply setup a post-initialization scheme using the pgs callback. The last step of the ICB is to set a flag and then alter a PGS variable. Then, as soon as the ICB exits, the pgs callback will be triggered and the first such triggering of the pgs 'sees' the post initialize flag is set and thus can execute any KS routine of your choosing. After executing this post-initializtion routine, the flag is turned off so this routine will never execute again.

The post-initialize routine can contain any valid KSP code including KN function calls.

So, the short answer to your question is: 'Use KN functions' :lol: 
ie unless I again misunderstood the question :wink: 

Rejoice,

Bob


----------



## tonewill (Nov 3, 2011)

Thanks again Bob. What you describe is what I am doing including using PGS to carry out any post init chores. It would just be nice to be able to 'call' a 'ui_control' callback directly, but that's not to be.

Thanks again for all your help,

Barry.


----------



## mk282 (Nov 3, 2011)

You can write the action carried out in the UI callback as a function, then call it in that UI callback, or wherever else you might need it.


----------



## Big Bob (Nov 3, 2011)

mk282 @ Thu Nov 03 said:


> You can write the action carried out in the UI callback as a function, then call it in that UI callback, or wherever else you might need it.



Daaah! Isn't that what I said? :?



> However, with the introduction of KN functions (native Kontakt user functions) with K4, the solution is much simpler. Specifically, code your KS functions as KN functions and then you can actually 'call' them from multiple places with very little code increase.



Maybe the above was too buried in the rest of the discussion? :lol: 

Rejoice,

Bob


----------



## tonewill (Nov 3, 2011)

Big Bob @ 3rd November 2011 said:


> mk282 @ Thu Nov 03 said:
> 
> 
> > You can write the action carried out in the UI callback as a function, then call it in that UI callback, or wherever else you might need it.
> ...





ME said:


> If however you set a knob position (say) from your script the code inside the callback isn't executed, so you have to move it from on ui_control() to a function and call that. Now you call your function from on ui_control() and soon you have lots of additional function plus the original callbacks.



Actually, I said it first :lol:.

If it were possible to call the callback directly, you could save a long list of unnecessary functions in KScript, that's all. Wasn't a problem as such just seeing if it were possible.

Thanks though, much appreciated.


----------



## Big Bob (Nov 3, 2011)

Hi Barry,

As usual, I guess I answered the wrong question again :oops: 



> If it were possible to call the callback directly, you could save a long list of unnecessary functions in KScript, that's all. Wasn't a problem as such just seeing if it were possible.



I'm still not exactly sure what you mean by a long list of unnecessary functions because it seems to me that if the ui callback handler is anything but trivial, you would want to modularize it anyway. I never thought that reducing the number of functions was the objective but rather I thought you wanted to reduce the overall number of compiled lines of code fed into K4.

I guess then that you just don't like to have a lot of functions even if they result in more readable and ultimately more compact code? I'm just the opposite, I modularize almost everything. Of course the way one divides the code into functions has a lot to do with its ultimate readability so I suppose one can overdo modularity.

Now as to what was apparently the central issue of your post, namely, triggering ui callbacks from the script, let me think on that a little and see what comes out of the tree when I shake it. :lol: 

Rejoice,

Bob


----------



## tonewill (Nov 3, 2011)

> Now as to what was apparently the central issue of your post, namely, triggering ui callbacks from the script, let me think on that a little and see what comes out of the tree when I shake it.


Really? That sounds interesting, I'll keep watching!

By the way, sometimes I ask something just because I'm interested in finding out what can and can't be done, I don't necessarily have an urgent problem, and often, as in this case, know how to get around it. I know that you're like that also because I've read a lot of your posts and some of your PDF reports.

Barry.


----------



## Big Bob (Nov 4, 2011)

> By the way, sometimes I ask something just because I'm interested in finding out what can and can't be done, I don't necessarily have an urgent problem, and often, as in this case, know how to get around it.



Yes, I finally caught on to that. :oops: 



> I know that you're like that also because I've read a lot of your posts and some of your PDF reports.



Indeed, curiosity (rather than necessity) is truly the 'mother of invention' :lol: 



> Really? That sounds interesting, I'll keep watching!



Unfortunately no fruit fell out of the tree when I shook it :( 

You might be able to utilize your idea of using cc automation if there was some way to distinguish when a control was changed with the mouse and when it was changed with a set_controller. However, even if you could come up with some way to do that, it's hard to see how that would result in anything superior to using callable KN functions and therefore, the motivation for finding a triggering technique is not too high. But, I'll move it to the back burner and if an idea ever pops into my head, I'll let you know.

Rejoice,

Bob


----------



## tonewill (Nov 4, 2011)

Thanks a lot Bob, the more I think about it, the more I've come round to your way of thinking anyway. Use functions.

While your there Bob, I'm using your ATFade function to control the on_change volume from several sliders who's min/max ranges are set to 0,127.

I'm using rng = 50%. Can I use any of your functions to then convert the value to dB (for displaying)? I couldn't work out how. I hope you don't mind me asking here but it doesn't seem right to start a new thread directed at you.

Thanks for any help,
Barry.


----------



## Big Bob (Nov 5, 2011)

Hi Barry,

This should be easy to do since the output of the *ATFade* function, *atn*, is already in mdb. You can either display it directly and append ' mdb' or, if you actually want it in db, you can use* D.FmtVal*(atn,3,@str) and then append ' db' on @str.

Of course I am assuming that you are using *atn* to control volume in the correct way. If you aren't, then you will need to explain how you are using the *atn* output of *ATFade* to control volume before I can see if you need any additional math to display it properly.

Rejoice,

Bob


----------



## tonewill (Nov 5, 2011)

Big Bob @ 5th November 2011 said:


> Hi Barry,
> 
> This should be easy to do since the output of the *ATFade* function, *atn*, is already in mdb


Oh yeah :oops:. What was I thinking?

Anyway, I'd better check I'm using it in the right way. cv is a value between 0-127. rng is set at 50%. If cv = 0, atn := Muted. atn is used directly in a change_vol() function. 

Thanks Bob, sorry for missing the obvious!

EDIT: I'm currently using V105 of your library because I'm working on a Kontakt v3.5 project.

EDIT 2: Just looked at D.FmtVal from V403 of your library, managed to extract the relevant code (hope that's okay) and get it working in K3.5. Regarding the fractional part, how could I modify the code (again, if that's okay to do) to have just one digit after the decimal point like the native Kontakt group volume control? I need to fit it into an 'old-style' Kontakt Knob label.

Don't worry if you haven't got time for this, I know I've asked a lot of questions the last couple of days.

Many thanks,
Barry.


----------



## Big Bob (Nov 5, 2011)

> Regarding the fractional part, how could I modify the code (again, if that's okay to do) to have just one digit after the decimal point like the native Kontakt group volume control? I need to fit it into an 'old-style' Kontakt Knob label.



Why don't you just divide atn by 100 first and then use D.FmtVal with one decimal?


```
D.FmtVal(atn/100,1,str)
```

or if you want a little better approximation, use rounding, ie (atn+50)/100.


```
ATFade(x,y,atn)
  fatn := (atn+50)/100
  D.FmtVal(fatn,1,str)
  set_text(show,str & ' db')
```

Rejoice,

Bob


----------



## tonewill (Nov 5, 2011)

Thanks a lot Bob, I admit I'm not too good at mathematics, I didn't think to try that. The 'resolution' isn't great of course because I'm only using input values of 0-127 rather than engine parameter values of 0-1000000 so I can't set it to exactly -6dB for instance. Still, it's working well enough, thanks for all your help and I'll give you a break now :wink:.

Thanks again,
Barry.


----------



## paoling (Nov 6, 2011)

Regarding your original question what about using just one KN function, a control variable and select case?
You set the variable for the control you want to modify, then call a function named update_controllers, then in the function you use a big select to perform the action associated with the control variable. In this way you can just use one function...


----------



## Big Bob (Nov 6, 2011)

Hey Paolo,

Please note my original response in which I also alluded to what you are suggesting:


> Before their introduction, the only rough equivalent was to use a lot of lengthy select case constructs because every control had to be addressed by 'name' for each type of operation to be performed.



In the days of K2, that's the only way in which a rough equivalent to indirect addressing could be accomplished. While this method can be made to work, keep in mind that you need a select-case construct for every operation type that you might need to use for the controls, not only for changing their value. Things like whether they are hidden or not, where they are positioned, etc. And, if you have 50 controls or so, it gets very verbose indeed.

Thankfully, Control IDs have largely solved most of these problems.

Rejoice,

Bob


----------

