/[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 3608 - (hide annotations) (download) (as text)
Wed Sep 18 13:24:28 2019 UTC (4 years, 6 months ago) by schoenebeck
File MIME type: text/html
File size: 64097 byte(s)
- Minor updates to NKSP language tour.

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 schoenebeck 3191 letters A to Z (lower and upper case), digits (<code>0</code> to <code>9</code>),
258     and the underscore character "<code>_</code>".
259 schoenebeck 2732 Variable names must be unique. So you can neither declare several variables
260     with the same name, nor can you use a name for your variable that is
261     already been reserved by <i>built-in variables</i>.
262     The right hand side's <code>??initial-value??</code> is simply the first
263     value the variable should store right after it was created. You can also
264     omit that.
265     </p>
266     <p>
267     <code>declare $??variable-name??
268     </p>
269     <p>
270     In that case the sampler will automatically assign <code>0</code> for you
271     as the variable's initial value. This way we could for example count the
272     total amount of notes triggered.
273     </p>
274     <code>
275     on init
276     declare $numberOfNotes := 0
277     end on
278    
279     on note
280     $numberOfNotes := $numberOfNotes + 1
281    
282     message("This is the " & $numberOfNotes & "th note triggered so far.")
283     end on
284     </code>
285     <p>
286     In the <code>init</code> event handler we create our own variable
287     <code>$numberOfNotes</code> and assign <code>0</code> to it as its
288     initial value. Like mentioned before, that initial assignment is optional.
289     In the <code>note</code> event handler we then increase the
290     <code>$numberOfNotes</code> variable by one, each time a new note was
291     triggered and then print a message to the terminal with the current total
292     amount of notes that have been triggered so far.
293     </p>
294     <note>
295     NKSP allows you to declare variables in all event handlers, however if
296     you want to keep compatibility with KSP, then you should only
297     declare variables in <code>init</code> event handlers.
298     </note>
299    
300     <h3>Variable Types</h3>
301     <p>
302     There are currently three different variable types, which you can easily
303     recognize upon their first character.
304     </p>
305     <table>
306     <tr>
307     <th>Variable Form</th> <th>Data Type</th> <th>Description</th>
308     </tr>
309     <tr>
310     <td><code>$??variable-name??</code></td> <td>Integer Scalar</td> <td>Stores one single integer number value.</td>
311     </tr>
312     <tr>
313     <td><code>%??variable-name??</code></td> <td>Integer Array</td> <td>Stores a certain amount of integer number values.</td>
314     </tr>
315     <tr>
316     <td><code>@??variable-name??</code></td> <td>String</td> <td>Stores one text string.</td>
317     </tr>
318     </table>
319     <p>
320     So the first character just before the actual variable name, always
321     denotes the data type of the variable. Also note that all variable types
322     share the same variable name space. That means you cannot declare a
323     variable with a name that has already been used to declare a variable of
324     another variable type.
325     </p>
326    
327     <h3>Array Variables</h3>
328     <p>
329     We already used the first two variable types. However we have not seen yet
330     how to declare such array variables. This is the common declaration form
331     for creating your own array variables.
332     </p>
333     <code>
334     on init
335     declare %??variable-name??[??array-size??] := ( ??list-of-values?? )
336     end on
337     </code>
338     <p>
339     So let's say you wanted to create an array variable with the first 12
340     prime numbers, then it might look like this.
341     </p>
342     <code>
343     on init
344     declare %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
345     end on
346     </code>
347     <p>
348     Like with integer variables, assigning some initial values with
349     <code>??list-of-values??</code> is optional. The array
350     declaration form without initial value assignment looks like this.
351     </p>
352     <code>
353     on init
354     declare %??variable-name??[??array-size??]
355     end on
356     </code>
357     <p>
358     When you omit that initial assignment, then all numbers of that array will
359     automatically be initialized with <code>0</code> each. With array
360     variables however, it is always mandatory to provide
361     <code>??array-size??</code> with an array
362     variable declaration, so the sampler can create that array with the
363     requested amount of values when the script is loaded. In contrast to many
364     other programming languages, changing that amount of values of an array
365     variable is not possible after the variable had been declared. That's due
366     to the fact that this language is dedicated to real-time applications, and
367     changing the size of an array variable at runtime would harm real-time
368     stability of the sampler and thus could lead to audio dropouts. So NKSP
369     does not allow you to do that.
370     </p>
371    
372    
373     <h3>String Variables</h3>
374     <p>
375     You might also store text with variables. These are called <i>text string
376     variables</i>, or short: <i>string variables</i>. Let's skip the common declaration
377     form of string variables and let us modify a prior example to just use
378     such kind of variable.
379     </p>
380     <code>
381     on init
382     declare $numberOfNotes
383     declare @firstText := "This is the "
384     declare @secondText
385     end on
386    
387     on note
388     $numberOfNotes := $numberOfNotes + 1
389     @secondText := "th note triggered so far."
390     message(@firstText & $numberOfNotes & @secondText)
391     end on
392     </code>
393     <p>
394     It behaves exactly like the prior example and shall just give you a
395     first idea how to declare and use string variables.
396     </p>
397     <note class="important">
398     Like with the message() function, you should not use string variables
399     with your final production sounds, since it can lead to audio dropouts.
400     You should only use string variables to try out things, and to spot
401     and debug problems with your scripts.
402     </note>
403    
404     <h3>Variable Scope</h3>
405     <p>
406     By default, all variables you declare with NKSP are
407     <i title="A variable that is accessible throughout an entire script.">
408     global variables
409     </i>. That means every event handler can access the data of such a global
410     variable. Furthermore, each instance of an event handler accesses the same
411     data when it is referencing that variable. And the latter fact can be a
412     problem sometimes, which we will outline next.
413     </p>
414     <p>
415     Let's assume you wanted to write an instrument script that shall resemble
416     a simple delay effect. You could do that by writing an note event handler
417     that automatically triggers several new notes for each note being
418     triggered on a MIDI keyboard. The following example demonstrates how that
419     could be achieved.
420     </p>
421     <code>
422     on init
423     { The amount of notes to play }
424     declare const $delayNotes := 4
425     { Tempo with which the new notes will follow the orignal note }
426     declare const $bpm := 90
427     { Convert BPM to microseconds (duration between the notes) }
428     declare const $delayMicroSeconds := 60 * 1000000 / $bpm
429     { Just a working variable for being used with the while loop below }
430     declare $i
431     { For each successive note we trigger, we will reduce the velocity a bit}
432     declare $velocity
433     end on
434    
435     on note
436     { First initialize the variable $i with 4 each time we enter this event
437     handler, because each time we executed this handler, the variable will be 0 }
438     $i := $delayNotes
439    
440     { Loop which will be executed 4 times in a row }
441     while ($i)
442     { Calculate the velocity for the next note being triggered }
443     $velocity := 127 * $i / ($delayNotes + 1)
444     { Suspend this script for a short moment ... }
445     wait($delayMicroSeconds)
446     { ... and after that short break, trigger a new note. }
447     play_note($EVENT_NOTE, $velocity)
448     { Decrement loop counter $i by one }
449     $i := $i - 1
450     end while
451     end on
452     </code>
453     <p>
454     In this example we used a new keyword <code>const</code>. This additional
455     variable qualifier defines that we don't intend to change this variable
456     after declaration. So if you know beforehand, that a certain variable should
457     remain with a certain value, then you might use the <code>const</code>
458     qualifier to avoid that you i.e. change the value accidently when you
459     modify the script somewhere in future.
460     </p>
461     <p>
462     Now when you trigger one single note on your keyboard with that script,
463     you will hear the additional notes being triggered. And also when you
464     hit another note after a while, everything seems to be fine. However if
465     you start playing quick successive notes, you will notice something goes
466     wrong. The amount of notes being triggered by the script is now incorrect
467     and also the volume of the individual notes triggered by the script is wrong.
468     What's going on?
469     </p>
470     <p>
471     To understand the problem in the last example, let's consider what is
472     happening when executing that script exactly: Each time you play a note
473     on your keyboard, a new instance of the <code>note</code> event handler
474     will be spawned and executed by the sampler. In all our examples so far
475     our scripts were so simple, that in practice only one handler instance
476     was executed at a time. This is different in this case though. Because
477     by calling the <code>wait()</code> function, the respective handler
478     execution instance is paused for a while and in total each handler
479     instance will be executed for more than 2 seconds in this particular
480     example. As a consequence, when
481     you play multiple, successive notes on your keyboard in short time, you
482     will have several instances of the <code>note</code> event handler running
483     simultaniously. And that's where the problem starts. Because by default,
484     as said, all variables are global variables. So the handler instances
485     which are now running in parallel, are all reading and modifying the same
486     data. Thus the individual handler instances will modify the
487     <code>$i</code> and <code>$velocity</code> variables of each other, causing
488     an undesired misbehavior.
489     </p>
490     <note>
491     NKSP's built-in function <code>play_note()</code> allows you to pass
492     between one and four function arguments. For the function arguments you
493     don't provide to a <code>play_note()</code> call, NKSP will automatically
494     use default values. If you want your script to be compatible with KSP,
495     then you should always pass four arguments to that function though.
496     </note>
497    
498     <h3>Polyphonic Variables</h3>
499     <p>
500     As a logical consequence of the previously described data concurrency
501     problem, it would be desirable to have each event handler instance use
502     its own variable instance, so that the individual handler instances stop
503     interfering with each other. For this purpose the so called
504     <i title="A variable which is effectively a separate variable for each event handler instance.">
505     polyphonic variable
506     </i>
507     qualifier exists with NKSP. Declaring such a variable is identical to
508     declaring a regular variable, just that you add the keyword <code>polyphonic</code>.
509     </p>
510     <code>
511     declare polyphonic $??variable-name??
512     </code>
513     <p>
514     So to fix the bug in our previous example, we simply make the variables
515     <code>$i</code> and <code>$velocity</code> polyphonic variables.
516     </p>
517     <code>
518     on init
519     { The amount of notes to play }
520     declare const $delayNotes := 4
521     { Tempo with which the new notes will follow the orignal note }
522     declare const $bpm := 90
523     { Convert BPM to microseconds (duration between the notes) }
524     declare const $delayMicroSeconds := 60 * 1000000 / $bpm
525     { Just a working variable for being used with the while loop below }
526     declare polyphonic $i { < --- NOW POLYPHONIC !!! }
527     { For each successive note we trigger, we will reduce the velocity a bit}
528     declare polyphonic $velocity { < --- NOW POLYPHONIC !!! }
529     end on
530    
531     on note
532     { First initialize the variable $i with 4 each time we enter this event
533     handler, because each time we executed this handler, the variable will be 0 }
534     $i := $delayNotes
535    
536     { Loop which will be executed 4 times in a row }
537     while ($i)
538     { Calculate the velocity for the next note being triggered }
539     $velocity := 127 * $i / ($delayNotes + 1)
540     { Suspend this script for a short moment ... }
541     wait($delayMicroSeconds)
542     { ... and after that short break, trigger a new note. }
543     play_note($EVENT_NOTE, $velocity)
544     { Decrement loop counter $i by one }
545     $i := $i - 1
546     end while
547     end on
548     </code>
549     <p>
550     And that's it! The script works now as intended. Now you might wonder, why
551     are variables not <i>polyphonic</i> by default? Isn't that more common and
552     wouldn't that be more safer than using global variables by default? The reason is that
553     a polyphonic variable consumes a lot more memory than a regular (global) variable.
554     That's because for each polyphonic variable, the sampler has to allocate
555     in advance (when the script is loaded) as many instances of that
556     polyphonic variable as there are maximum events
557     allowed with the sampler. So that's a lot! Considering that today's
558     computers have plenty of RAM this might be a theoretical aspect, but in the
559     end: this default scope of variables was already like this with <i>KSP</i>
560     so we are also doing it like this with NKSP for compatibility reasons.
561     </p>
562     <p>
563     Please note that the <i>polyphonic</i> qualifier only exists for integer
564     variables. So you cannot declare polyphonic string variables, nor can you
565     declare polyphonic array variables. Like in the previous explanation,
566     this is due to the fact that it would consume a huge amount of memory
567     for such variables. And with string variables and array variables, the
568     required amount of memory would be much higher than with simple integer
569     variables.
570     </p>
571     <p>
572     As summary, the following are guideline rules describing when you should
573     use the polyphonic qualifier for a certain variable. You should declare
574     a particular variable polyphonic if one (or even both) of the following two
575     conditions apply to that variable.
576     </p>
577     <ol>
578     <li>
579     If you call the <code>wait()</code> function within your event
580     handlers and the respective variable is modified and read before
581     and after at least one of the individual <code>wait()</code> calls.
582     </li>
583     <li>
584     If you have loops that might run for a very long time, while accessing
585     the respective variable in between. That's because if your script is
586     running consecutively for too long, the sampler will automatically suspend your
587     script for a while to avoid your script becoming a real-time stability
588     hazard for the sampler. Your script will then automatically be resumed
589     after a short moment by the sampler, so effectively this is similar to
590     something like an "automated" <code>wait()</code> function call by
591     the sampler.
592     </li>
593     </ol>
594     <p>
595     In all other cases you should rather use regular (global) variables instead.
596     But keep in mind that you might need to re-assign a certain value for
597     some global variables when you enter the respective event handler, just
598     like we did with <code>$i := $delayNotes</code> right from the start
599     during discussion of the previous example script.
600     </p>
601 schoenebeck 2763 <p>
602     There is another special aspect regarding the variable scope of polyphonic
603     variables: <code>note</code> handlers and <code>release</code> handlers of
604     the same script share the same polyphonic variable scope, that means you
605     may pass data from a particular note's <code>note</code> handler to its
606     <code>release</code> handler by using the same polyphonic variable name.
607     </p>
608 schoenebeck 2732
609     <h2>Control Structures</h2>
610     <p>
611     A computer is more than a calculator that adds numbers and stores them
612     somewhere. One of the biggest strength of a computer, which makes it
613     such powerful, is the ability to do different things depending on various
614     conditions. For example your computer might clean up your hard drive
615     while you are not sitting in front of it, and it might immediately stop
616     doing so when you need all its resources to cut your latest video which
617     you just shot.
618     </p>
619     <p>
620     In order to do that for you, a computer program allows you to define
621     conditions and a list of instructions the computer shall
622     perform for you under those individual conditions. These kinds of
623     software mechanisms are called <i>Control Structures</i>.
624     </p>
625    
626     <h3>if Branches</h3>
627     <p>
628     The most fundamental control structure are <i>if branches</i>, which has
629     the following general form.
630     </p>
631     <code>
632     if (??condition??)
633    
634     ??statements??
635    
636     end if
637     </code>
638     <p>
639     The specified <code>??condition??</code> is evaluated each time script
640     execution reaches this control block. The condition can for example be
641     the value of a variable, some arithmetic expression, a function call or
642     a combination of them. In all cases the sampler expects the
643     <code>??condition??</code> expression to evaluate to some numeric
644     (or boolean) value. If the evaluated number is exactly <code>0</code> then
645     the condition is interpreted to be <i>false</i> and thus the list of
646     <code>??statements??</code> is not executed. If the evaluated value is any
647     other value than <code>0</code> then the condition is interpreted to be
648     <i>true</i> and accordingly the list of <code>??statements??</code> will be
649     executed.
650     </p>
651     <p>
652     Alternatively you might also specify a list of instructions which shall be
653     executed when the condition is <i>false</i>.
654     </p>
655     <code>
656     if (??condition??)
657    
658     ??statements-when-true??
659    
660     else
661    
662     ??statements-when-false??
663    
664     end if
665     </code>
666     <p>
667     In this case the first list of statements is executed when the
668     <code>??condition??</code> evaluated to <i>true</i>, otherwise the second
669     list of statements is executed instead.
670     </p>
671     <p>
672     Once again, let's get back to the example of counting triggered notes.
673     You might have noticed that it did not output correct English for the
674     first three notes. Let's correct this now.
675     </p>
676     <code>
677     on init
678     declare $numberOfNotes
679     declare @postfix
680     end on
681    
682     on note
683     $numberOfNotes := $numberOfNotes + 1
684    
685     if ($numberOfNotes == 1)
686     @postfix := "st"
687     else
688     if ($numberOfNotes == 2)
689     @postfix := "nd"
690     else
691     if ($numberOfNotes == 3)
692     @postfix := "rd"
693     else
694     @postfix := "th"
695     end if
696     end if
697     end if
698    
699     message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
700     end on
701     </code>
702     <p>
703     We are now checking the value of <code>$numberOfNotes</code> before we
704     print out a message. If <code>$numberOfNotes</code> equals one, then we
705     assign the string <code>"st"</code> to the variable <code>@postfix</code>,
706     if <code>$numberOfNotes</code> equals 2 instead we assign the string
707     <code>"nd"</code> instead, if it equals 3 instead we assign
708     <code>"rd"</code>, in all other cases we assign the string
709     <code>"th"</code>. And finally we assemble the text message to be
710     printed out to the terminal on line 23.
711     </p>
712    
713     <h3>Select Case Branches</h3>
714     <p>
715     The previous example now outputs the numbers in correct English. But the
716     script code looks a bit bloated, right? That's why there is a short hand
717     form.
718     </p>
719     <code>
720     select ??expression??
721    
722     case ??integer-1??
723    
724     ??statements-1??
725    
726    
727     case ??integer-2??
728    
729     ??statements-2??
730    
731     .
732     .
733     .
734     end select
735     </code>
736     <p>
737     The provided <code>??expression??</code> is first evaluated to an integer
738     value. Then this value is compared to the integer values of the nested
739     <code>case</code> lines. So it first compares the evaluated value of
740     <code>??expression??</code> with <code>??integer-1??</code>, then it
741     compares it with <code>??integer-2??</code>, and so on. The first integer
742     number that matches with the evaluated value of <code>??expression??</code>,
743     will be interpreted as being the current valid condition. So if
744     <code>??expression??</code> equals <code>??integer-1??</code>,
745     then <code>??statements-1??</code> will be executed, otherwise if
746     <code>??expression??</code> equals <code>??integer-2??</code>,
747     then <code>??statements-2??</code> will be executed, and so on.
748     </p>
749     <p>
750     Using a select-case construct, our previous example would look like follows.
751     </p>
752     <code>
753     on init
754     declare $numberOfNotes
755     declare @postfix
756     end on
757    
758     on note
759     $numberOfNotes := $numberOfNotes + 1
760     @postfix := "th"
761    
762     select $numberOfNotes
763     case 1
764     @postfix := "st"
765     case 2
766     @postfix := "nd"
767     case 3
768     @postfix := "rd"
769 schoenebeck 3119 end select
770 schoenebeck 2732
771     message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
772     end on
773     </code>
774     <note>
775     If you like, you can also put parentheses around the select expression,
776     like <code>select (??expression??)</code>. Some developers familiar with
777     other programming languages might prefer this style. However if you want
778     to keep compatibility with KSP, you should not use parentheses for
779     select expressions.
780     </note>
781     <p>
782     The amount
783     of case conditions you add to such select-case blocks is completely up
784     to you. Just remember that the case conditions will be compared one by one,
785     from top to down. The latter can be important when you define a case line
786     that defines a value range. So for instance the following example will
787     not do what was probably intended.
788     </p>
789     <code>
790     on init
791     declare $numberOfNotes
792     end on
793    
794     on note
795     $numberOfNotes := $numberOfNotes + 1
796    
797     select $numberOfNotes
798     case 1 to 99
799     message("Less than 100 notes triggered so far")
800     exit
801     case 1
802     message("First note was triggered!") { Will never be printed ! }
803     exit
804     case 2
805     message("Second note was triggered!") { Will never be printed ! }
806     exit
807     case 3
808     message("Third note was triggered!") { Will never be printed ! }
809     exit
810 schoenebeck 3119 end select
811 schoenebeck 2732
812     message("Wow, already the " & $numberOfNotes & "th note triggered.")
813     end on
814     </code>
815     <p>
816     You probably get the idea what this script "should" do. For the 1st note
817     it should print <code>"First note was triggered!"</code>, for the 2nd
818     note it should print <code>"Second note was triggered!"</code>, for the 3rd
819     note it should print <code>"Third note was triggered!"</code>, for the 4th
820     up to 99th note it should print <code>"Less than 100 notes triggered so far"</code>,
821     and starting from the 100th note and all following ones, it should print
822     the precise note number according to line 23. However, it doesn't!
823     </p>
824     <p>
825     To correct this problem, you need to move the first case block to the end,
826     like follows.
827     </p>
828     <code>
829     on init
830     declare $numberOfNotes
831     end on
832    
833     on note
834     $numberOfNotes := $numberOfNotes + 1
835    
836     select $numberOfNotes
837     case 1
838     message("First note was triggered!")
839     exit
840     case 2
841     message("Second note was triggered!")
842     exit
843     case 3
844     message("Third note was triggered!")
845     exit
846     case 1 to 99
847     message("Less than 100 notes triggered so far")
848     exit
849 schoenebeck 3119 end select
850 schoenebeck 2732
851     message("Wow, already the " & $numberOfNotes & "th note triggered.")
852     end on
853     </code>
854     <p>
855     Or you could of course fix the questioned case range from <code>case 1 to 99</code>
856     to <code>case 4 to 99</code>. Both solutions will do.
857     </p>
858     <p>
859     We also used the <i>built-in function</i> <code>exit()</code> in the
860     previous example. You can use it to stop execution at that point of your
861     script. In the previous example it prevents multiple messages to be
862     printed to the terminal.
863     </p>
864     <note class="important">
865     The <code>exit()</code> function only stops execution of the <b>current</b>
866     event handler instance! It does <b>not</b> stop execution of other
867     instances of the same event handler, nor does it stop execution of other
868     handlers of other event types, and especially it does <b>not</b> stop or
869     prevent further or future execution of your entire script! In other words,
870     you should rather see this function as a return statement, in case you are
871     familiar with other programming languages already.
872     </note>
873    
874     <h3>while Loops</h3>
875     <p>
876     Another fundamental control construct of program flow are loops.
877     You can use so called
878     <i title="Repeats a given list of instructions until the defined condition turns false.">
879     while loops
880     </i>
881     with NKSP.
882     </p>
883     <code>
884     while (??condition??)
885    
886     ??statements??
887    
888     end while
889     </code>
890     <p>
891     A while loop is entered if the provided <code>??condition??</code>
892     expression evaluates to <i>true</i> and will then continue to execute
893     the given list of <code>??statements??</code> down to the end of the statements
894     list. The <code>??condition??</code> is re-evaluated each time execution
895     reached the end of the <code>??statements??</code> list and according to
896     that latest evaluated <code>??condition??</code> value at that point, it
897     will or will not repeat executing the statements again. If the condition
898     turned <i>false</i> instead, it will leave the loop and continue executing
899     statements that follow after the while loop block.
900     </p>
901     <p>
902     The next example will print the same message three times in a row to the
903     terminal, right after the script had been loaded by the sampler.
904     </p>
905     <code>
906     on init
907     declare $i := 3
908    
909     while ($i)
910     message("Print this three times.")
911     $i := $i - 1
912     end while
913     end on
914     </code>
915     <p>
916     When the while loop is reached for the first time in this example, the
917     condition value is <code>3</code>. And as we learned before, all integer
918     values that are not <code>0</code> are interpreted as being a <i>true</i> condition.
919     Accordingly the while loop is entered, the message is printed to the
920     terminal and the variable <code>$i</code> is reduced by one. We reached
921     the end of the loop's statements list, so it is now re-evaluating the
922     condition, which is now the value <code>2</code> and thus the loop
923     instructions are executed again. That is repeated until the loop was
924     executed for the third time. The variable <code>$i</code> is now
925     <code>0</code>, so the loop condition turned finally to <i>false</i> and the
926     loop is thus left at that point and the text message was printed
927     three times in total.
928     </p>
929 schoenebeck 3061
930     <h3>User Functions</h3>
931     <p>
932     We already came across various built-in functions, which you may call
933     by your scripts to perform certain tasks or behavior which is already
934 schoenebeck 3062 provided for you by the sampler. NKSP also allows you to write your
935     own functions, which you then may call from various places of your
936     script.
937     <p>
938     </p>
939     When working on larger scripts, you
940 schoenebeck 3061 may notice that you easily get to the point where you may have to
941     duplicate portions of your script code, since there are certain things
942     that you may have to do again and again in different parts of your script.
943     Software developers usually try to avoid such code duplications to
944 schoenebeck 3062 keep the overall amount of code as small as possible, since the
945     overall amount of code would bloat quickly and would
946 schoenebeck 3061 make the software very hard to maintain. One way for you to avoid such
947     script code duplications with NKSP is to write so called <i>User Functions</s>.
948     </p>
949     <p>
950     Let's assume you wanted to create a simple stuttering effect. You may do so
951     like in the following example.
952     </p>
953     <code>
954     on note
955     while (1)
956     wait(200000)
957     if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
958     exit()
959     end if
960     change_vol($EVENT_ID, -20000) { Reduce volume by 20 dB. }
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, 0) { Increase volume to 0 dB. }
966     end while
967     end on
968     </code>
969     <p>
970     This script will run an endless loop for each note being triggered.
971 schoenebeck 3064 Every <code lang="none">200ms</code> it will turn the volume alternatingly down and
972 schoenebeck 3063 up to create the audible stuttering effect. After each <code lang="nksp">wait()</code>
973 schoenebeck 3061 call it calls <code>event_status($EVENT_ID)</code> to check whether
974     this note is still alive, and as soon as the note died, it will stop
975     execution of the script instance by calling <code>exit()</code>. The latter
976 schoenebeck 3064 is important in this example, because otherwise the script execution instances would
977 schoenebeck 3061 continue to run in this endless loop forever, even after the respectives
978 schoenebeck 3064 notes are gone. Which would let your CPU usage to increase with every new note
979     and would never decrease again.
980 schoenebeck 3061 This behavior of the sampler is not a bug, it is intended, since there may
981     also be cases where you want to do certain things by script even after the
982     respective notes are dead and gone. However as you can see, that script is
983     using the same portions of script code twice. To avoid that, you could also
984     write the same script with a user function like this:
985     </p>
986     <code>
987     function pauseMyScript
988     wait(200000)
989     if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
990     exit()
991     end if
992     end function
993 schoenebeck 2732
994 schoenebeck 3061 on note
995     while (1)
996     call pauseMyScript
997     change_vol($EVENT_ID, -20000) { Reduce volume by 20 dB. }
998     call pauseMyScript
999     change_vol($EVENT_ID, 0) { Increase volume back to 0 dB. }
1000     end while
1001     end on
1002     </code>
1003     <p>
1004     The script became in this simple example only slightly smaller, but it also
1005 schoenebeck 3062 became easier to read and behaves identically to the previous solution.
1006     And in practice, with a more complex script, you can
1007 schoenebeck 3061 reduce the overall amount of script code a lot this way. You can choose any
1008     name for your own user functions, as long as the name is not already
1009     reserved by a built-in function. Note that for calling a user function,
1010     you must always precede the actual user function name with the
1011     <code>call</code> keyword. Likewise you may however not use the
1012     <code>call</code> keyword for calling any built-in function. So that
1013     substantially differs calling built-in functions from calling user functions.
1014     </p>
1015    
1016 schoenebeck 3262 <h3>Synchronized Blocks</h3>
1017     <p>
1018 schoenebeck 3263 When we introduced the <a href="#polyphonic_variables">polyphonic keyword</a>
1019 schoenebeck 3262 previously, we learned that a script may automatically be suspended by
1020     the sampler at any time and then your script is thus sleeping for an
1021     arbitrary while. The sampler must do such auto suspensions under certain
1022     situations in cases where an instrument script may become a hazard for the
1023     sampler's overall real-time stability. If the sampler would not do so, then
1024     instrument scripts might easily cause audio dropouts, or at worst, buggy
1025     instrument scripts might even lock up the entire sampler in an endless
1026     loop. So auto suspension is an essential feature of the sampler's real-time
1027     instrument script engine.
1028     </p>
1029     <p>
1030     Now the problem as a script author is that you don't really know beforehand
1031     why and when your script might get auto suspended by the sampler. And when
1032     you are working on more complex, sophisticated scripts, you will notice
1033     that this might indeed be a big problem in certain sections of your scripts.
1034     Because in practice, a sophisticated script often has at least one certain
1035     consecutive portion of statements which must be executed in strict consecutive order
1036     by the sampler, which might otherwise cause concurrency issues and thus
1037     misbehavior of your script if that sensible code section was auto suspended
1038     in between. A typical example of such concurrency sensible code sections are
1039     statements which are reading and conditionally modifying global variables.
1040     If your script gets auto suspended in such a code section, another
1041     script handler instance might then interfere and change those global
1042     variables in between.
1043     </p>
1044     <p>
1045     To avoid that, you can place such a sensible code section at the very beginning
1046     of your event handler. For example consider you might be writing a custom
1047     <i title="A consecutive pitch glide from one note to another note.">glissando</i>
1048     script starting like this:
1049     </p>
1050     <code>
1051     on init
1052     declare $keysDown
1053     declare $firstNoteID
1054     declare $firstNoteNr
1055     declare $firstVelocity
1056     end on
1057    
1058     on note
1059     { The concurrency sensible code section for the "first active" note. }
1060     inc($keysDown)
1061     if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1062     $firstNoteID = $EVENT_ID
1063     $firstNoteNr = $EVENT_NOTE
1064     $firstVelocity = $EVENT_VELOCITY
1065     exit { return from event handler here }
1066     end if
1067    
1068     { The non-sensible code for all other subsequent notes would go here. }
1069     end on
1070    
1071     on release
1072     dec($keysDown)
1073     end on
1074     </code>
1075     <p>
1076     Because the earlier statements are executed in an event handler, the higher
1077     the chance that they will never get auto suspended. And with those couple of
1078     lines in the latter example you might even be lucky that it won't ever get
1079     suspended in that sensible code section at least. However when it comes to live
1080     concerts you don't really want to depend on luck, and in practice such a
1081     sensible code section might be bigger than this one.
1082     </p>
1083     <p>
1084     That's why we introduced <code>synchronized</code> code blocks for the
1085     NKSP language, which have the following form:
1086     </p>
1087     <code>
1088     synchronized
1089    
1090     ??statements??
1091    
1092     end synchronized
1093     </code>
1094     <p>
1095     All <code>??statements??</code> which you put into such a synchronized
1096     code block are guaranteed that they will never get auto suspended by
1097     the sampler.
1098     </p>
1099     <note>
1100     Such <code>synchronized</code> blocks are a language extension which
1101 schoenebeck 3608 is only available with NKSP. KSP does not support <code>synchronized</code> blocks.
1102 schoenebeck 3262 </note>
1103     <p>
1104     So to make our previous example concurrency safe, we would
1105     change it like this:
1106     </p>
1107     <code>
1108     on init
1109     declare $keysDown
1110     declare $firstNoteID
1111     declare $firstNoteNr
1112     declare $firstVelocity
1113     end on
1114    
1115     on note
1116     { The concurrency sensible code section for the "first active" note. }
1117     synchronized
1118     inc($keysDown)
1119     if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1120     $firstNoteID = $EVENT_ID
1121     $firstNoteNr = $EVENT_NOTE
1122     $firstVelocity = $EVENT_VELOCITY
1123     exit { return from event handler here }
1124     end if
1125     end synchronized
1126    
1127     { The non-sensible code for all other subsequent notes would go here. }
1128     end on
1129    
1130     on release
1131     dec($keysDown)
1132     end on
1133     </code>
1134     <p>
1135     If you are already familiar with some programming languages, then you
1136     might already have seen such synchronized code block concepts
1137     in languages like i.e. Java. This technique really provides an easy way
1138     to protect certain sections of your script against concurrency issues.
1139     </p>
1140     <note class="important">
1141     You <b>must</b> use such <code>synchronized</code> code blocks only with great
1142     care! If the amount of statements being executed in your synchronized block
1143     is too large, then you will get audio dropouts. If you even use loops in
1144     synchronized code blocks, then the entire sampler might even become
1145     unresponsive in case your script is buggy!
1146     </note>
1147    
1148 schoenebeck 2732 <h2>Operators</h2>
1149     <p>
1150     A programming language provides so called <i>operators</i> to perform
1151     certain kinds of transformations of data placed next to the operators.
1152     These are the operators available with NKSP.
1153     </p>
1154    
1155     <h3>Arithmetic Operators</h3>
1156     <p>
1157     These are the most basic mathematical operators, which allow to add,
1158     subtract, multiply and divide integer values with each other.
1159     </p>
1160     <code>
1161     on init
1162     message("4 + 3 is " & 4 + 3) { Add }
1163     message("4 - 3 is " & 4 - 3) { Subtract }
1164     message("4 * 3 is " & 4 * 3) { Multiply }
1165     message("35 / 5 is " & 35 / 5) { Divide }
1166     message("35 mod 5 is " & 35 mod 5) { Remainder of Division ("modulo") }
1167     end on
1168     </code>
1169     <p>
1170     You may either use direct integer literal numbers like used in the upper
1171     example, or you can use integer number variables or integer array variables.
1172     </p>
1173    
1174     <h3>Boolean Operators</h3>
1175     <p>
1176     To perform logical transformations of <i>boolean</i> data, you may use the
1177 schoenebeck 2936 following logical operators:
1178 schoenebeck 2732 </p>
1179     <code>
1180     on init
1181     message("1 and 1 is " & 1 and 1) { logical "and" }
1182     message("1 and 0 is " & 1 and 0) { logical "and" }
1183     message("1 or 1 is " & 1 or 1) { logical "or" }
1184     message("1 or 0 is " & 1 or 0) { logical "or" }
1185     message("not 1 is " & not 1) { logical "not" }
1186     message("not 0 is " & not 0) { logical "not" }
1187     end on
1188     </code>
1189     <p>
1190 schoenebeck 2936 Keep in mind that with logical operators shown above,
1191     all integer values other than <code>0</code>
1192 schoenebeck 2732 are interpreted as boolean <i>true</i> while an integer value of
1193 schoenebeck 3397 precisely <code>0</code> is interpreted as being boolean <i>false</i>.
1194 schoenebeck 2732 </p>
1195 schoenebeck 2936 <p>
1196     So the logical operators shown above always look at numbers at a whole.
1197     Sometimes however you might rather need to process numbers bit by bit. For
1198     that purpose the following bitwise operators exist.
1199     </p>
1200     <code>
1201     on init
1202     message("1 .and. 1 is " & 1 .and. 1) { bitwise "and" }
1203     message("1 .and. 0 is " & 1 .and. 0) { bitwise "and" }
1204     message("1 .or. 1 is " & 1 .or. 1) { bitwise "or" }
1205     message("1 .or. 0 is " & 1 .or. 0) { bitwise "or" }
1206     message(".not. 1 is " & .not. 1) { bitwise "not" }
1207     message(".not. 0 is " & .not. 0) { bitwise "not" }
1208     end on
1209     </code>
1210     <p>
1211     Bitwise operators work essentially like logical operators, with the
1212     difference that bitwise operators compare each bit independently.
1213     So a bitwise <code>.and.</code> operator for instance takes the 1st bit
1214     of the left hand's side value, the 1st bit of the right hand's side value,
1215     compares the two bits logically and then stores that result as 1st bit of
1216     the final result value, then it takes the 2nd bit of the left hand's side value
1217     and the 2nd bit of the right hand's side value, compares those two bits logically
1218     and then stores that result as 2nd bit of the final result value, and so on.
1219     </p>
1220    
1221 schoenebeck 2732
1222     <h3>Comparison Operators</h3>
1223     <p>
1224     For branches in your program flow, it is often required to compare data
1225     with each other. This is done by using comparison operators, enumerated
1226     below.
1227     </p>
1228     <code>
1229     on init
1230     message("Relation 3 < 4 -> " & 3 < 4) { "smaller than" comparison }
1231     message("Relation 3 > 4 -> " & 3 > 4) { "greater than" comparison }
1232     message("Relation 3 <= 4 -> " & 3 <= 4) { "smaller or equal than" comparison}
1233     message("Relation 3 >= 4 -> " & 3 >= 4) { "greater or equal than" comparison}
1234     message("Relation 3 # 4 -> " & 3 # 4) { "not equal to" comparison}
1235     message("Relation 3 = 4 -> " & 3 = 4) { "is equal to" comparison}
1236     end on
1237     </code>
1238     <p>
1239     All these operations yield in a <i>boolean</i> result which could then
1240 schoenebeck 3397 be used i.e. with <code>if</code> or <code>while</code> loop statements.
1241 schoenebeck 2732 </p>
1242    
1243     <h3>String Operators</h3>
1244     <p>
1245     Last but not least, there is exactly one operator for text string data;
1246     the string concatenation operator <code>&</code>, which
1247     combines two text strings with each other.
1248     </p>
1249     <code>
1250     on init
1251     declare @s := "foo" & " bar"
1252     message(@s)
1253     end on
1254     </code>
1255     <p>
1256     We have used it now frequently in various examples before.
1257     </p>
1258    
1259     <h2>Preprocessor Statements</h2>
1260     <p>
1261     Similar to low-level programming languages like C, C++, Objective C
1262     and the like, NKSP supports a set of so called preprocessor statements.
1263     These are essentially "instructions" which are "executed" or rather
1264     processed, before (and only before) the script is executed by the sampler,
1265     and even before the script is parsed by the actual NKSP language parser.
1266     You can think of a preprocessor as a very primitive parser, which is the
1267     first one getting in touch with your script, it modifies the script code
1268     if requested by your preprocessor statements in the script, and then
1269     passes the (probably) modified script to the actual NKSP language parser.
1270     </p>
1271     <p>
1272     When we discussed <a href="#comments">comments</a> in NKSP scripts before,
1273     it was suggested that you might comment out certain code parts to disable
1274     them for a while during development of scripts. It was also suggested
1275     during this language tour that you should not use string variables or use
1276     the <code>message()</code> function with your final production sounds.
1277     However those are very handy things during development of your instrument
1278     scripts. You might even have a bunch of additional code in your scripts
1279     which only satisfies the purpose to make debugging of your scripts more easy,
1280     which however wastes on the other hand precious CPU time. So what do you
1281     do? Like suggested, you could comment out the respective code sections as
1282     soon as development of your script is completed. But then one day you
1283     might continue to improve your scripts, and the debugging code would be
1284     handy, so you would uncomment all the relevant code sections to get them
1285     back. When you think about this, that might be quite some work each time.
1286     Fortunately there is an alternative by using preprocessor statements.
1287     </p>
1288    
1289     <h3>Set a Condition</h3>
1290     <p>
1291     First you need to set a preprocessor condition in your script. You can do
1292     that like this:
1293     </p>
1294     <code>
1295     SET_CONDITION(??condition-name??)
1296     </code>
1297     <p>
1298     This preprocessor "condition" is just like some kind of
1299     <i title="A variable which can only have two states: i.e. true or false.">
1300     boolean variable
1301     </i>
1302     which is only available to the preprocessor and by using
1303     <code>SET_CONDITION(??condition-name??)</code>, this is like setting this
1304     preprocessor condition to <i>true</i>. Like with regular script
1305     variables, a preprocessor condition name can be chosen quite arbitrarily
1306     by you. But again, there are some pre-defined preprocessor conditions
1307     defined by the sampler for you. So you can only set a condition name here
1308     which is not already reserved by a built-in preprocessor condition. Also
1309     you shall not set a condition in your script again if you have already set it
1310     before somewhere in your script. The NKSP preprocessor will ignore setting
1311     a condition a 2nd time and will just print a warning when the script is
1312     loaded, but you should take care of it, because it might be a cause for
1313     some bug.
1314     </p>
1315    
1316     <h3>Reset a Condition</h3>
1317     <p>
1318     To clear a condition in your script, you might reset the condition like so:
1319     </p>
1320     <code>
1321     RESET_CONDITION(??condition-name??)
1322     </code>
1323     <p>
1324     This is like setting that preprocessor condition back to <i>false</i> again.
1325     You should only reset a preprocessor condition that way if you did set it
1326     with <code>SET_CONDITION(??condition-name??)</code> before. Trying to
1327     reset a condition that has not been set before, or trying to reset a
1328     condition that has already been reset, will both be ignored by the samlper,
1329     but again you will get a warning, and you should take care about it.
1330     </p>
1331    
1332     <h3>Conditionally Using Code</h3>
1333     <p>
1334     Now what do you actually do with such preprocessor conditions? You can use
1335     them for the NKSP language parser to either
1336     </p>
1337     <ul>
1338     <li>use certain parts of your code</i>
1339     <li><b>and</b> / <b>or</b> to ignore certain parts of your code</i>
1340     </ul>
1341     <p>
1342     You can achieve that by wrapping NKSP code parts into a pair of either
1343     </p>
1344     <code>
1345     USE_CODE_IF(??condition-name??)
1346    
1347     ??some-NKSP-code-goes-here??
1348    
1349     END_USE_CODE
1350     </code>
1351     <p>
1352     preprocessor statements, or between
1353     </p>
1354     <code>
1355     USE_CODE_IF_NOT(??condition-name??)
1356    
1357     ??some-NKSP-code-goes-here??
1358    
1359     END_USE_CODE
1360     </code>
1361     <p>
1362     statements. In the first case, the NKSP code portion is used by the NKSP
1363     language parser if the given preprocessor <code>??condition-name??</code> is set
1364     (that is if condition is <i>true</i>).
1365     If the condition is not set, the NKSP code portion in between is
1366     completely ignored by the NKSP language parser.
1367     </p>
1368     <p>
1369     In the second case, the NKSP code portion is used by the NKSP
1370     language parser if the given preprocessor <code>??condition-name??</code> is <b>not</b> set
1371     (or was reset)
1372     (that is if condition is <i>false</i>).
1373     If the condition is set, the NKSP code portion in between is
1374     completely ignored by the NKSP language parser.
1375     </p>
1376     <p>
1377     Let's look at an example how to use that to define conditional debugging
1378     code.
1379     </p>
1380     <code>
1381     SET_CONDITION(DEBUG_MODE)
1382    
1383     on init
1384     declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1385     declare $i
1386    
1387     USE_CODE_IF(DEBUG_MODE)
1388     message("This script has just been loaded.")
1389    
1390     $i := 0
1391     while ($i < num_elements(%primes))
1392     message("Prime " & $i & " is " & %primes[$i])
1393     $i := $i + 1
1394     end while
1395     END_USE_CODE
1396     end on
1397    
1398     on note
1399     USE_CODE_IF(DEBUG_MODE)
1400     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1401     END_USE_CODE
1402     end on
1403    
1404     on release
1405     USE_CODE_IF(DEBUG_MODE)
1406     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1407     END_USE_CODE
1408     end on
1409    
1410     on controller
1411     USE_CODE_IF(DEBUG_MODE)
1412     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1413     END_USE_CODE
1414     end on
1415     </code>
1416     <p>
1417     The <i>built-in function</i> <code>num_elements()</code> used above, can
1418     be called to obtain the size of an array variable at runtime.
1419     As this script looks now, the debug messages will be printed out. However
1420     it requires you to just remove the first line, or to comment out the first
1421     line, in order to disable all debug code portions in just a second:
1422     </p>
1423     <code>
1424     { Setting the condition is commented out, so our DEBUG_MODE is disabled now. }
1425     { SET_CONDITION(DEBUG_MODE) }
1426    
1427     on init
1428     declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1429     declare $i
1430    
1431     USE_CODE_IF(DEBUG_MODE) { Condition is not set, so this entire block will be ignored now. }
1432     message("This script has just been loaded.")
1433    
1434     $i := 0
1435     while ($i < num_elements(%primes))
1436     message("Prime " & $i & " is " & %primes[$i])
1437     $i := $i + 1
1438     end while
1439     END_USE_CODE
1440     end on
1441    
1442     on note
1443     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1444     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1445     END_USE_CODE
1446     end on
1447    
1448     on release
1449     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1450     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1451     END_USE_CODE
1452     end on
1453    
1454     on controller
1455     USE_CODE_IF(DEBUG_MODE) { Condition is not set, no message will be printed. }
1456     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1457     END_USE_CODE
1458     end on
1459     </code>
1460     <p>
1461     Now you might say, you could also achieve that by declaring and using
1462     a regular NKSP variable. That's correct, but there are two major
1463     advantages by using preprocessor statements.
1464     </p>
1465     <ol>
1466     <li>
1467     <b>Saving Resources</b> -
1468     The preprocessor conditions are only processed before the script is
1469     loaded into the NKSP parser. So in contrast to using NKSP variables,
1470     the preprocessor solution does not waste any CPU time or memory
1471     resources while executing the script. That also means that variable
1472     declarations can be disabled with the preprocessor this way
1473     and thus will also safe resources.
1474     </li>
1475     <li>
1476     <b>Cross Platform Support</b> -
1477     Since the code portions filtered out by the preprocessor never make it
1478     into the NKSP language parser, those filtered code portions might also
1479     contain code which would have lead to parser errors. For example you
1480     could use a built-in preprocessor condition to check whether your script
1481     was loaded into LinuxSampler or rather into another sampler. That way
1482     you could maintain one script for both platforms: NKSP and KSP.
1483     Accordingly you could
1484     also check a built-in variable to obtain the version of the sampler in
1485     order to enable or disable code portions of your script that might
1486     use some newer script features of the sampler which don't exist in older
1487     version of the sampler.
1488     </li>
1489     </ol>
1490     <p>
1491     As a rule of thumb: if there are things that you could move from your
1492     NKSP executed programming code out to the preprocessor, then you should
1493     use the preprocessor instead for such things. And like stated above,
1494     there are certain things which you can only achieve with the preprocessor.
1495     </p>
1496 schoenebeck 3337
1497     <h3>Disable Messages</h3>
1498 schoenebeck 3312 <p>
1499     Since it is quite common to switch a script between a development version
1500     and a production version, you actually don't need to wrap all your
1501     <code>message()</code> calls into preprocessor statements like in the
1502 schoenebeck 3337 previous example just to disable messages. There is actually a built-in
1503     preprocessor condition dedicated to perform that task much more conveniently for you.
1504     To disable all messages in your script, simply add <code>SET_CONDITION(NKSP_NO_MESSAGE)</code>
1505 schoenebeck 3338 i.e. at the very beginning of your script.
1506 schoenebeck 3337 So the previous example can be simplified like this:
1507 schoenebeck 3312 </p>
1508     <code>
1509     { Enable debug mode, so show all debug messages. }
1510     SET_CONDITION(DEBUG_MODE)
1511    
1512     { If our user declared condition "DEBUG_MODE" is not set ... }
1513     USE_CODE_IF_NOT(DEBUG_MODE)
1514     { ... then enable this built-in condition to disable all message() calls. }
1515     SET_CONDITION(NKSP_NO_MESSAGE)
1516     END_USE_CODE
1517    
1518     on init
1519     declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1520     declare $i
1521    
1522     message("This script has just been loaded.")
1523    
1524     USE_CODE_IF(DEBUG_MODE)
1525     $i := 0
1526     while ($i < num_elements(%primes))
1527     message("Prime " & $i & " is " & %primes[$i])
1528     $i := $i + 1
1529     end while
1530     END_USE_CODE
1531     end on
1532    
1533     on note
1534     message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1535     end on
1536    
1537     on release
1538     message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1539     end on
1540    
1541     on controller
1542     message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1543     end on
1544     </code>
1545     <p>
1546     You can then actually also add <code>RESET_CONDITION(NKSP_NO_MESSAGE)</code>
1547     at another section of your script, which will cause all subsequent
1548     <code>message()</code> calls to be processed again. So that way you can
1549     easily enable and disable <code>message()</code> calls of entire individual
1550     sections of your script, without having to wrap all <code>message()</code>
1551     calls into preprocessor statements.
1552     </p>
1553    
1554 schoenebeck 2732 <h2>What Next?</h2>
1555     <p>
1556     You have completed the introduction of the NKSP real-time instrument
1557     script language at this point. You can now dive into the details of the
1558     NKSP language by moving on to the
1559     <a href="nksp_reference.html">NKSP reference documentation</a>.
1560     Which provides you an overview and quick access to the details of all
1561     built-in functions, built-in variables and more.
1562     </p>
1563 schoenebeck 3608 <p>
1564     You might also be interested to look at new <i>NKSP</i> core language
1565     features being added to the latest development version of the sampler:
1566     <a href="real_unit_final/01_nksp_real_unit_final.html">
1567     Real Numbers, Units and Finalness ...
1568     </a>
1569     </p>
1570 schoenebeck 2732
1571     </body>
1572     </html>

  ViewVC Help
Powered by ViewVC