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

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

  ViewVC Help
Powered by ViewVC