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

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

  ViewVC Help
Powered by ViewVC