/[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 3337 - (show annotations) (download) (as text)
Sun Jul 30 16:07:58 2017 UTC (6 years, 7 months ago) by schoenebeck
File MIME type: text/html
File size: 64151 byte(s)
* NKSP language tour: Updated section about disabling
  messages with the preprocessor.

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

  ViewVC Help
Powered by ViewVC