ksp

Last modifiedby & filed under Kontakt Scripting (KSP) - Basics, UIs, Tutorials, Scripts and Tools, Kontakt Scripting (KSP) :: Basics.

The Basic code structure is very simple. We basicaly put most of our code into  callbacks

All callbacks look like this on <callback> ... end on

In general the code inside callbacks gets executed when specific events happen. For example playing a note on our keyboard always executes the “on note” callback.

So callbacks build a framework for our instrument and are mostly needed to communicate with different parts of the Kontakt engine.

Imagine it like that: an event triggers the related callback which is executing all our code inside it. Thereby sometimes the same callback can be called multiple times. For example playing 2 notes on our keyboard will execute 2 instances of the on note ... end on callback.

There are more callbacks as introduced in this article but with the ones introduced here we can already create awesome instruments.

Note: some commands & constants can only be used inside specific callbacks. For example the  wait() & purge() command can’t be used inside the init callback.

on init […] end on

the on init callback gets executed automatically on every start of our instrument. It also gets executed when hitting the apply button, when loading snapshots or when restarting the Kontakt engine (panic button).

The init callback will be the starting point for most of our scripts. Because inside on init ... end on  we have to put in all the initial code (like variables, ui elements, etc) we are even only allowed to declare new variables, arrays and UI controls (knobs, buttons, menus,…) here.

So the init callback is probably the most used callback and part of most of our scripts.

Example: simple init

on init
   set_ui_height_px(540)
   make_perfview
   declare ui_switch $switch
   declare ui_knob $knob (0,1000000,100)
   make_persistent($knob)
   message ("")
end on

on note […] end on

this callback is executed when we play a note. Several instances can be called at once when we play multiple notes on our keyboard.

We can use it to trigger other events whenever playing a note (like led lights for our ui) or of course we can use it to manipulaute the played notes themselves.

For example we can create a round robin application for more realistic instruments or we can create simple intervals & chords, like in the example below.

Example (this will add two additional notes, creating a chord)

on note
   play_note($EVENT_NOTE+4,$EVENT_VELOCITY,0,-1)
   play_note($EVENT_NOTE+7,$EVENT_VELOCITY,0,-1)
end on

on release […] end on

same as on note but executed when releasing a key

on ui_control(<variable>) […] end on

gets executed when using the assigned UI element (knobs, buttons, switches, menus etc.)

To assign an ui element we simply have to put its variable name after on ui_control (but remember first declare the ui elements inside the on init).

We can assign any variable we want like this

on init
  make_perfview
  declare ui_button $MySuperButtonToControlTheWorld
end on


on ui_control ($MySuperButtonToControlTheWorld) 
  {our master piece of a code waiting to be executed when pushing the button}
end on

For each of our already declared controls we can add an individual on ui_controlWe can add as many on ui_control .. end on callbacks as we want.

Once we have assigned an ui element we can then use the on control callback to control almost anything we want with our custom ui (we will learn more about this later on).

(of course you don’t wanna use that long variable names unless you like wounded fingers)

In general we use the on ui_control to adjust engine parameters like FX settings (e.g. reverb time, attack time, filter cutoffs etc.). But we can also use it to change other settings like UI behaviors, or to activate other functions, to play a note, midi files and many more.

Example – this sets the attack and release time of an AHDSR, named “ENV_AHDSR”:

on ui_control ($attack)
   set_engine_par($ENGINE_PAR_ATTACK, $attack, $group, find_mod($group,"ENV_AHDSR"), -1)
end on

on ui_control ($release) 
  set_engine_par($ENGINE_PAR_RELEASE, $release, $group, find_mod($group,"ENV_AHDSR"), -1) 
end on

NOTE: You can find a full list of all callbacks in your KSP reference manual.

How useful was this article?

something you didn't like? Please tell us before you rate!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

NOTE: highly negative votes may be removed without any reasonable given feedback!

Tell us how we can improve this post?

8 Responses to “KSP Scripting (NI Kontakt) :: BASICS :: Callbacks & Basic Structure”

  1. Dave

    Is there a way to load a group in the on init callback? I have made an instrument with 5 groups. For each group in the group editor I have set Group Starts: on key "if key is between" and provided a single key for each group When I load up my instrument no group of samples will play until I press one of the keys that I have specified in the group start settings. What I would like to do is have one group available to be played when load the instrument. I cant seem to find a way to do it via the on init function. Am I missing something obvious?

    • YummyBeats

      You can do this via a status array since the allow_group command is only allowed inside the on note callback.
      Try this. C1,D1,E1 enables group 0,1,2 where F1,G1,A1 disables them again.

      Edit: sorry I missed the important part. I've updated the script. You can set a default active group now inside the on init

      Note: This will layer all activated groups
      on init
      	{SETTINGS}
      		declare const $NUMBER_OF_GROUPS := 3	
      		declare $active_group := 0 { set to -1 if no group should be active on init }
      	
      	{GLOBAL VARS}
      		declare %allowed_groups[$NUMBER_OF_GROUPS]
      		declare %hot_key[$NUMBER_OF_GROUPS]
      		declare %cold_key[$NUMBER_OF_GROUPS]
      		declare $i
      
      	{ set midi note numbers for enabling keys C1, D1, E1 }
      		%hot_key[0] := 36
      		%hot_key[1] := 38
      		%hot_key[2] := 40
      
      	{ set midi note numbers for disbaling keys F1, G1, A1 }
      		%cold_key[0] := 41
      		%cold_key[1] := 43
      		%cold_key[2] := 45
      
      	 {set key color hot & cold}
      	 	$i := 0
      	 	while ($i < $NUMBER_OF_GROUPS)
      	 		set_key_color(%hot_key[$i], $KEY_COLOR_RED)
      	 		set_key_color(%cold_key[$i], $KEY_COLOR_BLUE)
      	 		inc($i)
      	 	end while
      
      	{ deactivate all groups }
      		$i:=0
      		while ($i < $NUMBER_OF_GROUPS)
      			%allowed_groups[$i] := 0
      			inc($i)
      		end while
      end on
      
      on note
      	disallow_group($ALL_GROUPS)
      	message("")
      
      	{activate group by key}
      		$i := 0
      		while ($i < $NUMBER_OF_GROUPS)
      			if ($EVENT_NOTE = %hot_key[$i])
      				%allowed_groups[$i] := 1
      				message("group " & $i & " enabled")
      				$i := $NUMBER_OF_GROUPS {breaks the while loop}
      			end if
      			inc($i)
      		end while
      
      	{ activate group by default}
      		if ($active_group # -1)
      			%allowed_groups[$active_group] := 1
      		end if
      
      	{ deactivate group by key}
      		$i := 0
      		while ($i < $NUMBER_OF_GROUPS)
      			if ($EVENT_NOTE = %cold_key[$i])
      				%allowed_groups[$i] := 0
      				message("group " & $i & " disabled")
      				$i := $NUMBER_OF_GROUPS {breaks the while loop}
      			end if
      			inc($i)
      		end while
      
      	{ only allow group when %allowed_groups[this] = 1 }
      		$i := 0
      		while($i < $NUMBER_OF_GROUPS)
      			if(%allowed_groups[$i] = 1)
      				allow_group($i)
      			end if
      			inc($i)
      		end while
      end on
      

      • Dave

        Thanks you so much! This example works. Seems a bit wild to me that loading a group on init requires this much code but I suppose that's Kontakt for you. lol Now all I have to do is figure out how to layer in disallow groups because I dont want them to be layered but only one group active at a time. Cheers.

        • YummyBeats

          Yeah KSP often means "find a workaround" :)
          But try this, I cleaned up the code a lot and modified it to your needs. Only one group is playing at the same time now.
          Cold Keys and loops are not required here which also saves some lines of code.

          on init
          	{SETTINGS}
          		declare const $NUMBER_OF_GROUPS := 5	
          		declare $active_group := 0 { set to -1 if no group should be active on init }
          	
          	{GLOBAL VARS}
          		declare %hot_key[$NUMBER_OF_GROUPS]
          		declare $i
          
          	{ set midi note numbers for enabling keys => C1, D1, E1, F1, G1 }
          		%hot_key[0] := 36
          		%hot_key[1] := 38
          		%hot_key[2] := 40
          		%hot_key[3] := 41
          		%hot_key[4] := 43
          
          	 {set key color}
          	 	$i := 0
          	 	while ($i < $NUMBER_OF_GROUPS)
          	 		set_key_color(%hot_key[$i], $KEY_COLOR_RED)
          	 		inc($i)
          	 	end while
          end on
          
          on note
          	disallow_group($ALL_GROUPS)
          
          	{ get current allowed group }
          		if(search(%hot_key, $EVENT_NOTE) # -1)
          			$active_group := search(%hot_key, $EVENT_NOTE)
          		end if
          
          	message($active_group) {console output}
          	allow_group($active_group)
          end on
          

          • Dave

            HA! Well at least its fun....So, I haven't tried your solution yet (stuck at day job) but this is exactly what I was thinking to try when I got home. Disallow groups at the start of the on note and then just enable after. Perfect. Thanks again!!!! Will try out your code when I get home.

  2. Serge

    Hello! To call a sound group on my instrument I use "purge_group()...". All is OK until I want to launch the sound from my keyboard controller button - all status changes are performed correctly, all indications are working fine, but no sound on output, because "on controller" callback doesn't allow any "purge_group()..." or "allow_group()...". The "on ui_control()..." doesn't react on changes that are performed. Could You help me to solve this problem - how to realize sound launch from controller button? Tested with different keyboards, the same problem every time - indications are working in proper way, but sound can't be launched. I use KONTAKT 6.0.3. Thanks in advance for Your reply. Best regards, 02/01/2019 Serge

    • YummyBeats

      hey, all I can think of right now is a workaround. If you train a slider with your preferred midi controller and save your nki, the assigned midi controller will be stored as well.
      So this is what you could do:
      1. Add a slider, make perfview
      2. exit edit mode
      3. learn midi automation with right mouse click on the slider (I used the Mod Wheel)
      4. save your nki
      5. close Kontakt and reopen your nki
      6. Hide your slider via $CONTROL_PAR_HIDE
      7. save your nki again
      Here is an example:
      on init    
      	declare ui_slider $button (0,1)
      	$button := 0
      	{set_control_par(get_ui_id($button),CONTROL_PAR_HIDE,$HIDE_WHOLE_CONTROL)} {learn midi automation => save nki => hide button-slider => save nki again}
      	make_perfview
      	message("")
      end on
      
      on ui_control($button)
      	if($button = 1)
      		purge_group(0, 1)
      		message("group 0: samples loaded")
      		else
      			purge_group(0, 0)
      			message("group 0: samples unloaded")
      	end if
      	wait(1000*1000*2)
      	message("")
      end on
      

      • Serge

        Hello! Thanks a lot for Your feedback. Your proposal has been tested today with both knobs & sliders versions, working fine. Especially useful, if some earlier programmed buttons can't be learnt by soft. NOTA => please, take into account, that while using the "select()..." function, several cases/situations can be appointed to the same one slider. Big thanks once again, wish You all the best! 03/01/2020 Serge.

Leave a Reply to Dave Cancel reply

use <pre> </pre> to wrap code blocks

use <code> </code> to wrap small code snippets

use basic html to style your comment

Your email address will not be published. Required fields are marked *