/[svn]/doc/docbase/instrument_scripts/nksp/01_nksp.html
ViewVC logotype

Annotation of /doc/docbase/instrument_scripts/nksp/01_nksp.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3119 - (hide annotations) (download) (as text)
Fri Apr 21 16:02:47 2017 UTC (6 years, 11 months ago) by schoenebeck
File MIME type: text/html
File size: 56754 byte(s)
* NKSP Language tutorial: Fixed syntax of select case blocks.

1 schoenebeck 2732 <html>
2     <head>
3     <meta name="author" content="Christian Schoenebeck">
4     <title>NKSP Language</title>
5     <meta name="description" content="Introduction to the NKSP real-time instrument script language.">
6     </head>
7     <body>
8     <p>
9     This document intends to give you a compact introduction and overview to
10     the NKSP real-time instrument script language, so you can start writing
11     your own instrument scripts in short time. It concentrates on describing
12     the script language. If you rather want to learn how to modify and
13     attach scripts to your sounds, then please refer to the gigedit manual for
14 schoenebeck 3111 <a href="gigedit_scripts.html">how to manage instrument scripts with gigedit</a>
15     for Gigasampler/GigaStudio format sounds, or refer to the SFZ opcode
16     <code lang="sfz">script</code> for attaching NKSP scripts with
17     SFZ format sounds.
18 schoenebeck 2732 </p>
19    
20     <h3>At a Glance</h3>
21     <p>
22     <img src="nksp_file.png" style="height:111px; margin-right:12px;">
23     NKSP stands for "is <b>N</b>ot <b>KSP</b>", which denotes its distinction
24 schoenebeck 2995 to an existing proprietary language called <i>KSP</i>.
25 schoenebeck 2732 NSKP is a script language specifically designed to write real-time capable
26     software extensions to LinuxSampler's sampler engines that can be bundled
27     individually with sounds by sound designers themselves.
28    
29     Instead of defining a completely new script language, NKSP is leaned on
30     that mentioned properiatary script language. The biggest advantage is that
31     sound designers and musicians can leverage the huge amount of existing KSP
32     scripts which are already available for various purposes on the Internet,
33     instead of being forced to write all scripts from scratch in a completely
34     different language.
35     </p>
36     <p>
37     That also means however that there are some differences between those two
38     languages. Some extensions have been added to the NKSP core language to
39     make it a bit more convenient and less error prone to write scripts, and
40     various new functions had to be added due to the large difference of the
41     sampler engines and their underlying sampler format. Efforts have been
42     made though to make NKSP as much compatible to KSP as possible.
43     The NKSP documentation will emphasize individual differences in
44     the two languages and function implementations wherever they may occur, to
45     give you immediate hints where you need to take care of regarding
46     compatibility issues when writing scripts that should be spawned on both
47     platforms.
48     </p>
49     <p>
50     Please note that the current focus of NKSP is the sound controlling aspect
51     of sounds. At this point there is no support for the graphical user
52     interface function set of KSP in NKSP.
53     </p>
54    
55     <h2>Event Handlers</h2>
56     <p>
57     NKSP is an event-driven language. That means you are writing so called
58     <i>event handlers</i> which define what the sampler shall do on individual
59     events that occur, while using the sound the script was bundled with.
60     An event handler in general looks like this:
61     </p>
62     <code lang="nksp">
63     on ??event-name??
64    
65     ??statements??
66    
67     end on
68     </code>
69     <p>
70     There are currently four events available:
71     </p>
72     <table>
73     <tr>
74     <th>Event Type</th> <th>Description</th>
75     </tr>
76     <tr>
77     <td><code>on note</code></td> <td>This event handler is executed when a new note was triggered, i.e. when hitting a key on a MIDI keyboard.</td>
78     </tr>
79     <tr>
80     <td><code>on release</code></td> <td>This event handler is executed when a new note was released, i.e. when releasing a key on a MIDI keyboard.</td>
81     </tr>
82     <tr>
83     <td><code>on controller</code></td> <td>This event handler is executed when a MIDI control change event occurred. For instance when turning the modulation wheel at a MIDI keyboard.</td>
84     </tr>
85     <tr>
86     <td><code>on init</code></td> <td>Executed only once, as very first event handler, right after the script had been loaded. This code block is usually used to initialize variables in your script with some initial, useful data.</td>
87     </tr>
88     </table>
89     <p>
90     You are free to decide for which ones of those event types you are going to
91     write an event handler for. You can write an event handler for only one
92     event type or write event handlers for all of those event types. Also
93     dependent on the respective event type, there are certain things you can
94     do and things which you can't do. But more on that later.
95     </p>
96    
97     <h3>Note Events</h3>
98     <p>
99     As a first example, the following tiny script will print a message to your
100     terminal whenever you trigger a new note with your MIDI keyboard.
101     </p>
102     <code>
103     on note
104     message("A new note was triggered!")
105     end on
106     </code>
107     <p>
108     Probably you are also interested to see which note you triggered exactly.
109     The sampler provides you a so called
110     <i title="A script variable which is provided by the sampler and which has a very specific purpose which you cannot override for other purposes.">
111     built-in variable
112     </i>
113     called <code>$EVENT_NOTE</code> which reflects the note number
114     (as value between 0 and 127) of the note that has just been triggered. Additionally
115     the built-in variable <code>$EVENT_VELOCITY</code> provides you the
116     velocity value (also between 0 and 127) of the note event.
117     </p>
118     <code>
119     on note
120     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
121     end on
122     </code>
123     <p>
124     The <code>&</code> character concatenates text strings with each other.
125     In this case it is also automatically converting the note number into a
126     text string.
127     </p>
128     <note class="important">
129     The message() function is not appropriate for being used with your final
130     production sounds, since it can lead to audio dropouts.
131     You should only use the message() function to try out things, and to spot
132     and debug problems with your scripts.
133     </note>
134    
135     <h3>Release Events</h3>
136     <p>
137     As counter part to the <code>note</code> event handler, there is also the
138     <code>release</code> event handler, which is executed when a note was
139     released. This event handler can be used similarly:
140     </p>
141     <code>
142     on release
143     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
144     end on
145     </code>
146     <p>
147     Please note that you can hardly find MIDI keyboards which support release
148     velocity. So with most keyboards this value will be 127.
149     </p>
150    
151     <h3>Controller Events</h3>
152     <p>
153     Now let's extend the first script to not only show note-on and note-off
154     events, but also to show a message whenever
155     you use a MIDI controller (i.e. modulation wheel, sustain pedal, etc.).
156     </p>
157     <code>
158     on note
159     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
160     end on
161    
162     on release
163     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
164     end on
165    
166     on controller
167     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
168     end on
169     </code>
170     <p>
171     It looks very similar to the note event handlers. <code>$CC_NUM</code>
172     reflects the MIDI controller number of the MIDI controller that had been
173     changed and <code>%CC</code> is a so called <i>array variable</i>, which not only
174     contains a single number value, but instead it contains several values at
175     the same time. The built-in <code>%CC</code> array variable contains the current
176     controller values of all 127 MIDI controllers. So <code>%CC[1]</code> for
177     example would give you the current controller value of the modulation
178     wheel, and therefore <code>%CC[$CC_NUM]</code> reflects the new controller
179     value of the controller that just had been changed.
180     </p>
181     <p>
182     There is some special aspect you need to be aware about: in contrast to the MIDI standard,
183     monophonic aftertouch (a.k.a. channel pressure) and pitch beend wheel are
184     handled by NKSP as if they were regular MIDI controllers. So a value change
185     of one of those two triggers a regular <code>controller</code> event handler
186     to be executed. To obtain the current aftertouch value you can use
187     <code>%CC[$VCC_MONO_AT]</code>, and to get the current pitch bend wheel
188     value use <code>%CC[$VCC_PITCH_BEND]</code>.
189     </p>
190    
191     <h3>Script Load Event</h3>
192     <p>
193     As the last one of the four event types available with NKSP, the following
194     is an example of an <code>init</code> event handler.
195     </p>
196     <code>
197     on init
198     message("This script has been loaded and is ready now!")
199     end on
200     </code>
201     <p>
202     You might think, that this is probably a very exotic event. Because in
203     fact, this "event" is only executed once for your script: exactly when
204     the script was loaded by the sampler. This is not an unimportant event
205     handler though. Because it is used to prepare your script for various
206     purposes. We will get more about that later.
207     </p>
208    
209     <h2>Comments</h2>
210     <p>
211     Let's face it: software code is sometimes hard to read, especially when you
212     are not a professional software developer who deals with such kinds of
213     things every day. To make it more easy for you to understand, what you
214     had in mind when you wrote a certain script three years ago, and also if
215     some other developer might need to continue working on your scripts one
216     day, you should place as many comments into your scripts as possible. A
217     comment in NKSP is everything that is nested into a an opening and closing
218     pair of curly braces.
219     </p>
220     <code>{ This is a comment. }</code>
221     <p>
222     You cannot only use this to leave some human readable explanations here
223     and there, you might also use such curly braces to quickly disable parts
224     of your scripts for a moment, i.e. when debugging certain things.
225     </p>
226     <code>
227     on init
228     { The following will be prompted to the terminal when the sampler loaded this script. }
229     message("My script loaded.")
230    
231     { This code block is commented out, so these two messages will not be displayed }
232     {
233     message("Another text")
234     message("And another one")
235     }
236     end on
237     </code>
238    
239     <h2>Variables</h2>
240     <p>
241     In order to be able to write more complex and more useful scripts, you
242     also need to remember some data somewhere for being able to use that
243     data at a later point. This can be done by using
244     <i title="A variable is a storage location paired with an associated symbolic name.">
245     variables
246     </i>.
247     We already came across some <i>built-in variables</i>, which are already
248     defined by the sampler for you. To store your own data you need to declare
249     your own <i>user variables</i>, which has the following form:
250     </p>
251     <p>
252     <code>declare $??variable-name?? := ??initial-value??
253     </p>
254     <p>
255     The left hand side's <code>??variable-name??</code> is an arbitrary name
256     you can chose for your variable. That name might consist of English
257     letters A to Z (lower and upper case) and the underscore character "<code>_</code>".
258     Variable names must be unique. So you can neither declare several variables
259     with the same name, nor can you use a name for your variable that is
260     already been reserved by <i>built-in variables</i>.
261     The right hand side's <code>??initial-value??</code> is simply the first
262     value the variable should store right after it was created. You can also
263     omit that.
264     </p>
265     <p>
266     <code>declare $??variable-name??
267     </p>
268     <p>
269     In that case the sampler will automatically assign <code>0</code> for you
270     as the variable's initial value. This way we could for example count the
271     total amount of notes triggered.
272     </p>
273     <code>
274     on init
275     declare $numberOfNotes := 0
276     end on
277    
278     on note
279     $numberOfNotes := $numberOfNotes + 1
280    
281     message("This is the " & $numberOfNotes & "th note triggered so far.")
282     end on
283     </code>
284     <p>
285     In the <code>init</code> event handler we create our own variable
286     <code>$numberOfNotes</code> and assign <code>0</code> to it as its
287     initial value. Like mentioned before, that initial assignment is optional.
288     In the <code>note</code> event handler we then increase the
289     <code>$numberOfNotes</code> variable by one, each time a new note was
290     triggered and then print a message to the terminal with the current total
291     amount of notes that have been triggered so far.
292     </p>
293     <note>
294     NKSP allows you to declare variables in all event handlers, however if
295     you want to keep compatibility with KSP, then you should only
296     declare variables in <code>init</code> event handlers.
297     </note>
298    
299     <h3>Variable Types</h3>
300     <p>
301     There are currently three different variable types, which you can easily
302     recognize upon their first character.
303     </p>
304     <table>
305     <tr>
306     <th>Variable Form</th> <th>Data Type</th> <th>Description</th>
307     </tr>
308     <tr>
309     <td><code>$??variable-name??</code></td> <td>Integer Scalar</td> <td>Stores one single integer number value.</td>
310     </tr>
311     <tr>
312     <td><code>%??variable-name??</code></td> <td>Integer Array</td> <td>Stores a certain amount of integer number values.</td>
313     </tr>
314     <tr>
315     <td><code>@??variable-name??</code></td> <td>String</td> <td>Stores one text string.</td>
316     </tr>
317     </table>
318     <p>
319     So the first character just before the actual variable name, always
320     denotes the data type of the variable. Also note that all variable types
321     share the same variable name space. That means you cannot declare a
322     variable with a name that has already been used to declare a variable of
323     another variable type.
324     </p>
325    
326     <h3>Array Variables</h3>
327     <p>
328     We already used the first two variable types. However we have not seen yet
329     how to declare such array variables. This is the common declaration form
330     for creating your own array variables.
331     </p>
332     <code>
333     on init
334     declare %??variable-name??[??array-size??] := ( ??list-of-values?? )
335     end on
336     </code>
337     <p>
338     So let's say you wanted to create an array variable with the first 12
339     prime numbers, then it might look like this.
340     </p>
341     <code>
342     on init
343     declare %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
344     end on
345     </code>
346     <p>
347     Like with integer variables, assigning some initial values with
348     <code>??list-of-values??</code> is optional. The array
349     declaration form without initial value assignment looks like this.
350     </p>
351     <code>
352     on init
353     declare %??variable-name??[??array-size??]
354     end on
355     </code>
356     <p>
357     When you omit that initial assignment, then all numbers of that array will
358     automatically be initialized with <code>0</code> each. With array
359     variables however, it is always mandatory to provide
360     <code>??array-size??</code> with an array
361     variable declaration, so the sampler can create that array with the
362     requested amount of values when the script is loaded. In contrast to many
363     other programming languages, changing that amount of values of an array
364     variable is not possible after the variable had been declared. That's due
365     to the fact that this language is dedicated to real-time applications, and
366     changing the size of an array variable at runtime would harm real-time
367     stability of the sampler and thus could lead to audio dropouts. So NKSP
368     does not allow you to do that.
369     </p>
370    
371    
372     <h3>String Variables</h3>
373     <p>
374     You might also store text with variables. These are called <i>text string
375     variables</i>, or short: <i>string variables</i>. Let's skip the common declaration
376     form of string variables and let us modify a prior example to just use
377     such kind of variable.
378     </p>
379     <code>
380     on init
381     declare $numberOfNotes
382     declare @firstText := "This is the "
383     declare @secondText
384     end on
385    
386     on note
387     $numberOfNotes := $numberOfNotes + 1
388     @secondText := "th note triggered so far."
389     message(@firstText & $numberOfNotes & @secondText)
390     end on
391     </code>
392     <p>
393     It behaves exactly like the prior example and shall just give you a
394     first idea how to declare and use string variables.
395     </p>
396     <note class="important">
397     Like with the message() function, you should not use string variables
398     with your final production sounds, since it can lead to audio dropouts.
399     You should only use string variables to try out things, and to spot
400     and debug problems with your scripts.
401     </note>
402    
403     <h3>Variable Scope</h3>
404     <p>
405     By default, all variables you declare with NKSP are
406     <i title="A variable that is accessible throughout an entire script.">
407     global variables
408     </i>. That means every event handler can access the data of such a global
409     variable. Furthermore, each instance of an event handler accesses the same
410     data when it is referencing that variable. And the latter fact can be a
411     problem sometimes, which we will outline next.
412     </p>
413     <p>
414     Let's assume you wanted to write an instrument script that shall resemble
415     a simple delay effect. You could do that by writing an note event handler
416     that automatically triggers several new notes for each note being
417     triggered on a MIDI keyboard. The following example demonstrates how that
418     could be achieved.
419     </p>
420 schoenebeck 2872 <note>
421     You need at least LinuxSampler 2.0.0.svn2 or higher for the following
422     example to work as described and as expected. Refer to the notes of the
423     <code>wait()</code> function reference documentation for more
424     informations about this issue.
425 schoenebeck 2732 </note>
426     <code>
427     on init
428     { The amount of notes to play }
429     declare const $delayNotes := 4
430     { Tempo with which the new notes will follow the orignal note }
431     declare const $bpm := 90
432     { Convert BPM to microseconds (duration between the notes) }
433     declare const $delayMicroSeconds := 60 * 1000000 / $bpm
434     { Just a working variable for being used with the while loop below }
435     declare $i
436     { For each successive note we trigger, we will reduce the velocity a bit}
437     declare $velocity
438     end on
439    
440     on note
441     { First initialize the variable $i with 4 each time we enter this event
442     handler, because each time we executed this handler, the variable will be 0 }
443     $i := $delayNotes
444    
445     { Loop which will be executed 4 times in a row }
446     while ($i)
447     { Calculate the velocity for the next note being triggered }
448     $velocity := 127 * $i / ($delayNotes + 1)
449     { Suspend this script for a short moment ... }
450     wait($delayMicroSeconds)
451     { ... and after that short break, trigger a new note. }
452     play_note($EVENT_NOTE, $velocity)
453     { Decrement loop counter $i by one }
454     $i := $i - 1
455     end while
456     end on
457     </code>
458     <p>
459     In this example we used a new keyword <code>const</code>. This additional
460     variable qualifier defines that we don't intend to change this variable
461     after declaration. So if you know beforehand, that a certain variable should
462     remain with a certain value, then you might use the <code>const</code>
463     qualifier to avoid that you i.e. change the value accidently when you
464     modify the script somewhere in future.
465     </p>
466     <p>
467     Now when you trigger one single note on your keyboard with that script,
468     you will hear the additional notes being triggered. And also when you
469     hit another note after a while, everything seems to be fine. However if
470     you start playing quick successive notes, you will notice something goes
471     wrong. The amount of notes being triggered by the script is now incorrect
472     and also the volume of the individual notes triggered by the script is wrong.
473     What's going on?
474     </p>
475     <p>
476     To understand the problem in the last example, let's consider what is
477     happening when executing that script exactly: Each time you play a note
478     on your keyboard, a new instance of the <code>note</code> event handler
479     will be spawned and executed by the sampler. In all our examples so far
480     our scripts were so simple, that in practice only one handler instance
481     was executed at a time. This is different in this case though. Because
482     by calling the <code>wait()</code> function, the respective handler
483     execution instance is paused for a while and in total each handler
484     instance will be executed for more than 2 seconds in this particular
485     example. As a consequence, when
486     you play multiple, successive notes on your keyboard in short time, you
487     will have several instances of the <code>note</code> event handler running
488     simultaniously. And that's where the problem starts. Because by default,
489     as said, all variables are global variables. So the handler instances
490     which are now running in parallel, are all reading and modifying the same
491     data. Thus the individual handler instances will modify the
492     <code>$i</code> and <code>$velocity</code> variables of each other, causing
493     an undesired misbehavior.
494     </p>
495     <note>
496     NKSP's built-in function <code>play_note()</code> allows you to pass
497     between one and four function arguments. For the function arguments you
498     don't provide to a <code>play_note()</code> call, NKSP will automatically
499     use default values. If you want your script to be compatible with KSP,
500     then you should always pass four arguments to that function though.
501     </note>
502    
503     <h3>Polyphonic Variables</h3>
504     <p>
505     As a logical consequence of the previously described data concurrency
506     problem, it would be desirable to have each event handler instance use
507     its own variable instance, so that the individual handler instances stop
508     interfering with each other. For this purpose the so called
509     <i title="A variable which is effectively a separate variable for each event handler instance.">
510     polyphonic variable
511     </i>
512     qualifier exists with NKSP. Declaring such a variable is identical to
513     declaring a regular variable, just that you add the keyword <code>polyphonic</code>.
514     </p>
515     <code>
516     declare polyphonic $??variable-name??
517     </code>
518     <p>
519     So to fix the bug in our previous example, we simply make the variables
520     <code>$i</code> and <code>$velocity</code> polyphonic variables.
521     </p>
522     <code>
523     on init
524     { The amount of notes to play }
525     declare const $delayNotes := 4
526     { Tempo with which the new notes will follow the orignal note }
527     declare const $bpm := 90
528     { Convert BPM to microseconds (duration between the notes) }
529     declare const $delayMicroSeconds := 60 * 1000000 / $bpm
530     { Just a working variable for being used with the while loop below }
531     declare polyphonic $i { < --- NOW POLYPHONIC !!! }
532     { For each successive note we trigger, we will reduce the velocity a bit}
533     declare polyphonic $velocity { < --- NOW POLYPHONIC !!! }
534     end on
535    
536     on note
537     { First initialize the variable $i with 4 each time we enter this event
538     handler, because each time we executed this handler, the variable will be 0 }
539     $i := $delayNotes
540    
541     { Loop which will be executed 4 times in a row }
542     while ($i)
543     { Calculate the velocity for the next note being triggered }
544     $velocity := 127 * $i / ($delayNotes + 1)
545     { Suspend this script for a short moment ... }
546     wait($delayMicroSeconds)
547     { ... and after that short break, trigger a new note. }
548     play_note($EVENT_NOTE, $velocity)
549     { Decrement loop counter $i by one }
550     $i := $i - 1
551     end while
552     end on
553     </code>
554     <p>
555     And that's it! The script works now as intended. Now you might wonder, why
556     are variables not <i>polyphonic</i> by default? Isn't that more common and
557     wouldn't that be more safer than using global variables by default? The reason is that
558     a polyphonic variable consumes a lot more memory than a regular (global) variable.
559     That's because for each polyphonic variable, the sampler has to allocate
560     in advance (when the script is loaded) as many instances of that
561     polyphonic variable as there are maximum events
562     allowed with the sampler. So that's a lot! Considering that today's
563     computers have plenty of RAM this might be a theoretical aspect, but in the
564     end: this default scope of variables was already like this with <i>KSP</i>
565     so we are also doing it like this with NKSP for compatibility reasons.
566     </p>
567     <p>
568     Please note that the <i>polyphonic</i> qualifier only exists for integer
569     variables. So you cannot declare polyphonic string variables, nor can you
570     declare polyphonic array variables. Like in the previous explanation,
571     this is due to the fact that it would consume a huge amount of memory
572     for such variables. And with string variables and array variables, the
573     required amount of memory would be much higher than with simple integer
574     variables.
575     </p>
576     <p>
577     As summary, the following are guideline rules describing when you should
578     use the polyphonic qualifier for a certain variable. You should declare
579     a particular variable polyphonic if one (or even both) of the following two
580     conditions apply to that variable.
581     </p>
582     <ol>
583     <li>
584     If you call the <code>wait()</code> function within your event
585     handlers and the respective variable is modified and read before
586     and after at least one of the individual <code>wait()</code> calls.
587     </li>
588     <li>
589     If you have loops that might run for a very long time, while accessing
590     the respective variable in between. That's because if your script is
591     running consecutively for too long, the sampler will automatically suspend your
592     script for a while to avoid your script becoming a real-time stability
593     hazard for the sampler. Your script will then automatically be resumed
594     after a short moment by the sampler, so effectively this is similar to
595     something like an "automated" <code>wait()</code> function call by
596     the sampler.
597     </li>
598     </ol>
599     <p>
600     In all other cases you should rather use regular (global) variables instead.
601     But keep in mind that you might need to re-assign a certain value for
602     some global variables when you enter the respective event handler, just
603     like we did with <code>$i := $delayNotes</code> right from the start
604     during discussion of the previous example script.
605     </p>
606 schoenebeck 2763 <p>
607     There is another special aspect regarding the variable scope of polyphonic
608     variables: <code>note</code> handlers and <code>release</code> handlers of
609     the same script share the same polyphonic variable scope, that means you
610     may pass data from a particular note's <code>note</code> handler to its
611     <code>release</code> handler by using the same polyphonic variable name.
612     </p>
613 schoenebeck 2732
614     <h2>Control Structures</h2>
615     <p>
616     A computer is more than a calculator that adds numbers and stores them
617     somewhere. One of the biggest strength of a computer, which makes it
618     such powerful, is the ability to do different things depending on various
619     conditions. For example your computer might clean up your hard drive
620     while you are not sitting in front of it, and it might immediately stop
621     doing so when you need all its resources to cut your latest video which
622     you just shot.
623     </p>
624     <p>
625     In order to do that for you, a computer program allows you to define
626     conditions and a list of instructions the computer shall
627     perform for you under those individual conditions. These kinds of
628     software mechanisms are called <i>Control Structures</i>.
629     </p>
630    
631     <h3>if Branches</h3>
632     <p>
633     The most fundamental control structure are <i>if branches</i>, which has
634     the following general form.
635     </p>
636     <code>
637     if (??condition??)
638    
639     ??statements??
640    
641     end if
642     </code>
643     <p>
644     The specified <code>??condition??</code> is evaluated each time script
645     execution reaches this control block. The condition can for example be
646     the value of a variable, some arithmetic expression, a function call or
647     a combination of them. In all cases the sampler expects the
648     <code>??condition??</code> expression to evaluate to some numeric
649     (or boolean) value. If the evaluated number is exactly <code>0</code> then
650     the condition is interpreted to be <i>false</i> and thus the list of
651     <code>??statements??</code> is not executed. If the evaluated value is any
652     other value than <code>0</code> then the condition is interpreted to be
653     <i>true</i> and accordingly the list of <code>??statements??</code> will be
654     executed.
655     </p>
656     <p>
657     Alternatively you might also specify a list of instructions which shall be
658     executed when the condition is <i>false</i>.
659     </p>
660     <code>
661     if (??condition??)
662    
663     ??statements-when-true??
664    
665     else
666    
667     ??statements-when-false??
668    
669     end if
670     </code>
671     <p>
672     In this case the first list of statements is executed when the
673     <code>??condition??</code> evaluated to <i>true</i>, otherwise the second
674     list of statements is executed instead.
675     </p>
676     <p>
677     Once again, let's get back to the example of counting triggered notes.
678     You might have noticed that it did not output correct English for the
679     first three notes. Let's correct this now.
680     </p>
681     <code>
682     on init
683     declare $numberOfNotes
684     declare @postfix
685     end on
686    
687     on note
688     $numberOfNotes := $numberOfNotes + 1
689    
690     if ($numberOfNotes == 1)
691     @postfix := "st"
692     else
693     if ($numberOfNotes == 2)
694     @postfix := "nd"
695     else
696     if ($numberOfNotes == 3)
697     @postfix := "rd"
698     else
699     @postfix := "th"
700     end if
701     end if
702     end if
703    
704     message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
705     end on
706     </code>
707     <p>
708     We are now checking the value of <code>$numberOfNotes</code> before we
709     print out a message. If <code>$numberOfNotes</code> equals one, then we
710     assign the string <code>"st"</code> to the variable <code>@postfix</code>,
711     if <code>$numberOfNotes</code> equals 2 instead we assign the string
712     <code>"nd"</code> instead, if it equals 3 instead we assign
713     <code>"rd"</code>, in all other cases we assign the string
714     <code>"th"</code>. And finally we assemble the text message to be
715     printed out to the terminal on line 23.
716     </p>
717    
718     <h3>Select Case Branches</h3>
719     <p>
720     The previous example now outputs the numbers in correct English. But the
721     script code looks a bit bloated, right? That's why there is a short hand
722     form.
723     </p>
724     <code>
725     select ??expression??
726    
727     case ??integer-1??
728    
729     ??statements-1??
730    
731    
732     case ??integer-2??
733    
734     ??statements-2??
735    
736     .
737     .
738     .
739     end select
740     </code>
741     <p>
742     The provided <code>??expression??</code> is first evaluated to an integer
743     value. Then this value is compared to the integer values of the nested
744     <code>case</code> lines. So it first compares the evaluated value of
745     <code>??expression??</code> with <code>??integer-1??</code>, then it
746     compares it with <code>??integer-2??</code>, and so on. The first integer
747     number that matches with the evaluated value of <code>??expression??</code>,
748     will be interpreted as being the current valid condition. So if
749     <code>??expression??</code> equals <code>??integer-1??</code>,
750     then <code>??statements-1??</code> will be executed, otherwise if
751     <code>??expression??</code> equals <code>??integer-2??</code>,
752     then <code>??statements-2??</code> will be executed, and so on.
753     </p>
754     <p>
755     Using a select-case construct, our previous example would look like follows.
756     </p>
757     <code>
758     on init
759     declare $numberOfNotes
760     declare @postfix
761     end on
762    
763     on note
764     $numberOfNotes := $numberOfNotes + 1
765     @postfix := "th"
766    
767     select $numberOfNotes
768     case 1
769     @postfix := "st"
770     case 2
771     @postfix := "nd"
772     case 3
773     @postfix := "rd"
774 schoenebeck 3119 end select
775 schoenebeck 2732
776     message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
777     end on
778     </code>
779     <note>
780     If you like, you can also put parentheses around the select expression,
781     like <code>select (??expression??)</code>. Some developers familiar with
782     other programming languages might prefer this style. However if you want
783     to keep compatibility with KSP, you should not use parentheses for
784     select expressions.
785     </note>
786     <p>
787     The amount
788     of case conditions you add to such select-case blocks is completely up
789     to you. Just remember that the case conditions will be compared one by one,
790     from top to down. The latter can be important when you define a case line
791     that defines a value range. So for instance the following example will
792     not do what was probably intended.
793     </p>
794     <code>
795     on init
796     declare $numberOfNotes
797     end on
798    
799     on note
800     $numberOfNotes := $numberOfNotes + 1
801    
802     select $numberOfNotes
803     case 1 to 99
804     message("Less than 100 notes triggered so far")
805     exit
806     case 1
807     message("First note was triggered!") { Will never be printed ! }
808     exit
809     case 2
810     message("Second note was triggered!") { Will never be printed ! }
811     exit
812     case 3
813     message("Third note was triggered!") { Will never be printed ! }
814     exit
815 schoenebeck 3119 end select
816 schoenebeck 2732
817     message("Wow, already the " & $numberOfNotes & "th note triggered.")
818     end on
819     </code>
820     <p>
821     You probably get the idea what this script "should" do. For the 1st note
822     it should print <code>"First note was triggered!"</code>, for the 2nd
823     note it should print <code>"Second note was triggered!"</code>, for the 3rd
824     note it should print <code>"Third note was triggered!"</code>, for the 4th
825     up to 99th note it should print <code>"Less than 100 notes triggered so far"</code>,
826     and starting from the 100th note and all following ones, it should print
827     the precise note number according to line 23. However, it doesn't!
828     </p>
829     <p>
830     To correct this problem, you need to move the first case block to the end,
831     like follows.
832     </p>
833     <code>
834     on init
835     declare $numberOfNotes
836     end on
837    
838     on note
839     $numberOfNotes := $numberOfNotes + 1
840    
841     select $numberOfNotes
842     case 1
843     message("First note was triggered!")
844     exit
845     case 2
846     message("Second note was triggered!")
847     exit
848     case 3
849     message("Third note was triggered!")
850     exit
851     case 1 to 99
852     message("Less than 100 notes triggered so far")
853     exit
854 schoenebeck 3119 end select
855 schoenebeck 2732
856     message("Wow, already the " & $numberOfNotes & "th note triggered.")
857     end on
858     </code>
859     <p>
860     Or you could of course fix the questioned case range from <code>case 1 to 99</code>
861     to <code>case 4 to 99</code>. Both solutions will do.
862     </p>
863     <p>
864     We also used the <i>built-in function</i> <code>exit()</code> in the
865     previous example. You can use it to stop execution at that point of your
866     script. In the previous example it prevents multiple messages to be
867     printed to the terminal.
868     </p>
869     <note class="important">
870     The <code>exit()</code> function only stops execution of the <b>current</b>
871     event handler instance! It does <b>not</b> stop execution of other
872     instances of the same event handler, nor does it stop execution of other
873     handlers of other event types, and especially it does <b>not</b> stop or
874     prevent further or future execution of your entire script! In other words,
875     you should rather see this function as a return statement, in case you are
876     familiar with other programming languages already.
877     </note>
878    
879     <h3>while Loops</h3>
880     <p>
881     Another fundamental control construct of program flow are loops.
882     You can use so called
883     <i title="Repeats a given list of instructions until the defined condition turns false.">
884     while loops
885     </i>
886     with NKSP.
887     </p>
888     <code>
889     while (??condition??)
890    
891     ??statements??
892    
893     end while
894     </code>
895     <p>
896     A while loop is entered if the provided <code>??condition??</code>
897     expression evaluates to <i>true</i> and will then continue to execute
898     the given list of <code>??statements??</code> down to the end of the statements
899     list. The <code>??condition??</code> is re-evaluated each time execution
900     reached the end of the <code>??statements??</code> list and according to
901     that latest evaluated <code>??condition??</code> value at that point, it
902     will or will not repeat executing the statements again. If the condition
903     turned <i>false</i> instead, it will leave the loop and continue executing
904     statements that follow after the while loop block.
905     </p>
906     <p>
907     The next example will print the same message three times in a row to the
908     terminal, right after the script had been loaded by the sampler.
909     </p>
910     <code>
911     on init
912     declare $i := 3
913    
914     while ($i)
915     message("Print this three times.")
916     $i := $i - 1
917     end while
918     end on
919     </code>
920     <p>
921     When the while loop is reached for the first time in this example, the
922     condition value is <code>3</code>. And as we learned before, all integer
923     values that are not <code>0</code> are interpreted as being a <i>true</i> condition.
924     Accordingly the while loop is entered, the message is printed to the
925     terminal and the variable <code>$i</code> is reduced by one. We reached
926     the end of the loop's statements list, so it is now re-evaluating the
927     condition, which is now the value <code>2</code> and thus the loop
928     instructions are executed again. That is repeated until the loop was
929     executed for the third time. The variable <code>$i</code> is now
930     <code>0</code>, so the loop condition turned finally to <i>false</i> and the
931     loop is thus left at that point and the text message was printed
932     three times in total.
933     </p>
934 schoenebeck 3061
935     <h3>User Functions</h3>
936     <p>
937     We already came across various built-in functions, which you may call
938     by your scripts to perform certain tasks or behavior which is already
939 schoenebeck 3062 provided for you by the sampler. NKSP also allows you to write your
940     own functions, which you then may call from various places of your
941     script.
942     <p>
943     </p>
944     When working on larger scripts, you
945 schoenebeck 3061 may notice that you easily get to the point where you may have to
946     duplicate portions of your script code, since there are certain things
947     that you may have to do again and again in different parts of your script.
948     Software developers usually try to avoid such code duplications to
949 schoenebeck 3062 keep the overall amount of code as small as possible, since the
950     overall amount of code would bloat quickly and would
951 schoenebeck 3061 make the software very hard to maintain. One way for you to avoid such
952     script code duplications with NKSP is to write so called <i>User Functions</s>.
953     </p>
954     <p>
955     Let's assume you wanted to create a simple stuttering effect. You may do so
956     like in the following example.
957     </p>
958     <code>
959     on note
960     while (1)
961     wait(200000)
962     if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
963     exit()
964     end if
965     change_vol($EVENT_ID, -20000) { Reduce volume by 20 dB. }
966     wait(200000)
967     if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
968     exit()
969     end if
970     change_vol($EVENT_ID, 0) { Increase volume to 0 dB. }
971     end while
972     end on
973     </code>
974     <p>
975     This script will run an endless loop for each note being triggered.
976 schoenebeck 3064 Every <code lang="none">200ms</code> it will turn the volume alternatingly down and
977 schoenebeck 3063 up to create the audible stuttering effect. After each <code lang="nksp">wait()</code>
978 schoenebeck 3061 call it calls <code>event_status($EVENT_ID)</code> to check whether
979     this note is still alive, and as soon as the note died, it will stop
980     execution of the script instance by calling <code>exit()</code>. The latter
981 schoenebeck 3064 is important in this example, because otherwise the script execution instances would
982 schoenebeck 3061 continue to run in this endless loop forever, even after the respectives
983 schoenebeck 3064 notes are gone. Which would let your CPU usage to increase with every new note
984     and would never decrease again.
985 schoenebeck 3061 This behavior of the sampler is not a bug, it is intended, since there may
986     also be cases where you want to do certain things by script even after the
987     respective notes are dead and gone. However as you can see, that script is
988     using the same portions of script code twice. To avoid that, you could also
989     write the same script with a user function like this:
990     </p>
991     <code>
992     function pauseMyScript
993     wait(200000)
994     if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
995     exit()
996     end if
997     end function
998 schoenebeck 2732
999 schoenebeck 3061 on note
1000     while (1)
1001     call pauseMyScript
1002     change_vol($EVENT_ID, -20000) { Reduce volume by 20 dB. }
1003     call pauseMyScript
1004     change_vol($EVENT_ID, 0) { Increase volume back to 0 dB. }
1005     end while
1006     end on
1007     </code>
1008     <p>
1009     The script became in this simple example only slightly smaller, but it also
1010 schoenebeck 3062 became easier to read and behaves identically to the previous solution.
1011     And in practice, with a more complex script, you can
1012 schoenebeck 3061 reduce the overall amount of script code a lot this way. You can choose any
1013     name for your own user functions, as long as the name is not already
1014     reserved by a built-in function. Note that for calling a user function,
1015     you must always precede the actual user function name with the
1016     <code>call</code> keyword. Likewise you may however not use the
1017     <code>call</code> keyword for calling any built-in function. So that
1018     substantially differs calling built-in functions from calling user functions.
1019     </p>
1020    
1021 schoenebeck 2732 <h2>Operators</h2>
1022     <p>
1023     A programming language provides so called <i>operators</i> to perform
1024     certain kinds of transformations of data placed next to the operators.
1025     These are the operators available with NKSP.
1026     </p>
1027    
1028     <h3>Arithmetic Operators</h3>
1029     <p>
1030     These are the most basic mathematical operators, which allow to add,
1031     subtract, multiply and divide integer values with each other.
1032     </p>
1033     <code>
1034     on init
1035     message("4 + 3 is " & 4 + 3) { Add }
1036     message("4 - 3 is " & 4 - 3) { Subtract }
1037     message("4 * 3 is " & 4 * 3) { Multiply }
1038     message("35 / 5 is " & 35 / 5) { Divide }
1039     message("35 mod 5 is " & 35 mod 5) { Remainder of Division ("modulo") }
1040     end on
1041     </code>
1042     <p>
1043     You may either use direct integer literal numbers like used in the upper
1044     example, or you can use integer number variables or integer array variables.
1045     </p>
1046    
1047     <h3>Boolean Operators</h3>
1048     <p>
1049     To perform logical transformations of <i>boolean</i> data, you may use the
1050 schoenebeck 2936 following logical operators:
1051 schoenebeck 2732 </p>
1052     <code>
1053     on init
1054     message("1 and 1 is " & 1 and 1) { logical "and" }
1055     message("1 and 0 is " & 1 and 0) { logical "and" }
1056     message("1 or 1 is " & 1 or 1) { logical "or" }
1057     message("1 or 0 is " & 1 or 0) { logical "or" }
1058     message("not 1 is " & not 1) { logical "not" }
1059     message("not 0 is " & not 0) { logical "not" }
1060     end on
1061     </code>
1062     <p>
1063 schoenebeck 2936 Keep in mind that with logical operators shown above,
1064     all integer values other than <code>0</code>
1065 schoenebeck 2732 are interpreted as boolean <i>true</i> while an integer value of
1066     precisely <code>0</code> is interpreted of being boolean <i>false</i>.
1067     </p>
1068 schoenebeck 2936 <p>
1069     So the logical operators shown above always look at numbers at a whole.
1070     Sometimes however you might rather need to process numbers bit by bit. For
1071     that purpose the following bitwise operators exist.
1072     </p>
1073     <code>
1074     on init
1075     message("1 .and. 1 is " & 1 .and. 1) { bitwise "and" }
1076     message("1 .and. 0 is " & 1 .and. 0) { bitwise "and" }
1077     message("1 .or. 1 is " & 1 .or. 1) { bitwise "or" }
1078     message("1 .or. 0 is " & 1 .or. 0) { bitwise "or" }
1079     message(".not. 1 is " & .not. 1) { bitwise "not" }
1080     message(".not. 0 is " & .not. 0) { bitwise "not" }
1081     end on
1082     </code>
1083     <p>
1084     Bitwise operators work essentially like logical operators, with the
1085     difference that bitwise operators compare each bit independently.
1086     So a bitwise <code>.and.</code> operator for instance takes the 1st bit
1087     of the left hand's side value, the 1st bit of the right hand's side value,
1088     compares the two bits logically and then stores that result as 1st bit of
1089     the final result value, then it takes the 2nd bit of the left hand's side value
1090     and the 2nd bit of the right hand's side value, compares those two bits logically
1091     and then stores that result as 2nd bit of the final result value, and so on.
1092     </p>
1093    
1094 schoenebeck 2732
1095     <h3>Comparison Operators</h3>
1096     <p>
1097     For branches in your program flow, it is often required to compare data
1098     with each other. This is done by using comparison operators, enumerated
1099     below.
1100     </p>
1101     <code>
1102     on init
1103     message("Relation 3 < 4 -> " & 3 < 4) { "smaller than" comparison }
1104     message("Relation 3 > 4 -> " & 3 > 4) { "greater than" comparison }
1105     message("Relation 3 <= 4 -> " & 3 <= 4) { "smaller or equal than" comparison}
1106     message("Relation 3 >= 4 -> " & 3 >= 4) { "greater or equal than" comparison}
1107     message("Relation 3 # 4 -> " & 3 # 4) { "not equal to" comparison}
1108     message("Relation 3 = 4 -> " & 3 = 4) { "is equal to" comparison}
1109     end on
1110     </code>
1111     <p>
1112     All these operations yield in a <i>boolean</i> result which could then
1113     by used i.e. with <code>if</code> or <code>while</code> loop statements.
1114     </p>
1115    
1116     <h3>String Operators</h3>
1117     <p>
1118     Last but not least, there is exactly one operator for text string data;
1119     the string concatenation operator <code>&</code>, which
1120     combines two text strings with each other.
1121     </p>
1122     <code>
1123     on init
1124     declare @s := "foo" & " bar"
1125     message(@s)
1126     end on
1127     </code>
1128     <p>
1129     We have used it now frequently in various examples before.
1130     </p>
1131    
1132     <h2>Preprocessor Statements</h2>
1133     <p>
1134     Similar to low-level programming languages like C, C++, Objective C
1135     and the like, NKSP supports a set of so called preprocessor statements.
1136     These are essentially "instructions" which are "executed" or rather
1137     processed, before (and only before) the script is executed by the sampler,
1138     and even before the script is parsed by the actual NKSP language parser.
1139     You can think of a preprocessor as a very primitive parser, which is the
1140     first one getting in touch with your script, it modifies the script code
1141     if requested by your preprocessor statements in the script, and then
1142     passes the (probably) modified script to the actual NKSP language parser.
1143     </p>
1144     <p>
1145     When we discussed <a href="#comments">comments</a> in NKSP scripts before,
1146     it was suggested that you might comment out certain code parts to disable
1147     them for a while during development of scripts. It was also suggested
1148     during this language tour that you should not use string variables or use
1149     the <code>message()</code> function with your final production sounds.
1150     However those are very handy things during development of your instrument
1151     scripts. You might even have a bunch of additional code in your scripts
1152     which only satisfies the purpose to make debugging of your scripts more easy,
1153     which however wastes on the other hand precious CPU time. So what do you
1154     do? Like suggested, you could comment out the respective code sections as
1155     soon as development of your script is completed. But then one day you
1156     might continue to improve your scripts, and the debugging code would be
1157     handy, so you would uncomment all the relevant code sections to get them
1158     back. When you think about this, that might be quite some work each time.
1159     Fortunately there is an alternative by using preprocessor statements.
1160     </p>
1161    
1162     <h3>Set a Condition</h3>
1163     <p>
1164     First you need to set a preprocessor condition in your script. You can do
1165     that like this:
1166     </p>
1167     <code>
1168     SET_CONDITION(??condition-name??)
1169     </code>
1170     <p>
1171     This preprocessor "condition" is just like some kind of
1172     <i title="A variable which can only have two states: i.e. true or false.">
1173     boolean variable
1174     </i>
1175     which is only available to the preprocessor and by using
1176     <code>SET_CONDITION(??condition-name??)</code>, this is like setting this
1177     preprocessor condition to <i>true</i>. Like with regular script
1178     variables, a preprocessor condition name can be chosen quite arbitrarily
1179     by you. But again, there are some pre-defined preprocessor conditions
1180     defined by the sampler for you. So you can only set a condition name here
1181     which is not already reserved by a built-in preprocessor condition. Also
1182     you shall not set a condition in your script again if you have already set it
1183     before somewhere in your script. The NKSP preprocessor will ignore setting
1184     a condition a 2nd time and will just print a warning when the script is
1185     loaded, but you should take care of it, because it might be a cause for
1186     some bug.
1187     </p>
1188    
1189     <h3>Reset a Condition</h3>
1190     <p>
1191     To clear a condition in your script, you might reset the condition like so:
1192     </p>
1193     <code>
1194     RESET_CONDITION(??condition-name??)
1195     </code>
1196     <p>
1197     This is like setting that preprocessor condition back to <i>false</i> again.
1198     You should only reset a preprocessor condition that way if you did set it
1199     with <code>SET_CONDITION(??condition-name??)</code> before. Trying to
1200     reset a condition that has not been set before, or trying to reset a
1201     condition that has already been reset, will both be ignored by the samlper,
1202     but again you will get a warning, and you should take care about it.
1203     </p>
1204    
1205     <h3>Conditionally Using Code</h3>
1206     <p>
1207     Now what do you actually do with such preprocessor conditions? You can use
1208     them for the NKSP language parser to either
1209     </p>
1210     <ul>
1211     <li>use certain parts of your code</i>
1212     <li><b>and</b> / <b>or</b> to ignore certain parts of your code</i>
1213     </ul>
1214     <p>
1215     You can achieve that by wrapping NKSP code parts into a pair of either
1216     </p>
1217     <code>
1218     USE_CODE_IF(??condition-name??)
1219    
1220     ??some-NKSP-code-goes-here??
1221    
1222     END_USE_CODE
1223     </code>
1224     <p>
1225     preprocessor statements, or between
1226     </p>
1227     <code>
1228     USE_CODE_IF_NOT(??condition-name??)
1229    
1230     ??some-NKSP-code-goes-here??
1231    
1232     END_USE_CODE
1233     </code>
1234     <p>
1235     statements. In the first case, the NKSP code portion is used by the NKSP
1236     language parser if the given preprocessor <code>??condition-name??</code> is set
1237     (that is if condition is <i>true</i>).
1238     If the condition is not set, the NKSP code portion in between is
1239     completely ignored by the NKSP language parser.
1240     </p>
1241     <p>
1242     In the second case, the NKSP code portion is used by the NKSP
1243     language parser if the given preprocessor <code>??condition-name??</code> is <b>not</b> set
1244     (or was reset)
1245     (that is if condition is <i>false</i>).
1246     If the condition is set, the NKSP code portion in between is
1247     completely ignored by the NKSP language parser.
1248     </p>
1249     <p>
1250     Let's look at an example how to use that to define conditional debugging
1251     code.
1252     </p>
1253     <code>
1254     SET_CONDITION(DEBUG_MODE)
1255    
1256     on init
1257     declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1258     declare $i
1259    
1260     USE_CODE_IF(DEBUG_MODE)
1261     message("This script has just been loaded.")
1262    
1263     $i := 0
1264     while ($i < num_elements(%primes))
1265     message("Prime " & $i & " is " & %primes[$i])
1266     $i := $i + 1
1267     end while
1268     END_USE_CODE
1269     end on
1270    
1271     on note
1272     USE_CODE_IF(DEBUG_MODE)
1273     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1274     END_USE_CODE
1275     end on
1276    
1277     on release
1278     USE_CODE_IF(DEBUG_MODE)
1279     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1280     END_USE_CODE
1281     end on
1282    
1283     on controller
1284     USE_CODE_IF(DEBUG_MODE)
1285     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1286     END_USE_CODE
1287     end on
1288     </code>
1289     <p>
1290     The <i>built-in function</i> <code>num_elements()</code> used above, can
1291     be called to obtain the size of an array variable at runtime.
1292     As this script looks now, the debug messages will be printed out. However
1293     it requires you to just remove the first line, or to comment out the first
1294     line, in order to disable all debug code portions in just a second:
1295     </p>
1296     <code>
1297     { Setting the condition is commented out, so our DEBUG_MODE is disabled now. }
1298     { SET_CONDITION(DEBUG_MODE) }
1299    
1300     on init
1301     declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1302     declare $i
1303    
1304     USE_CODE_IF(DEBUG_MODE) { Condition is not set, so this entire block will be ignored now. }
1305     message("This script has just been loaded.")
1306    
1307     $i := 0
1308     while ($i < num_elements(%primes))
1309     message("Prime " & $i & " is " & %primes[$i])
1310     $i := $i + 1
1311     end while
1312     END_USE_CODE
1313     end on
1314    
1315     on note
1316     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1317     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1318     END_USE_CODE
1319     end on
1320    
1321     on release
1322     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1323     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1324     END_USE_CODE
1325     end on
1326    
1327     on controller
1328     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1329     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1330     END_USE_CODE
1331     end on
1332     </code>
1333     <p>
1334     Now you might say, you could also achieve that by declaring and using
1335     a regular NKSP variable. That's correct, but there are two major
1336     advantages by using preprocessor statements.
1337     </p>
1338     <ol>
1339     <li>
1340     <b>Saving Resources</b> -
1341     The preprocessor conditions are only processed before the script is
1342     loaded into the NKSP parser. So in contrast to using NKSP variables,
1343     the preprocessor solution does not waste any CPU time or memory
1344     resources while executing the script. That also means that variable
1345     declarations can be disabled with the preprocessor this way
1346     and thus will also safe resources.
1347     </li>
1348     <li>
1349     <b>Cross Platform Support</b> -
1350     Since the code portions filtered out by the preprocessor never make it
1351     into the NKSP language parser, those filtered code portions might also
1352     contain code which would have lead to parser errors. For example you
1353     could use a built-in preprocessor condition to check whether your script
1354     was loaded into LinuxSampler or rather into another sampler. That way
1355     you could maintain one script for both platforms: NKSP and KSP.
1356     Accordingly you could
1357     also check a built-in variable to obtain the version of the sampler in
1358     order to enable or disable code portions of your script that might
1359     use some newer script features of the sampler which don't exist in older
1360     version of the sampler.
1361     </li>
1362     </ol>
1363     <p>
1364     As a rule of thumb: if there are things that you could move from your
1365     NKSP executed programming code out to the preprocessor, then you should
1366     use the preprocessor instead for such things. And like stated above,
1367     there are certain things which you can only achieve with the preprocessor.
1368     </p>
1369    
1370     <h2>What Next?</h2>
1371     <p>
1372     You have completed the introduction of the NKSP real-time instrument
1373     script language at this point. You can now dive into the details of the
1374     NKSP language by moving on to the
1375     <a href="nksp_reference.html">NKSP reference documentation</a>.
1376     Which provides you an overview and quick access to the details of all
1377     built-in functions, built-in variables and more.
1378     </p>
1379    
1380     </body>
1381     </html>

  ViewVC Help
Powered by ViewVC