Using functions

The KScript Editor contains a preprocessor which is a tool that goes through a text and perform certain substitutions and transformations to generate a new text. The purpose of this particular preprocessor is to convert Kontakt2 scripts that have an extended syntax that Kontakt2 cannot understand but is easier to work with for humans, to a syntax that Kontakt2 can understand.

The extension making scripting more human-friendly mentioned here, allows you to define your own functions. Hence, just like you can use built-in functions like play_note you can then also make your own functions. After you have specified what a function should do, you can use it like any other builtin script function. Using functions your scripts will become easier to understand since actions are given names, and you never have to repeat the same code twice since you can move such code inside a function and just invoke the function multiple times from different places in your program.

Well, here's an example of a simple function definition:

function play_octave($note, $velocity)
    play_note($note, $velocity, 0, -1)
    play_note($note+12, $velocity, 0, -1)
end function
Easy, right? As you see the format is the word function followed it's name (you decide this) and then a list of arguments that control what the function should do (decided on by you as well). The arguments look like variables, but they are really not, so you shouldn't declare them. Arguments are more like placeholders; they will later be replaced by whatever parameters you specify when you invoke the function. In this example the function play_octave is supposed to play a certain note at a certain velocity together with the same note one octave higher. This is how the function is used (just like any built-in function):
on note
    play_octave($NOTE_EVENT, $NOTE_VELOCITY)
end on

As you see, you can now call your function. What will happen is that the parameters - $NOTE_EVENT and $NOTE_VELOCITY - will replace every occurance of $note and $velocity. When you feed this script as input to the preprocessor it will give you this as output:

on note
    {begin play_octave($NOTE_EVENT, $NOTE_VELOCITY)}
        play_note($NOTE_EVENT, $NOTE_VELOCITY, 0, -1)
        play_note($NOTE_EVENT+12, $NOTE_VELOCITY, 0, -1)
    {end play_octave($NOTE_EVENT, $NOTE_VELOCITY)}
end on
This script code can then be pasted into Kontakt2 since the preprocessor has translated all things that Kontakt2 cannot understand to the regular script syntax.

Simple enough, but are functions really useful?
Well, the example above was primarily meant to be a simple introduction. You can do all sort of fancy scripts by calling functions from functions and as I said they are a good way to get rid of duplicate code and organize scripts better.

What about functions without parameters?
I think you almost guessed it. They look like this:

function init_declare_variables
    { some variable declarations here }
end function

function init_gui_controls
    { some initialization code here }
end function

on init
end on

Any gotchas?
Well, yes actually there's one. Consider this example:

function play_double_length_note($X)
    play_note(60, 100, 0, $X * 2)
end function

on note
    play_double_length_note($length1 + $length2)
end on
Output from the preprocessor:
on note
    {begin play_double_length_note($length1 + $length2)}
        play_note(60, 100, 0, $length1 + $length2 * 2)
    {end play_double_length_note($length1 + $length2)}
end on
As you can see only $length2 gets multiplied by 2. Hence, you will sometimes need parenthesis around expressions. In this case one should have used play_note(60, 100, 0, ($X) * 2) in the function.

What about returning values from functions?
Currently there's no support for this. But there's always the possibility to assign return values to a special variable (eg. $result) as a workaround.