/[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 3817 - (show annotations) (download) (as text)
Sat Aug 29 09:16:38 2020 UTC (3 years, 6 months ago) by schoenebeck
File MIME type: text/html
File size: 67086 byte(s)
Just a typo fix.

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

  ViewVC Help
Powered by ViewVC