Native Instruments Kontakt 3.0 Script Language

4.6 (5)
Native Instruments Kontakt 3.0 Script Language

Kontakt Script Language Manual

The Kontakt Script Language

1

Kontakt Script Language Manual

Copyright © 2006 Native Instruments Software Synthesis GmbH. All rights reserved.

Manual written by: Nicki Marinic, Josef Natterer, Wolfgang Schneider

Last updated: April 26, 2006

Please note:

When viewing this manual with Acrobat Reader, the underscore ("_") may not be visible.

It is recommended to view this manual at a higher zoom factor and/or to print it out, since the underscore is a very important character in the programming language.

Also, we included a copy of this manual as a raw text file, since when copying and pasting portions of this text (e.g. code examples) you might loose line breaks which results in incorrect code. Please use the raw text file for copying and pasting the script examples.

2

Kontakt Script Language Manual

Table of Contents

Introduction...................................................................................................................

5

Getting Started - the Kontakt Script Processor ..................................................................

6

Working with KSP and Scripts .......................................................................................

10

Basic Scripting Tutorial ................................................................................................

12

Generating MIDI notes: a simple accompanist .............................................................

12

Built-in variables: Building a simple Octaver................................................................

14

UI Control variables and the init callback: Creating a simple Harmonizer ........................

15

Debugging and customizing: finishing your script .........................................................

18

Fundamentals..............................................................................................................

25

General rules concerning the syntax............................................................................

25

Callbacks .................................................................................................................

26

Variables..................................................................................................................

26

Script Call Order .......................................................................................................

31

Tempoand time-based scripting ...................................................................................

32

The wait() function....................................................................................................

32

Polyphonic Variables .................................................................................................

33

Control Statements.......................................................................................................

34

if…else…end ...........................................................................................................

34

select() ....................................................................................................................

34

while() .....................................................................................................................

35

Operators ....................................................................................................................

36

Boolean Operators.....................................................................................................

36

Arithmetic Operators .................................................................................................

36

Bit Operators ............................................................................................................

37

Array Functions ........................................................................................................

37

Random Generator ....................................................................................................

37

Group Management ......................................................................................................

38

Events and Note ID's.................................................................................................

40

Changing Events .......................................................................................................

41

Grouping Events .......................................................................................................

43

Assigning Event Parameters .......................................................................................

44

3

Kontakt Script Language Manual

 

User Interface Controls .................................................................................................

45

Buttons....................................................................................................................

45

Knobs......................................................................................................................

45

Menus .....................................................................................................................

46

Text Labels ..............................................................................................................

47

Value Edit ................................................................................................................

47

Table .......................................................................................................................

48

Positioning of ui elements..........................................................................................

48

Hiding GUI elements.................................................................................................

49

UI Callbacks.............................................................................................................

49

Naming of GUI elements ...........................................................................................

49

Performance View .....................................................................................................

50

Usage of Midi Controllers ..............................................................................................

51

The Controller Callback .............................................................................................

51

Controller variables and arrays....................................................................................

51

Working with RPN and NRPN messages ......................................................................

53

Advanced Concepts ......................................................................................................

55

Preprocessor.............................................................................................................

55

Engine Parameter .....................................................................................................

57

Loading IR Samples ..................................................................................................

69

Specifying when persistent variables are read ..............................................................

70

Reference....................................................................................................................

72

1.

Callback types ......................................................................................................

72

2.

Declaration of variables and ui elements .................................................................

72

3. Functions.............................................................................................................

74

4.

Group and array functions......................................................................................

77

5.

Built-in Variables ..................................................................................................

78

6.

Slice functions .....................................................................................................

81

7.

Preprocessor.........................................................................................................

82

8.

Engine Parameters ................................................................................................

83

4

Kontakt Script Language Manual

Introduction

Welcome to KSP – the Kontakt Script Processor.

The Kontakt Script Processor is a unique feature in Kontakt 2. You can use it as an effect or composition tool, you can build custom instruments with intelligent processing through algorithms, create sequencers, exotic tunings and much more. But the best part of it is, you can program script modules yourself, share them with others, or modify and personalize existing scripts. This manual describes the usage of the script processor and the programming of scripts in the Kontakt Script language.

A programming language? But I'm a musician and not a computer geek!

Don't be afraid of such terms as "programming language" or "scripting"; this manual will give you a step by step approach, even (or especially) for the novices in computer programming. In fact you don't need to know anything about programming languages in order to benefit from KSP; even if you don't want to program yourself, you'll get an insight into the structure of KSP and can modify certain scripts to fulfill your needs.

As a serious musician, you will find yourself in situations where you need to solve a problem in a very specific way, whether you're a performer, composer or producer. A "problem" is anything where your imagination and creativity are restricted by the boundaries of a specific music program. With KSP, you can extend the already numerous possibilities in Kontakt2 and tailor your own modules.

But I AM a computer geek – do I need to read the whole manual?

If you do have experience in programming languages or in a programming environment like Reaktor, you'll probably want to step through the whole manual as fast as possible and start scripting. That's fine but please remember that certain commands are unique to KSP; you might want to have a quick look at the Reference and then read the chapters which look unfamiliar to you.

So I'm ready to start – what else do I need besides this manual?

Of course, you must have Kontakt2 installed on your computer, together with the proper Audio/Midi configuration. There's really nothing else you need, but you might find it convenient to use an external text editor to type in your scripts. This of course can also be done in Kontakt (and is much faster for small scripts), but for larger scripts we recommend using a text editor, e.g. BBEdit on OS X or Ultraedit on Windows.

5

Kontakt Script Language Manual

Getting Started - the Kontakt Script Processor

To begin with, we should clarify a couple of things so you know exactly what you're dealing with.

So what is the Kontakt Script Processor anyway?

The Kontakt Script Processor is one part of the architecture of Kontakt, i.e. it constitutes one element in the signal flow. As you'll recall from the Kontakt manual, from the point of hitting a key on the keyboard to actually hearing the sound, the audio signal goes through various stages (this is somewhat simplified):

Play a note → Source (sample is triggered) → Group FX → Amplifier → Instrument FX → Output

KSP is situated between the incoming midi information and the source:

Play a note → KSP → Source (sample is triggered) → Group FX → Amplifier → Instrument FX → Output

However, KSP is not a simple MIDI processor which takes in MIDI, processes it and spits it out again; if that were the case, you could use any MIDI processing utility and patch it between your keyboard and Kontakt. KSP, on the other hand, is able to retrieve Kontaktspecific parameters like the naming of the groups in an instrument, for example. It also can pass Kontakt-specific parameters to the source module, like the tuning of the triggered zone.

Please note: the KSP operates on the instrument level of a Kontakt instrument, just like the instrument send and instrument insert effects.

Don't worry if think you're already lost - you'll grasp the principle quite soon.

So what about the Kontakt Script Language?

Not so fast…in order for KSP to do anything, a module must be plugged in (just like if you want to have a delay effect on your audio, you must plug in the delay effect in the effect chain). We refer to such a module as a script, and a script is a program written in the Kontakt Script Language.

Let's illustrate this in Kontakt:

Open Kontakt, load an instrument, and click the wrench icon to access the edit mode

Click on the Script Editor tab in the top area to open the script module pane

Click on the Script icon. A pop up menu appears

Click on Harmonization/Harmonize

The module appears in the script module pane:

6

Kontakt Script Language Manual

Now click on the Edit button in the bottom left corner of the module:

Magic, huh?

What you see is the actual code of the module. If you keep on reading this manual soon you'll be able to read and access the code, modify it to make it suitable for your own genius musical style, copy parts of it to use in your own scripts and so forth.

7

Kontakt Script Language Manual

Let's move on:

Click the Edit button to close the edit area

Click on the Script icon and choose - Empty - from the pop up menu. This removes the script from the module pane.

Select the following text and copy it to the clipboard:

on init

declare ui_label $test (1,1)

set_text ($test, "My first script!!!") move_control ($test, 3,1)

end on

In Kontakt, click the Edit button to access the script edit area. You'll see a blinking cursor waiting for your masterpiece.

Paste the text from the clipboard into the script edit area. Notice how the LED next to the “Apply” button turns orange, indicating that you've done something to the script.

Click on “Apply”. You should end up with the following:

Congratulations! You have taken the first step in becoming a programming geek! But our work of art is not finished yet; let's be thorough and bring it to an end:

Next to where it says Title for this script enter a nice, descriptive and boring title like My first script and hit Return.

Click on Edit to close the edit area and select save preset… from the Script pop-up menu. A standard Save dialog box appears.

Type in a name for the file (be sure to keep the extension .nkp) and save it.

Assume we want to finish our session for today, so close the instrument and quit Kontakt (no need to save anything).

Assume we've changed our mind, so open up Kontakt, load an instrument and bring the script module pane to the front (you should know by know how that works).

From the Script pop up menu, select your script and voilá: you brought your masterpiece back.

At this point, you've basically already learned all the necessary steps in script production (well, all except for actually writing the scripts yourself, but we'll deal with that).

8

Kontakt Script Language Manual

Let's recap:

The Kontakt Script Processor (KSP) is an element in Kontakt's flowchart.

In order for KSP to do anything, a module has to be loaded.

We refer to such a module as a s cript.

A script is a small program, which is executed by KSP.

This program is basically nothing more than pure text, written in the Kontakt Script Language.

Here's what the normal workflow looks like:

Write some code, either in an external text editor or in the script edit area.

If you've written the code in an external text editor, copy it to the script edit area.

Click on “Apply” to initialize the script.

Save the script. It now becomes an encoded file with the extension .nkp (like all Kontakt presets).

The scripts are stored on your hard drive in the Kontakt application folder:

Kontakt 2/presets/scripts/

This concludes our getting started session. Next we'll learn a little bit more about the general user interface of KSP before we finally start to write our own scripts.

In case you're wondering…the script you saved a couple of minutes ago does not do anything glorious. Actually, it does nothing; but don't worry, this will change.

9

Kontakt Script Language Manual

Working with KSP and Scripts

Let's have a look at the general user interface elements of KSP:

Script module: This area is similar to a normal Kontakt module. At the top you'll find five tabs to switch from one script to the other (you can load up to five script modules per instrument). A script module need not necessarily contain any GUI elements; a script can have a specific function and have a blank interface. Later you'll learn how to create UI elements.

Bypass: Activates/deactivates the script

Script: Use this pop-up menu to load and save scripts.

Edit: Click this button to open the script edit area. The lock indicates if the script is editable or not (see below).

Script edit area: This area opens up if you click on Edit in the script module. Here you can write, paste and view the actual code of the script.

Only have the script edit area open if you need to view or edit the code, otherwise keep it closed to conserve CPU power.

Lock with Password: Click this button to type in a password in order to prevent others from viewing or changing your scripts.

10

Kontakt Script Language Manual

Title for this Script: You can enter a title for the script in this field. The title will then appear in the tab. Note that scripts can have different names for titles and file names.

Apply: Click on "Apply" to activate the script. KSP checks the syntax of the code, and if there are no error messages you're ready to go. The LED left of the "Apply" button turns orange whenever you make changes to a script and the script is not yet activated.

Script status line: If you've made a mistake while typing a script, KSP will output an error message in this line and highlight the incorrect line in the edit area.

Kontakt status line: This line will output all script messages generated from a message() function as well as errors which occur during playback of a script. Don't know what a function is? Don't worry, you'll see.

11

Kontakt Script Language Manual

Basic Scripting Tutorial

Generating MIDI notes: a simple accompanist

Now we're ready to jump right into programming. This chapter will introduce you to the most basic (yet very important) procedures while programming. Also, you will get an insight into many topics which will be covered later in this manual.

We'll start with a simple script demonstrating one important and powerful feature of the script engine: the ability to generate "artificial" MIDI events. So let's get started!

Open Kontakt, load an instrument of your choice, open the script editor and copy the following text into the script editor:

on note play_note(60,120,0,-1)

end on

After pressing "Apply" the script is analyzed and (if you did not make any mistakes while copying...) ready to use. Play some notes on your keyboard; each played note will be accompanied by the note C3 with a velocity of 120.

Cool! I ALWAYS wanted every note that I play to be accompanied by C3…

Yeah, I know, maybe you think it's silly but let's stick to this example and really see what's going on.

So how does it work?

Whenever you play a note, KSP processes a specific part of the script. These parts are called callbacks. What you've written above is a so-called note callback. A note callback is a section in the script which is executed whenever you play a note. "Executed" means that each and every line is interpreted by KSP from top to bottom.

So let's analyze what we've done line by line:

on note: this marks the beginning of a note callback, i.e. it tells KSP to interpret the following lines of code whenever a note is played.

play_note(60,120,0,-1): this is the first command KSP executes (it's also the only one in this case). We'll refer to such a command as a function. This function generates midi notes. In this case it generates a C3 (note number 60) with a velocity of 120. See below for a complete definition of this function.

end on: this marks the end of the callback.

Again, keep in mind that this callback is only triggered by notes (since it's a note callback), so it will not generate any notes when you move the mod wheel for example. KSP recognizes more than this type of callback of course. You'll learn one more in this chapter and the remaining in the section labeled "Callbacks".

12

Kontakt Script Language Manual

You'll probably have understood everything except for the those fancy numbers in the play_note() statement. These numbers are called parameters and each function needs parameters to work properly. Functions can have one, two, three or more parameters. In this case play_note() has four parameters and it always needs four parameters to work with.

Here's a complete definition of the play_note()function (you'll come across many definitions of functions in this manual so we'll introduce you also to the general format of such a definition):

play_note(<note-number>,<velocity>,<sample-offset>,<duration>)

play a note, i.e. generate a note on message followed by a note off message

<note-number>

the note number to be generated (0 -127)

<velocity>

velocity of the generated note (1 -127)

<sample-

this parameter specifies an offset in the sample in microseconds

offset>

 

 

Please note: this parameter does not work in DFD mode - only in

 

sampler mode!

<duration>

specifies the length of the generated note in microseconds

 

this parameter also accepts two special values:

 

-1: releasing the note which started the callback stops the sample

 

0: the entire sample is played

Now we can fully understand what our script does:

it plays a note with note number 60: play_note(60,120,0,-1)

with a velocity of 120: play_note(60,120,0,-1)

the sample will be played from the beginning: play_note(60,120,0,-1)

and the sample will have the same duration as the note which triggered the callback: play_note(60,120,0,-1)

Maybe now it is a good time to take a break and play around with what you've learned so far; explore the play_note() function by entering other values, or even adding more play_note() functions to the script.

Don't forget: it's wise to read the manual but as with any programming language…learning by doing is the key to success!

Summary

The statement "on note" marks the beginning of a note callback. A callback is a section within a script that is being "called back" (i.e. executed) at certain times. In our example, the callback is executed whenever the program receives a note-on message, since it's a note callback. The script processor then interprets each line of the script from top to bottom until it reaches the "end on" statement, which defines the end of the callback. The function play_note() generates artificial MIDI notes.

13

Kontakt Script Language Manual

Built-in variables: Building a simple Octaver

If you've played around with the script mentioned above you will have noticed that you can enter various numbers for the note and velocity of the MIDI note to be generated, but it's always static - the script always generates the same notes.

Now, this really should change, right?

Please input the following script:

on note

play_note($EVENT_NOTE - 12,$EVENT_VELOCITY,0,-1) end on

Play some notes on the keyboard, every note you play will be accompanied by the octave below with the same velocity of the original note; you've just built a simple octaver!

So how did we do that?

This little script introduces you to two new elements: variables and operators.

You will find detailed information about these two concepts later in this manual, for now let's stick to the following:

$EVENT_NOTE is a built-in variable, it carries note. So when you play C3 (60) on your keyboard,

the note number of the original played $EVENT_NOTE will be 60.

$EVENT_VELOCITY is also a built-in variable, it carries the velocity number of the original played note. So when you play a note with a velocity of 110, $EVENT_VELOCITY will be 110.

You'll also find the operator "-". And yes, it performs exactly as you would expect: it subtracts a value. So the first parameter in the play_note function() – which denotes the note number of the generated note – is: $EVENT_NOTE - 12; so when you play C3 (60), the script will output C2 (48) (since 60 - 12 = 48) with the same velocity as the note you played!

Again, it's time to experiment: fool around with different transpositions (i.e. other numbers instead of 12), alter the velocity of the generated note (e.g. $EVENT_VELOCITY - 20), use more than one play_note() function; you'll get the idea.

Summary

Built-in variables are very important and powerful things. They cannot be declared, but "are always there". We looked at two important built-in variables here: $EVENT_NOTE and $EVENT_VELOCITY. KSP provides many different built-in variables. A complete list of all built-in variables can be found in the reference section of this document.

14

Kontakt Script Language Manual

UI Control variables and the init callback: Creating a simple Harmonizer

Now let's extend our little script:

Wouldn't it be great if you had some sort of knob with which you could specify the distance between the generated note and the original note; maybe a knob labeled "Interval"?

Please input the following script:

on init

declare ui_knob $Interval (-12,12,1) $Interval := 7

end on

on note

play_note($EVENT_NOTE + $Interval,$EVENT_VELOCITY,0,-1) end on

Play a few notes, each note will be accompanied a fifth above, perfect for scoring a Ben Hurlike movie…

But something else happened, take a look at the script module area:

A cute knob appeared, labeled "Interval". Now play a few notes and set the knob to different values: you can now specify the amount of transposition yourself, so you've changed your octaver into a simple harmonizer!

But how did we do that?

To put it in a simplified manner, we declared a GUI element (in this case a knob), we told KSP that this knob has a range from -12 to 12 and that its initial value should be 7, and finally we told KSP that it should add this number to the note number we play and generate a new note.

This script introduces you to three new elements: the init callback, the declaration of UI control variables and the assignment of values to variables.

Let's dig into it:

on init ... end on

initial callback, executed when the script was successfully analyzed

15

Kontakt Script Language Manual

The init callback is a callback which is executed when you click on "Apply”. It contains all initializations, variable declarations, UI elements and much more. The init callback is thus interpreted only once, whereas the note callback is interpreted whenever you play note. It's obvious that when you want to have a GUI element like a knob in your module, this knob needs to be created, but it needs to be created only once. That's why all GUI elements, for example, can only be declared ("created") in the init callback. The beginning of an init callback is marked with on init and its end is marked with end on (like the note callback).

A UI control variable is a type of user defined variable. The Kontakt Script Language distinguishes between built-in variables and user defined variables.

In our example we created a knob which in principle is a user defined variable, where you can change the value of the variable by changing the knob in the script module area.

Here's how we define a UI element like a knob:

declare ui_knob $<variable-name> (<min>,<max>,<display-ratio>)

create a user interface knob

Don't worry about the various parameters for now. You'll learn them later.

So in our script we've created a knob and given it the name Interval. What's missing in our discussion is the third line:

$Interval := 7

":=" denotes an assignment. In our example it says "Assign the value 7 to the variable called Interval".

So when the init callback is executed (upon clicking on "Apply"), a knob is created and the knob initializes itself to 7. When you play a note, this value is then added to the note number you've played, so when you set Interval to -12 and play C3 (60), the accompanying note will be C2 (48) since $EVENT_NOTE + $Interval equals 60 + (-12) equals 48!

We finish with a subtle variation. By now you should have the chops to understand what it's doing:

on init

declare ui_knob $Interval (-12,12,1) $Interval := 7

declare ui_knob $Velocity (1,127,1) $Velocity := 60

end on

on note

play_note($EVENT_NOTE + $Interval,$Velocity,0,-1) end on

16

Kontakt Script Language Manual

Summary

The init callback is called as soon as the script is successfully analyzed. That happens exactly when you press the "Apply" button in the script editor window.

A knob is a UI Control variable which is a type of user defined variable. UI elements are created in the init callback.

":=" marks an assignment, the value at the right gets assigned to the variable at the left of this sign.

17

Kontakt Script Language Manual

Debugging and customizing: finishing your script

In this last part of the chapter we'll begin with a slight variation on the preceding script:

on init

declare ui_knob $Interval (-12,12,1) declare ui_knob $Velocity (-64,64,1)

$Interval := 7 $Velocity := 20

end on

on note play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1)

end on

With the knob labeled Velocity you can now modify the velocity of the generated note; if set to -10 for example, when you play a note with a velocity of 100 the generated note will have a velocity of 90.

No big deal, why don't we just go on with something new?

Now, you think we're done with our little script. Alas, we're not…

Try this: set Velocity to the maximum value of 64 and play a note on your keyboard as loud as possible. Then take a look at the status of Kontakt (in the lower left corner of the Kontakt window):

Oops, we have a problem. What happened?

Well, probably you've played a note with a velocity of 100 or more, the Velocity knob value of 64 got added to this velocity and you end up with a velocity value well beyond 127 which does not exist in MIDI. So KSP is so friendly to remind you that it was told to play a note with a velocity that is simply not possible. In this case, KSP will process the play_note() function with a velocity of 127 and output an error message.

An error message does not necessarily lead to a catastrophe; in our script we actually could live with such an error message since the harmonizer does its job. However, make it a habit to watch out for those messages and program your scripts in such a way that no errors are produced.

18

Kontakt Script Language Manual

Take a look at the following:

on init

declare ui_knob $Interval (-12,12,1) declare ui_knob $Velocity (-64,64,1)

$Interval := 7 $Velocity := 20

message ("")

end on

on note

if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1)

else play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1)

end if end on

Again, set the V elocity knob to 64 and play a loud note; no error message will be produced.

So let's go through this script. It contains two new elements: the message() function and the if…else…end if control statement.

The message function writes text into the Kontakt status line. Here's the complete definition.

 

message(<number,variable or text>)

 

 

display numbers, variable values and text in the status line in Kontakt

 

 

<number>

display single numbers: message(2), message(128)

<variable>

display the value of a variable: message($EVENT_VELOCITY)

<text>

display text: message("script info") – you must put the text string in

 

quotation marks

Remarks

you can also use combinations of the above:

 

message("Velocity: " & $EVENT_VELOCITY)

 

you must use the & operator in order to concatenate elements

The message() function can be extremely helpful in scripts when you run into problems and need to retrieve specific information. Please note that only one message can be displayed in the Kontakt status line, so you will always see the last output of message().

If you want to output a message to the user, please do not use the message() function.

There is a GUI label (explained later), which is more useful for those purposes.

Imagine having 16 instruments loaded, each with 5 scripts: if every scripts outputs messages (something like: this script was created by xxx, master of scripting!), it can get VERY annoying.

In our example we wrote: message("") (i.e. nothing) in the init callback; this is helpful if you want to clear previous error messages.

19

Kontakt Script Language Manual

Make it a habit to write message("") in the init callback. You can then be sure that all previous messages (by the script or by the system) are deleted and you see only new messages.

The next new element is the if…else…end if control statement.

If the condition $EVENT_VELOCITY + $Velocity > 127 is true (i.e. the sum is larger than 127), the script will output:

play_note($EVENT_NOTE+$Interval,127,0,-1)

If not (i.e. the sum is equal or less 127), the script will output:

play_note($EVENT_NOTE + $Interval, $EVENT_VELOCITY+$VELOCITY,0,- 1)

An if statement is closed by the term end if.

So now we can be sure that the play_note() function will always process correct velocity values (i.e. in the range of 1 - 127).

Cool…enough smart talk. Are we finally finished now?

No.

Are you really sure this script will not produce any error messages? We were talking about velocities exceeding 127, but did we talk about velocities below 1, which are also not possible?

Right, turn the Velocity knob to -40 and play a soft note, you will get the same error message since the velocity in the play_note() function was below 1.

20

Kontakt Script Language Manual

Without any further comments, take a look at the following script:

on init

declare ui_knob $Interval (-12,12,1) {transposition amount} declare ui_knob $Velocity (-64,64,1) {Vel amount for new note}

$Interval := 7 {initialize to a perfect fifth}

$Velocity := 20 {initialize to 20: all generated notes are louder}

message (" ") {clear Kontakt status line}

end on

on note

{check if Vel is higher than 127}

if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1)

else

{check if Velocity is lower than 1} if ($EVENT_VELOCITY+$VELOCITY < 1)

play_note($EVENT_NOTE+$Interval,1,0,-1) else

play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end if

end if end on

Now your script should work as expected and will not produce any error messages.

By the way, the above announcement "Without any further comments" is not quite true. In fact, our script now has many comments indeed…

Take a look at the script editor:

Everything you write between curly brackets: {........} is a comment; it is not interpreted by KSP (in the script editor, comments are highlighted). The purpose of comments is just to help you structure your code so at every point you're know what you're doing.

21

Kontakt Script Language Manual

Be smart, use comments!

You might find it silly to comment every command of code, but when working on larger scripts this might become extremely helpful. Let's say you work on a larger script, take a break for a couple of weeks and then come back to your script; without comments it is very hard to "get back into the code".

Also, do not expect anybody to help you with your scripts when you encounter problems if your script has no comments; it is just too difficult to look at 500 lines of code from somebody else without any comments.

So my script is up and running. Anything else?

Yep, one more thing and we're done for today.

Load the script and find a nice combination of I nterval and V elocity for your upcoming musical masterpiece. Save the patch (or your project if you're working in a host sequencer) and reopen it: all your settings in the script module are lost!

How come?

Whenever you load a script or a patch that contains a script, the init callback is executed. Thus all variables (in our script the two knobs) are reset to their initial value (i.e. the values they were assigned to in the init callback).

Now that's just great – no total recall with scripts at all?

You're right. It would be pretty useless to load a script into a patch, tweak it, save the patch and lose your settings. The only workaround would be to always write the parameter values into the init callback, but that's not really how a musician works.

22

Kontakt Script Language Manual

Therefore it is possible to make variables p ersistent. Try this script:

on init

{----- GUI elements -----}

declare ui_knob $Interval (-12,12,1) {transposition amount} declare ui_knob $Velocity (-64,64,1) {Vel amount for new note}

{----- Inits -----}

$Interval := 7 {initialize to a perfect fifth}

$Velocity := 20 {initialize to 20: all generated notes are louder}

{----- Recall -----}

make_persistent ($Interval) {save the state of the knob Interval} make_persistent ($Velocity) {save the state of the knob Velocity}

message ("") {clear Kontakt status line} end on

on note

{check if Vel is higher than 127}

if ($EVENT_VELOCITY+$VELOCITY > 127) play_note($EVENT_NOTE+$Interval,127,0,-1)

else

{check if Velocity is lower than 1} if ($EVENT_VELOCITY+$VELOCITY < 1)

play_note($EVENT_NOTE+$Interval,1,0,-1) else

play_note($EVENT_NOTE+$Interval,$EVENT_VELOCITY+$VELOCITY,0,-1) end if

end if end on

Load the script, make some changes to it, save the patch and reload the patch: everything in its right place!

This is achieved by using the function the init callback and must contain the

make_persistent(); this function has to be written in variable name.

make_persistent(<variable-name>)

retain the value of a variable when a patch is loaded

All variable types (e.g. arrays, user defined variables) can be made persistent, not just UI control variables.

So that's it - the script is finally complete. Congratulations!

Now give it a nice title, save it, and…most important of all…make music with it!

Summary

You can execute commands under certain conditions with if…else…end if. By using the message() function, you can display numbers, variable values or text in the Kontakt status line. If you want all variables (e.g. knobs) to be saved with the patch, use the make_persistent() function.

23

Kontakt Script Language Manual

Comments are written in curly brackets: {this is a comment}. They are an immeasurable help for you and others in understanding the code.

This concludes our little Basic Scripting chapter. From now on, we'll move on at a slightly faster pace with more complete definitions. Be sure to always play around with everything as you learn it. This is the only way to really grasp the full potential of the Kontakt Script Language. Don't be afraid to make mistakes. You cannot ruin Kontakt with any script…

24

Kontakt Script Language Manual

Fundamentals

General rules concerning the syntax

Let's start by laying down some basic rules about the syntax of the script language (e.g. the way scripts have to be written in order to be properly executed):

each command has to be written in one line

there can be an infinite number of spaces between the command lines

there can be an infinite number of spaces between single words

the script language is case sensitive, so the command play_note() would not be recognized when spelled Play_Note()

if one command line is too long and therefore is difficult to read, you can break it by typing "... "at the end of the line. Since a script statement must always be contained within a single line, we need a special mechanism to tell the processor that our line is not yet finished, should we want to break it.

So the following two scripts are identical:

on note

if($EVENT_VELOCITY > 100)

message ("Script message: key struck HARD")

else

message("Script message: key struck SOFT") end if

end on

is the same as

on note

if( $EVENT_VELOCITY > 100)

message(...

"Script message: key struck HARD") else

message("Script message: key struck SOFT") end...

if

end on

syntax errors are reported in the script status line. The line containing the error is marked in red.

errors during a running script are reported in the Kontakt status line below Kontakt's browser.

25

Kontakt Script Language Manual

Callbacks

Callbacks are programs which are executed at certain times. If you press and hold a note, the note callback is executed, but releasing the note triggers the release callback and so forth.

There are five different types of callbacks:

on init ... end on

initial callback, executed when the script was successfully analyzed

on note ... end on

note callback, executed whenever a note on message is received

on release ... end on

release callback, executed whenever a note off message is received

on ui_control (<variable-name>) ... end on

ui callback, executed whenever the user changes the respective UI element

on controller ... end on

controller callback, executed whenever a cc or pitch bend message is received

(actually there's two more callbacks used for rpn/nrpn messages, but those two callbacks can be seen as "special" controller callbacks).

You can stop a callback with the statement exit:

exit

immediately stops a callback

Variables

Let's go back to our first script:

on note play_note(60,120,0,-1)

end on

As we said – having each note accompanied by middle C3 is not very spectacular. So if we want each played note to be accompanied by a newly generated note which has the same velocity and sounds an octave higher we write:

on note

play_note($EVENT_NOTE + 12,$EVENT_VELOCITY,0,-1) end on

26

Kontakt Script Language Manual

Instead of a specific note number we write $EVENT_NOTE + 12, instead of specifying a velocity we type $EVENT_VELOCITY. $EVENT_NOTE and $EVENT_VELOCITY are so-called built-in variables; they contain the note number and the velocity of the note which triggered the callback.

Variables are the most important part of the script language. Speaking in computer terms, they are named storage spaces for numbers. We have several types of variables which we'll discuss in a moment, but for now it's important that we distinguish between u serdefined variables and builtin variables.

Both user-defined and built-in variables can have two states:

normal variables, marked by a dollar sign ($my_variable or $EVENT_VELOCITY) or an "at" sign (@my_text)

array variables, marked by a percent sign (%my_array[]or %KEY_DOWN[<note-number>]) or an exclamation mark (!my_text_array[])

A normal variable can store a single integer value or a text string. An array variable is similar to a normal one, but it can store several values/text strings at once. An array is an indexed list of numbers, similar to a table with each index x pointing to an address y. An array can have 1 to 512 indices.

Declaration of variables

All user-defined variables must be declared. Declaring a variable means that its name is registered for subsequent use and its value is initialized to a certain value. Let's look at some examples of variable declarations:

on init

declare $first_variable declare $second_variable := 12

declare const $third_variable := 24 declare %first_array[4]

declare %second_array[3] := (3,7,2) end on

So what does this script do?

The first line marks the beginning of an init callback (you'll recall that an init callback is executed immediately after the script has been successfully analyzed).

In the second line, a normal variable called first_variable is declared by using the statement declare. It has no value assigned to it by the user so it is initialized to zero.

The third line declares a normal variable called second_variable and assigns it the value 12 with the operator :=

The fourth line declares a special normal variable: a constant called third_variable. A constant is pretty much the same thing as a normal variable, except that its value cannot be changed and it's a little more efficient (since it need not be evaluated at runtime).

The fifth line declares an array called first_array with four elements, all initialized to zero.

The sixth line declares an array called second_array with three elements, which are initialized to 3, 7 and 2.

The seventh line marks the end of the init callback.

27

Kontakt Script Language Manual

We can see that variables have certain naming conventions: non-array variables must start with a dollar sign, whereas arrays must start with a percent sign. The syntax is always the same as in the example; constant declarations must always include the initial value, which gets assigned by the := operator.

Now we'll take the script from above (which does not do anything yet) and try to extend it.

Working with variables

Copy the following script and play a note on the keyboard:

on init

 

declare $first_variable

 

declare $second_variable :=

12

declare const $third_variable := 24

declare %first_array[4]

 

declare %second_array[3] :=

(3,7,2)

end on

 

on note

 

play_note ($second_variable

+ 48,$third_variable + 96,...

%first_array[2] +

$first_variable,%second_array[0] - 4)

end on

 

This (rather useless) script generates the same note as our very first script: each played note will be accompanied by the note C3 with a velocity of 120…

Its purpose is to show an extremely basic idea of manipulating variables. The above play_note() function is identical to play_note (60, 120, 0, -1):

$second_variable + 48 equals 60

$third_variable + 96 equals 120

%first_array[2] equals 0 since index number 2 points to the value 0

%second_array[0] - 4 equals -1, since index number value points to value 3 which is subtracted by 4

The built-in variables are very important and powerful things. They cannot be declared but "are always there". We take a look at two important built-in variables here (a complete list of all built-in variables can be found in the appendix of this document):

$EVENT_NOTE

note number of the event which triggered the callback

$EVENT_VELOCITY

velocity of the note which triggered the callback

$EVENT_NOTE contains the note value of the MIDI event that triggered the containing callback and $EVENT_VELOCITY is its corresponding velocity. It's pretty obvious that both variables may not be used within an init callback (since the init callback doesn’t get triggered by a key and thus has no note or velocity value!).

28

Kontakt Script Language Manual

Valid note values go from 0 – 127 which correspond to C-2 – G8 obviously. $EVENT_VELOCITY can contain values from 1 to 127. As you can see, built-in variables are spelled with capitals, so it's a good idea if you stick to small letters for your own variables.

Let's look at some examples that contain both types of variables.

on init

declare $new_note end on

on note

$new_note := $EVENT_NOTE + 12 play_note($new_note,$EVENT_VELOCITY,0,-1)

end on

And again, this script accompanies each and every note you play with C3 and a velocity of 120…

The variable $new_note is declared and has the value zero, since it was not assigned to a value. By hitting a note, the note callback is processed, where the value of $new_note is replaced by the expression $EVENT_NOTE+12. (remember: by using the operator := the value of the left variable is replaced by the value of the right variable).

Can we PLEASE make a script that does not accompany each note I play with C?

Sure we can. Check out the following:

on init

declare %addNote[12] := (4, 6, 3, 6, 3, 4, 6, 4, 6, 3, 6, 3) declare $keyClass

end on

on note

$keyClass := $EVENT_NOTE mod 12

play_note($EVENT_NOTE + %addNote[$keyClass],$EVENT_VELOCITY,0,-1) end on

Play a few notes – magic, huh? Each note you play will be accompanied by note which really fits well in the key of C major…

Before we start analyzing this script, let's first direct our attention to the modulo operator mod. A modulo operator divides two numbers and outputs the remainder of the division, so for example 14 mod 12 equals 2, 128 mod 10 equals 8 and so on.

In our example we can see a very common use for the modulo operator: by writing $EVENT_NOTE mod 12 we can retrieve the pitch class (i.e. the pitch independent of the octave) of the played note. So whenever you hit any D, $keyClass will always be 2.

Let's assume you've played D3 (62): now this variable is used as an index in the array %addNote[12] which results in the new note number 62 + 3 = 65, which equals F3.

29

Kontakt Script Language Manual

String Variables

There are two variable types which store text strings instead of integers:

string variables, which are declared with a @ prefix

string arrays, which are declared with a ! prefix

See the following script for a simple example:

on init

declare @text

@text :=

"note played: "

declare !list[12]

!list[0]

:= "C"

!list[1]

:= "C#"

!list[2]

:= "D"

!list[3]

:= "D#"

!list[4]

:= "E"

!list[5]

:= "F"

!list[6]

:= "F#"

!list[7]

:= "G"

!list[8]

:= "G#"

!list[9]

:= "A"

!list[10] := "A#" !list[11] := "B"

end on on note

message(@text & !list[$EVENT_NOTE mod 12]) end on

Persistent variables

In the Basic Scripting chapter, the command make_persistent() was already introduced:

make_persistent(<variable-name>)

retain the value of a variable when a patch is loaded

Whenever you load a patch or a script, the init callback is processed and the persistent variables are set to their saved state. Additionally, the value of persistent variables is also saved when clicking on Apply. So when you load for example the Arpeggiator, make some changes to the rhythm in the gui and then decide to edit the code of this particular script, you will not loose the changes you've made before.

Please note: if you load a script from the script menu, the value of persistent variables is NOT buffered. This is necessary, since for example you could have more than one script with the same variable name.

So if you load a script which contains the variable name $Time (say for example a delay script), make some changes and then load a different script which contains the same variable name (say for example sequencing script), you would not want the changes of the first script to be applied to the second script.

30

Loading...
+ 68 hidden pages