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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3062 - (show annotations) (download) (as text)
Fri Dec 16 18:25:17 2016 UTC (7 years, 3 months ago) by schoenebeck
File MIME type: text/html
File size: 56516 byte(s)
- Minor changes to previous commit.

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

  ViewVC Help
Powered by ViewVC