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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2732 by schoenebeck, Sun Apr 26 20:54:00 2015 UTC revision 3608 by schoenebeck, Wed Sep 18 13:24:28 2019 UTC
# Line 11  Line 11 
11        your own instrument scripts in short time. It concentrates on describing        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        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        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>.        <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>      </p>
19    
20      <h3>At a Glance</h3>      <h3>At a Glance</h3>
21      <p>      <p>
22        <img src="nksp_file.png" style="height:111px; margin-right:12px;">        <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        NKSP stands for "is <b>N</b>ot <b>KSP</b>", which denotes its distinction
24        to an existing proprieatary language called <i>KSP</i>.        to an existing proprietary language called <i>KSP</i>.
25        NSKP is a script language specifically designed to write real-time capable        NSKP is a script language specifically designed to write real-time capable
26        software extensions to LinuxSampler's sampler engines that can be bundled        software extensions to LinuxSampler's sampler engines that can be bundled
27        individually with sounds by sound designers themselves.        individually with sounds by sound designers themselves.
# Line 251  end on Line 254  end on
254      <p>      <p>
255        The left hand side's <code>??variable-name??</code> is an arbitrary name        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        you can chose for your variable. That name might consist of English
257        letters A to Z (lower and upper case) and the underscore character "<code>_</code>".        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        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        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>.        already been reserved by <i>built-in variables</i>.
# Line 414  end on Line 418  end on
418        triggered on a MIDI keyboard. The following example demonstrates how that        triggered on a MIDI keyboard. The following example demonstrates how that
419        could be achieved.        could be achieved.
420      </p>      </p>
     <note class="important">  
       The following example does not fully work with LinuxSampler yet. That's  
       because the used <code>wait()</code> function is not fully implemented  
       yet. Currently a <code>wait()</code> function call suspends execution,  
       but since the respective scheduler code is yet missing, the script  
       will automatically be resumed with the next audio fragment cycle. So  
       effectively a <code>wait()</code> call will pause your script for a few  
       miliseconds with LinuxSampler right now, no matter which function argument  
       you provided. Hopefully this will be implemented soon though.  
     </note>  
421      <code>      <code>
422  on init  on init
423    { The amount of notes to play }    { The amount of notes to play }
# Line 604  end on Line 598  end on
598        like we did with <code>$i := $delayNotes</code> right from the start        like we did with <code>$i := $delayNotes</code> right from the start
599        during discussion of the previous example script.        during discussion of the previous example script.
600      </p>      </p>
601        <p>
602          There is another special aspect regarding the variable scope of polyphonic
603          variables: <code>note</code> handlers and <code>release</code> handlers of
604          the same script share the same polyphonic variable scope, that means you
605          may pass data from a particular note's <code>note</code> handler to its
606          <code>release</code> handler by using the same polyphonic variable name.
607        </p>
608    
609      <h2>Control Structures</h2>      <h2>Control Structures</h2>
610      <p>      <p>
# Line 765  on note Line 766  on note
766        @postfix := "nd"        @postfix := "nd"
767      case 3      case 3
768        @postfix := "rd"        @postfix := "rd"
769    end if    end select
770    
771    message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")    message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
772  end on  end on
# Line 806  on note Line 807  on note
807      case 3      case 3
808        message("Third note was triggered!") { Will never be printed ! }        message("Third note was triggered!") { Will never be printed ! }
809        exit        exit
810    end if    end select
811    
812    message("Wow, already the " & $numberOfNotes & "th note triggered.")    message("Wow, already the " & $numberOfNotes & "th note triggered.")
813  end on  end on
# Line 845  on note Line 846  on note
846      case 1 to 99      case 1 to 99
847        message("Less than 100 notes triggered so far")        message("Less than 100 notes triggered so far")
848        exit        exit
849    end if    end select
850    
851    message("Wow, already the " & $numberOfNotes & "th note triggered.")    message("Wow, already the " & $numberOfNotes & "th note triggered.")
852  end on  end on
# Line 925  end on Line 926  end on
926        loop is thus left at that point and the text message was printed        loop is thus left at that point and the text message was printed
927        three times in total.        three times in total.
928      </p>      </p>
929    
930        <h3>User Functions</h3>
931        <p>
932          We already came across various built-in functions, which you may call
933          by your scripts to perform certain tasks or behavior which is already
934          provided for you by the sampler. NKSP also allows you to write your
935          own functions, which you then may call from various places of your
936          script.
937        <p>  
938        </p>
939          When working on larger scripts, you
940          may notice that you easily get to the point where you may have to
941          duplicate portions of your script code, since there are certain things
942          that you may have to do again and again in different parts of your script.
943          Software developers usually try to avoid such code duplications to
944          keep the overall amount of code as small as possible, since the
945          overall amount of code would bloat quickly and would
946          make the software very hard to maintain. One way for you to avoid such
947          script code duplications with NKSP is to write so called <i>User Functions</s>.
948        </p>
949        <p>
950          Let's assume you wanted to create a simple stuttering effect. You may do so
951          like in the following example.
952        </p>
953        <code>
954    on note
955      while (1)
956        wait(200000)
957        if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
958          exit()
959        end if
960        change_vol($EVENT_ID, -20000)  { Reduce volume by 20 dB. }
961        wait(200000)
962        if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
963          exit()
964        end if
965        change_vol($EVENT_ID, 0)  { Increase volume to 0 dB. }
966      end while
967    end on
968        </code>
969        <p>
970          This script will run an endless loop for each note being triggered.
971          Every <code lang="none">200ms</code> it will turn the volume alternatingly down and
972          up to create the audible stuttering effect. After each <code lang="nksp">wait()</code>
973          call it calls <code>event_status($EVENT_ID)</code> to check whether
974          this note is still alive, and as soon as the note died, it will stop
975          execution of the script instance by calling <code>exit()</code>. The latter
976          is important in this example, because otherwise the script execution instances would
977          continue to run in this endless loop forever, even after the respectives
978          notes are gone. Which would let your CPU usage to increase with every new note
979          and would never decrease again.
980          This behavior of the sampler is not a bug, it is intended, since there may
981          also be cases where you want to do certain things by script even after the
982          respective notes are dead and gone. However as you can see, that script is
983          using the same portions of script code twice. To avoid that, you could also
984          write the same script with a user function like this:
985        </p>
986        <code>
987    function pauseMyScript
988      wait(200000)
989      if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
990        exit()
991      end if
992    end function
993            
994    on note
995      while (1)
996        call pauseMyScript
997        change_vol($EVENT_ID, -20000)  { Reduce volume by 20 dB. }
998        call pauseMyScript
999        change_vol($EVENT_ID, 0)  { Increase volume back to 0 dB. }
1000      end while
1001    end on
1002        </code>
1003        <p>
1004          The script became in this simple example only slightly smaller, but it also
1005          became easier to read and behaves identically to the previous solution.
1006          And in practice, with a more complex script, you can
1007          reduce the overall amount of script code a lot this way. You can choose any
1008          name for your own user functions, as long as the name is not already
1009          reserved by a built-in function. Note that for calling a user function,
1010          you must always precede the actual user function name with the
1011          <code>call</code> keyword. Likewise you may however not use the
1012          <code>call</code> keyword for calling any built-in function. So that
1013          substantially differs calling built-in functions from calling user functions.
1014        </p>
1015    
1016        <h3>Synchronized Blocks</h3>
1017        <p>
1018          When we introduced the <a href="#polyphonic_variables">polyphonic keyword</a>
1019          previously, we learned that a script may automatically be suspended by
1020          the sampler at any time and then your script is thus sleeping for an
1021          arbitrary while. The sampler must do such auto suspensions under certain
1022          situations in cases where an instrument script may become a hazard for the
1023          sampler's overall real-time stability. If the sampler would not do so, then
1024          instrument scripts might easily cause audio dropouts, or at worst, buggy
1025          instrument scripts might even lock up the entire sampler in an endless
1026          loop. So auto suspension is an essential feature of the sampler's real-time
1027          instrument script engine.
1028        </p>
1029        <p>
1030          Now the problem as a script author is that you don't really know beforehand
1031          why and when your script might get auto suspended by the sampler. And when
1032          you are working on more complex, sophisticated scripts, you will notice
1033          that this might indeed be a big problem in certain sections of your scripts.
1034          Because in practice, a sophisticated script often has at least one certain
1035          consecutive portion of statements which must be executed in strict consecutive order
1036          by the sampler, which might otherwise cause concurrency issues and thus
1037          misbehavior of your script if that sensible code section was auto suspended
1038          in between. A typical example of such concurrency sensible code sections are
1039          statements which are reading and conditionally modifying global variables.
1040          If your script gets auto suspended in such a code section, another
1041          script handler instance might then interfere and change those global
1042          variables in between.
1043        </p>
1044        <p>
1045          To avoid that, you can place such a sensible code section at the very beginning
1046          of your event handler. For example consider you might be writing a custom
1047          <i title="A consecutive pitch glide from one note to another note.">glissando</i>
1048          script starting like this:
1049        </p>
1050        <code>
1051    on init
1052      declare $keysDown
1053      declare $firstNoteID
1054      declare $firstNoteNr
1055      declare $firstVelocity
1056    end on
1057    
1058    on note
1059      { The concurrency sensible code section for the "first active" note. }
1060      inc($keysDown)
1061      if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1062        $firstNoteID = $EVENT_ID
1063        $firstNoteNr = $EVENT_NOTE
1064        $firstVelocity = $EVENT_VELOCITY
1065        exit { return from event handler here }
1066      end if
1067    
1068      { The non-sensible code for all other subsequent notes would go here. }
1069    end on
1070    
1071    on release
1072      dec($keysDown)
1073    end on
1074        </code>
1075        <p>
1076          Because the earlier statements are executed in an event handler, the higher
1077          the chance that they will never get auto suspended. And with those couple of
1078          lines in the latter example you might even be lucky that it won't ever get
1079          suspended in that sensible code section at least. However when it comes to live
1080          concerts you don't really want to depend on luck, and in practice such a
1081          sensible code section might be bigger than this one.
1082        </p>
1083        <p>
1084          That's why we introduced <code>synchronized</code> code blocks for the
1085          NKSP language, which have the following form:
1086        </p>
1087        <code>
1088    synchronized
1089    
1090      ??statements??
1091    
1092    end synchronized
1093        </code>
1094        <p>
1095          All <code>??statements??</code> which you put into such a synchronized
1096          code block are guaranteed that they will never get auto suspended by
1097          the sampler.
1098        </p>
1099        <note>
1100          Such <code>synchronized</code> blocks are a language extension which
1101          is only available with NKSP. KSP does not support <code>synchronized</code> blocks.
1102        </note>
1103        <p>
1104          So to make our previous example concurrency safe, we would
1105          change it like this:
1106        </p>
1107        <code>
1108    on init
1109      declare $keysDown
1110      declare $firstNoteID
1111      declare $firstNoteNr
1112      declare $firstVelocity
1113    end on
1114    
1115    on note
1116      { The concurrency sensible code section for the "first active" note. }
1117      synchronized
1118        inc($keysDown)
1119        if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1120          $firstNoteID = $EVENT_ID
1121          $firstNoteNr = $EVENT_NOTE
1122          $firstVelocity = $EVENT_VELOCITY
1123          exit { return from event handler here }
1124        end if
1125      end synchronized
1126    
1127      { The non-sensible code for all other subsequent notes would go here. }
1128    end on
1129    
1130    on release
1131      dec($keysDown)
1132    end on
1133        </code>
1134        <p>
1135          If you are already familiar with some programming languages, then you
1136          might already have seen such synchronized code block concepts
1137          in languages like i.e. Java. This technique really provides an easy way
1138          to protect certain sections of your script against concurrency issues.
1139        </p>
1140        <note class="important">
1141          You <b>must</b> use such <code>synchronized</code> code blocks only with great
1142          care! If the amount of statements being executed in your synchronized block
1143          is too large, then you will get audio dropouts. If you even use loops in
1144          synchronized code blocks, then the entire sampler might even become
1145          unresponsive in case your script is buggy!
1146        </note>
1147    
1148      <h2>Operators</h2>      <h2>Operators</h2>
1149      <p>      <p>
1150        A programming language provides so called <i>operators</i> to perform        A programming language provides so called <i>operators</i> to perform
# Line 955  end on Line 1174  end on
1174      <h3>Boolean Operators</h3>      <h3>Boolean Operators</h3>
1175      <p>      <p>
1176        To perform logical transformations of <i>boolean</i> data, you may use the        To perform logical transformations of <i>boolean</i> data, you may use the
1177        following boolean operators:        following logical operators:
1178      </p>      </p>
1179      <code>      <code>
1180  on init  on init
# Line 968  on init Line 1187  on init
1187  end on  end on
1188      </code>      </code>
1189      <p>      <p>
1190        Remember that with boolean operations, all integer values other than <code>0</code>        Keep in mind that with logical operators shown above,
1191          all integer values other than <code>0</code>
1192        are interpreted as boolean <i>true</i> while an integer value of        are interpreted as boolean <i>true</i> while an integer value of
1193        precisely <code>0</code> is interpreted of being boolean <i>false</i>.        precisely <code>0</code> is interpreted as being boolean <i>false</i>.
1194        </p>
1195        <p>
1196          So the logical operators shown above always look at numbers at a whole.
1197          Sometimes however you might rather need to process numbers bit by bit. For
1198          that purpose the following bitwise operators exist.
1199      </p>      </p>
1200        <code>
1201    on init
1202      message("1 .and. 1 is " & 1 .and. 1)  { bitwise "and" }
1203      message("1 .and. 0 is " & 1 .and. 0)  { bitwise "and" }
1204      message("1 .or. 1 is " & 1 .or. 1)    { bitwise "or" }
1205      message("1 .or. 0 is " & 1 .or. 0)    { bitwise "or" }
1206      message(".not. 1 is " & .not. 1)      { bitwise "not" }
1207      message(".not. 0 is " & .not. 0)      { bitwise "not" }
1208    end on
1209        </code>
1210        <p>
1211          Bitwise operators work essentially like logical operators, with the
1212          difference that bitwise operators compare each bit independently.
1213          So a bitwise <code>.and.</code> operator for instance takes the 1st bit
1214          of the left hand's side value, the 1st bit of the right hand's side value,
1215          compares the two bits logically and then stores that result as 1st bit of
1216          the final result value, then it takes the 2nd bit of the left hand's side value
1217          and the 2nd bit of the right hand's side value, compares those two bits logically
1218          and then stores that result as 2nd bit of the final result value, and so on.
1219        </p>
1220    
1221            
1222      <h3>Comparison Operators</h3>      <h3>Comparison Operators</h3>
1223      <p>      <p>
# Line 991  end on Line 1237  end on
1237      </code>      </code>
1238      <p>      <p>
1239        All these operations yield in a <i>boolean</i> result which could then        All these operations yield in a <i>boolean</i> result which could then
1240        by used i.e. with <code>if</code> or <code>while</code> loop statements.        be used i.e. with <code>if</code> or <code>while</code> loop statements.
1241      </p>      </p>
1242            
1243      <h3>String Operators</h3>      <h3>String Operators</h3>
# Line 1247  end on Line 1493  end on
1493        use the preprocessor instead for such things. And like stated above,        use the preprocessor instead for such things. And like stated above,
1494        there are certain things which you can only achieve with the preprocessor.        there are certain things which you can only achieve with the preprocessor.
1495      </p>      </p>
1496        
1497        <h3>Disable Messages</h3>
1498        <p>
1499          Since it is quite common to switch a script between a development version
1500          and a production version, you actually don't need to wrap all your
1501          <code>message()</code> calls into preprocessor statements like in the
1502          previous example just to disable messages. There is actually a built-in
1503          preprocessor condition dedicated to perform that task much more conveniently for you.
1504          To disable all messages in your script, simply add <code>SET_CONDITION(NKSP_NO_MESSAGE)</code>
1505          i.e. at the very beginning of your script.
1506          So the previous example can be simplified like this:
1507        </p>
1508        <code>
1509    { Enable debug mode, so show all debug messages. }
1510    SET_CONDITION(DEBUG_MODE)
1511    
1512    { If our user declared condition "DEBUG_MODE" is not set ... }
1513    USE_CODE_IF_NOT(DEBUG_MODE)
1514      { ... then enable this built-in condition to disable all message() calls. }
1515      SET_CONDITION(NKSP_NO_MESSAGE)
1516    END_USE_CODE
1517    
1518    on init
1519      declare const %primes[12] :=  ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1520      declare $i
1521    
1522      message("This script has just been loaded.")
1523    
1524      USE_CODE_IF(DEBUG_MODE)
1525      $i := 0
1526      while ($i < num_elements(%primes))
1527        message("Prime " & $i & " is " & %primes[$i])
1528        $i := $i + 1
1529      end while
1530      END_USE_CODE
1531    end on
1532    
1533    on note
1534      message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1535    end on
1536    
1537    on release
1538      message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1539    end on
1540    
1541    on controller
1542      message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1543    end on
1544        </code>
1545        <p>
1546          You can then actually also add <code>RESET_CONDITION(NKSP_NO_MESSAGE)</code>
1547          at another section of your script, which will cause all subsequent
1548          <code>message()</code> calls to be processed again. So that way you can
1549          easily enable and disable <code>message()</code> calls of entire individual
1550          sections of your script, without having to wrap all <code>message()</code>
1551          calls into preprocessor statements.
1552        </p>
1553    
1554      <h2>What Next?</h2>      <h2>What Next?</h2>
1555      <p>      <p>
1556        You have completed the introduction of the NKSP real-time instrument        You have completed the introduction of the NKSP real-time instrument
# Line 1257  end on Line 1560  end on
1560        Which provides you an overview and quick access to the details of all        Which provides you an overview and quick access to the details of all
1561        built-in functions, built-in variables and more.        built-in functions, built-in variables and more.
1562      </p>      </p>
1563        <p>
1564          You might also be interested to look at new <i>NKSP</i> core language
1565          features being added to the latest development version of the sampler:
1566          <a href="real_unit_final/01_nksp_real_unit_final.html">
1567            Real Numbers, Units and Finalness ...
1568          </a>
1569        </p>
1570    
1571    </body>    </body>
1572  </html>  </html>

Legend:
Removed from v.2732  
changed lines
  Added in v.3608

  ViewVC Help
Powered by ViewVC