# Knobs and Sliders together?



## mus_student22 (Dec 18, 2018)

I have been doing fairly okay with all of this, except for my teacher wants me to figure out how to link a knob to a slider in kontakt 5 and ive read every article, my KSP manual. im simply lost on what to do. This is for a grade so the sooner the better thank you so much!


----------



## Fredeke (Dec 19, 2018)

Something like this ?


```
on ui_control ($mySlider)
  $myKnob := $mySlider
end on
```


If you want the link to be bi-directional, then also add:


```
on ui_control ($myKnob)
  $mySlider := $myKnob
end on
```


That's provided the knob and the slider have the same min and max values, of course.
Otherwise there will be some scaling to do (which is left as an exercise to the student  )


----------



## Fredeke (Dec 19, 2018)

Ok, I finally did it myself. 

Here's a code providing bi-directional link between a knob and a slider which have different min and max values :


```
on init


  { set up min and max values for the controls }
 
  declare $knobMin := 0     {these are example values}
  declare $knobMax := 127
  declare $sliderMin := 16
  declare $sliderMax := 31


  { create the controls }

  declare ui_knob $myKnob ($knobMin, $knobMax, 1)
  declare ui_slider $mySlider ($sliderMin, $sliderMax)


  { calculate offset and ratio needed to adapt one control's range to the other }
 
  declare $kRange
  declare $sRange
  declare $offset
  declare ~ratio
  $sRange := $sliderMax - $sliderMin
  $kRange := $knobMax - $knobMin
  $offset := $sliderMin - $knobMin
  ~ratio  := int_to_real ($sRange) / int_to_real ($kRange)

 
end on



on ui_control ($myKnob)
  $mySlider := real_to_int (int_to_real ($myKnob) * ~ratio + int_to_real ($offset))
end on

on ui_control ($mySlider)
  $myKnob := real_to_int ( (int_to_real ($mySlider) - int_to_real ($offset)) / ~ratio)
end on
```


Note : The math gets clearer if you strip away all the _real_to_int_ and _int_to_real_ commands. Unfortunately, they are needed for the script to work because KSP is a rather rigid language, that can't convert real numbers into integers (or vice-versa) on the fly.

Also note : This should work with any min and max values (even negative ones), as long as each control's maximum is greater than its minimum. I honestly don't know what would happen with inverted controls.
*
[EDIT: @mus_student22: Do not use this code ! I just realized my math was wrong and only works in some cases. I am currently trying to correct it, and will post the correct code soon]*


----------



## EvilDragon (Dec 19, 2018)

Those min/max values should be constants if you want to actually be able to declare controls...


----------



## Fredeke (Dec 19, 2018)

@EvilDragon is right. This should be necessary :


```
declare const $knobMin := 0 
  declare const $knobMax := 127
  declare const $sliderMin := 16
  declare const $sliderMax := 31
```


(Note the _const_ prefixes)

However, the previous script did work in my version of Kontakt (5.7), despite the error.
That's surprising, because KSP is not exactly a forgiving language.
(And no, I wasn't compiling with SublimeKSP)


----------



## EvilDragon (Dec 19, 2018)

Also your scaling is not working if $knobMin is a different value from 0.


----------



## Fredeke (Dec 19, 2018)

Ok, I finally got the math right !

This should work with any combination of positive or negative min/max values, and it should also work with either or both controls being reversed (that is, with a minimum greater than the maximum) :


```
on init

  { set up min and max values for the controls }
  declare const $knobMin := 0        {these are example values - try different ones :) }
  declare const $knobMax := 127
  declare const $sliderMin := 0
  declare const $sliderMax := 10

  { create the controls }
  declare ui_knob $myKnob ($knobMin, $knobMax, 1)
  declare ui_slider $mySlider ($sliderMin, $sliderMax)

  { declare buffer variable ( for short-term storage ) }
  declare ~relative_pos

end on

on ui_control ($myKnob)
  ~relative_pos := int_to_real ($myKnob - $knobMin) / int_to_real ($knobMax - $knobMin)
  $mySlider := $sliderMin + real_to_int (int_to_real ($sliderMax - $sliderMin) * ~relative_pos)
  message (~relative_pos)
end on

on ui_control ($mySlider)
  ~relative_pos := int_to_real ($mySlider - $sliderMin) / int_to_real ($sliderMax - $sliderMin)
  $myKnob := $knobMin + real_to_int (int_to_real ($knobMax - $knobMin) * ~relative_pos)
  message (~relative_pos)
end on
```


Note: no instance of _message (~relative_pos)_ is really necessary, but they help understanding what the script does by displaying the relative position of each control within its own boundaries (in Kontakt's status bar).

You can also use a display ratio other than '1' for the knob.


----------



## polypx (Dec 19, 2018)

The teacher is totally going to realize the student didn't write this


----------



## mus_student22 (Dec 19, 2018)

That’s okay, he didn’t even know how to write it 
Thank you guys so much!


----------



## Fredeke (Dec 20, 2018)

Anyway, if the complete version is too elaborate, you can still use my very first answer to your question. It's very simple and is probably what your teacher's expecting, but it only works when knob and slider have the same minimum and maximum.


----------



## Fredeke (Dec 20, 2018)

Oh, by the way, I noticed a typo in my code. 

On this line :
~relative_pos := int_to_real ($myknob - $knobMin) / int_to_real ($knobMax - $knobMin)

$myknob should be $myKnob. I don't know if KSP is case-sensitive, but just in case...

I've corrected my previous post, but if you already copied the code, you should correct this.
Sorry


----------



## EvilDragon (Dec 20, 2018)

KSP is not case-sensitive regarding variable names.


----------



## Tod (Dec 23, 2018)

Wow, ha ha, thanks Mario, I wasn't sure about that, is that a blanket statement? What about the internal variables?


----------



## EvilDragon (Dec 23, 2018)

Those are constants, not variables (yes the KSP reference is wrong on that account)  And they must always be all caps. If you try using $engine_par_cutoff it won't compile the script.


----------



## P.N. (Dec 23, 2018)

Tod said:


> What about the internal variables?





EvilDragon said:


> Those are constants, not variables (yes the KSP reference is wrong on that account)



Well, there's $ENGINE_UPTIME which is an internal variable and also case sensitive.

So i guess the rule is:
- Internal constants or variables (i don't remember other internal variables besides $ENGINE_UPTIME, id need to check the manual) are always case sensitive.
- Declared constants / variables are not case sensitive.

Right?

Edit: The ones that start with $NI are variables too... forgot about those.
I don't know how many are there.


----------



## EvilDragon (Dec 23, 2018)

There are a number of internal variables, but most are constants. Not all $NI_ things are variables either (mainly those for setting dropdown menu values, all of them are constants, like $NI_SYNC_UNIT_xyz, $NI_CB_TYPE_xyz, $NI_SIGNAL_xyz, etc.).

What I actually meant to say was that the manual is wrong to say "control/engine parameter variables". They're not variables, they're constants pointing to whichever control/engine parameter is about to be _modified by a variable_.  This is easy to test, too, just do message($CONTROL_PAR_X) or message($CONTROL_PAR_CUTOFF). The value won't change no matter what you do 



P.N. said:


> So i guess the rule is:
> - Internal constants or variables (i don't remember other internal variables besides $ENGINE_UPTIME, id need to check the manual) are always case sensitive.
> - Declared constants / variables are not case sensitive.
> 
> Right?



Yep! With added rule that, bizzarely enough, function names are case sensitive.


----------



## P.N. (Dec 24, 2018)

EvilDragon said:


> Not all $NI_ things are variables either (mainly those for setting dropdown menu values, all of them are constants, like $NI_SYNC_UNIT



I had the feeling i was forgeting those, even having declared countless menus with sync units...

I was refering to $NI_CALLBACK_ID and $NI_CONTROL_PAR_IDX (this last one i recently confused with a command constant... yes, now i know that's a variable too).


----------



## Tod (Dec 24, 2018)

I guess it really doesn't matter, for user variables I've never used the same variable name, one having caps the other one not. I do like caps though for identification, like Knb_Lbl instead of knb_lbl, although I'm sure it's just a personal thing.


----------



## Fredeke (Dec 27, 2018)

Also, my full-fledged code uses real numbers (as opposed to integers) which became supported somewhere in the 5.x version line (were not supported in 5.2 but were supported in 5.7 is all I can say).

The simpler code in post #2 of this thread however, should work even in more ancient versions of Kontakt.


----------



## Fredeke (Dec 27, 2018)

EvilDragon said:


> P.N. said:
> 
> 
> > So i guess the rule is:
> ...


KSP is a really weird language ! Seems come up with in a hurry, with no long term vision. But it kinda works, so...


----------

