/[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 2872 by schoenebeck, Sun Apr 10 18:42:55 2016 UTC revision 3262 by schoenebeck, Wed May 31 23:19:39 2017 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 768  on note Line 772  on note
772        @postfix := "nd"        @postfix := "nd"
773      case 3      case 3
774        @postfix := "rd"        @postfix := "rd"
775    end if    end select
776    
777    message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")    message("This is the " & $numberOfNotes & @postfix & " note triggered so far.")
778  end on  end on
# Line 809  on note Line 813  on note
813      case 3      case 3
814        message("Third note was triggered!") { Will never be printed ! }        message("Third note was triggered!") { Will never be printed ! }
815        exit        exit
816    end if    end select
817    
818    message("Wow, already the " & $numberOfNotes & "th note triggered.")    message("Wow, already the " & $numberOfNotes & "th note triggered.")
819  end on  end on
# Line 848  on note Line 852  on note
852      case 1 to 99      case 1 to 99
853        message("Less than 100 notes triggered so far")        message("Less than 100 notes triggered so far")
854        exit        exit
855    end if    end select
856    
857    message("Wow, already the " & $numberOfNotes & "th note triggered.")    message("Wow, already the " & $numberOfNotes & "th note triggered.")
858  end on  end on
# Line 928  end on Line 932  end on
932        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
933        three times in total.        three times in total.
934      </p>      </p>
935    
936        <h3>User Functions</h3>
937        <p>
938          We already came across various built-in functions, which you may call
939          by your scripts to perform certain tasks or behavior which is already
940          provided for you by the sampler. NKSP also allows you to write your
941          own functions, which you then may call from various places of your
942          script.
943        <p>  
944        </p>
945          When working on larger scripts, you
946          may notice that you easily get to the point where you may have to
947          duplicate portions of your script code, since there are certain things
948          that you may have to do again and again in different parts of your script.
949          Software developers usually try to avoid such code duplications to
950          keep the overall amount of code as small as possible, since the
951          overall amount of code would bloat quickly and would
952          make the software very hard to maintain. One way for you to avoid such
953          script code duplications with NKSP is to write so called <i>User Functions</s>.
954        </p>
955        <p>
956          Let's assume you wanted to create a simple stuttering effect. You may do so
957          like in the following example.
958        </p>
959        <code>
960    on note
961      while (1)
962        wait(200000)
963        if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
964          exit()
965        end if
966        change_vol($EVENT_ID, -20000)  { Reduce volume by 20 dB. }
967        wait(200000)
968        if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
969          exit()
970        end if
971        change_vol($EVENT_ID, 0)  { Increase volume to 0 dB. }
972      end while
973    end on
974        </code>
975        <p>
976          This script will run an endless loop for each note being triggered.
977          Every <code lang="none">200ms</code> it will turn the volume alternatingly down and
978          up to create the audible stuttering effect. After each <code lang="nksp">wait()</code>
979          call it calls <code>event_status($EVENT_ID)</code> to check whether
980          this note is still alive, and as soon as the note died, it will stop
981          execution of the script instance by calling <code>exit()</code>. The latter
982          is important in this example, because otherwise the script execution instances would
983          continue to run in this endless loop forever, even after the respectives
984          notes are gone. Which would let your CPU usage to increase with every new note
985          and would never decrease again.
986          This behavior of the sampler is not a bug, it is intended, since there may
987          also be cases where you want to do certain things by script even after the
988          respective notes are dead and gone. However as you can see, that script is
989          using the same portions of script code twice. To avoid that, you could also
990          write the same script with a user function like this:
991        </p>
992        <code>
993    function pauseMyScript
994      wait(200000)
995      if (not (event_status($EVENT_ID) .and. $EVENT_STATUS_NOTE_QUEUE))
996        exit()
997      end if
998    end function
999            
1000    on note
1001      while (1)
1002        call pauseMyScript
1003        change_vol($EVENT_ID, -20000)  { Reduce volume by 20 dB. }
1004        call pauseMyScript
1005        change_vol($EVENT_ID, 0)  { Increase volume back to 0 dB. }
1006      end while
1007    end on
1008        </code>
1009        <p>
1010          The script became in this simple example only slightly smaller, but it also
1011          became easier to read and behaves identically to the previous solution.
1012          And in practice, with a more complex script, you can
1013          reduce the overall amount of script code a lot this way. You can choose any
1014          name for your own user functions, as long as the name is not already
1015          reserved by a built-in function. Note that for calling a user function,
1016          you must always precede the actual user function name with the
1017          <code>call</code> keyword. Likewise you may however not use the
1018          <code>call</code> keyword for calling any built-in function. So that
1019          substantially differs calling built-in functions from calling user functions.
1020        </p>
1021    
1022        <h3>Synchronized Blocks</h3>
1023        <p>
1024          When we introduced the <a href="polyphonic_variables">polyphonic keyword</a>
1025          previously, we learned that a script may automatically be suspended by
1026          the sampler at any time and then your script is thus sleeping for an
1027          arbitrary while. The sampler must do such auto suspensions under certain
1028          situations in cases where an instrument script may become a hazard for the
1029          sampler's overall real-time stability. If the sampler would not do so, then
1030          instrument scripts might easily cause audio dropouts, or at worst, buggy
1031          instrument scripts might even lock up the entire sampler in an endless
1032          loop. So auto suspension is an essential feature of the sampler's real-time
1033          instrument script engine.
1034        </p>
1035        <p>
1036          Now the problem as a script author is that you don't really know beforehand
1037          why and when your script might get auto suspended by the sampler. And when
1038          you are working on more complex, sophisticated scripts, you will notice
1039          that this might indeed be a big problem in certain sections of your scripts.
1040          Because in practice, a sophisticated script often has at least one certain
1041          consecutive portion of statements which must be executed in strict consecutive order
1042          by the sampler, which might otherwise cause concurrency issues and thus
1043          misbehavior of your script if that sensible code section was auto suspended
1044          in between. A typical example of such concurrency sensible code sections are
1045          statements which are reading and conditionally modifying global variables.
1046          If your script gets auto suspended in such a code section, another
1047          script handler instance might then interfere and change those global
1048          variables in between.
1049        </p>
1050        <p>
1051          To avoid that, you can place such a sensible code section at the very beginning
1052          of your event handler. For example consider you might be writing a custom
1053          <i title="A consecutive pitch glide from one note to another note.">glissando</i>
1054          script starting like this:
1055        </p>
1056        <code>
1057    on init
1058      declare $keysDown
1059      declare $firstNoteID
1060      declare $firstNoteNr
1061      declare $firstVelocity
1062    end on
1063    
1064    on note
1065      { The concurrency sensible code section for the "first active" note. }
1066      inc($keysDown)
1067      if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1068        $firstNoteID = $EVENT_ID
1069        $firstNoteNr = $EVENT_NOTE
1070        $firstVelocity = $EVENT_VELOCITY
1071        exit { return from event handler here }
1072      end if
1073    
1074      { The non-sensible code for all other subsequent notes would go here. }
1075    end on
1076    
1077    on release
1078      dec($keysDown)
1079    end on
1080        </code>
1081        <p>
1082          Because the earlier statements are executed in an event handler, the higher
1083          the chance that they will never get auto suspended. And with those couple of
1084          lines in the latter example you might even be lucky that it won't ever get
1085          suspended in that sensible code section at least. However when it comes to live
1086          concerts you don't really want to depend on luck, and in practice such a
1087          sensible code section might be bigger than this one.
1088        </p>
1089        <p>
1090          That's why we introduced <code>synchronized</code> code blocks for the
1091          NKSP language, which have the following form:
1092        </p>
1093        <code>
1094    synchronized
1095    
1096      ??statements??
1097    
1098    end synchronized
1099        </code>
1100        <p>
1101          All <code>??statements??</code> which you put into such a synchronized
1102          code block are guaranteed that they will never get auto suspended by
1103          the sampler.
1104        </p>
1105        <note>
1106          Such <code>synchronized</code> blocks are a language extension which
1107          is only available with NKSP and requires at least LinuxSampler 2.0.0.svn60
1108          or higher. KSP does not support <code>synchronized</code> blocks.
1109        </note>
1110        <p>
1111          So to make our previous example concurrency safe, we would
1112          change it like this:
1113        </p>
1114        <code>
1115    on init
1116      declare $keysDown
1117      declare $firstNoteID
1118      declare $firstNoteNr
1119      declare $firstVelocity
1120    end on
1121    
1122    on note
1123      { The concurrency sensible code section for the "first active" note. }
1124      synchronized
1125        inc($keysDown)
1126        if ($keysDown = 1 or event_status($firstNoteID) = $EVENT_STATUS_INACTIVE)
1127          $firstNoteID = $EVENT_ID
1128          $firstNoteNr = $EVENT_NOTE
1129          $firstVelocity = $EVENT_VELOCITY
1130          exit { return from event handler here }
1131        end if
1132      end synchronized
1133    
1134      { The non-sensible code for all other subsequent notes would go here. }
1135    end on
1136    
1137    on release
1138      dec($keysDown)
1139    end on
1140        </code>
1141        <p>
1142          If you are already familiar with some programming languages, then you
1143          might already have seen such synchronized code block concepts
1144          in languages like i.e. Java. This technique really provides an easy way
1145          to protect certain sections of your script against concurrency issues.
1146        </p>
1147        <note class="important">
1148          You <b>must</b> use such <code>synchronized</code> code blocks only with great
1149          care! If the amount of statements being executed in your synchronized block
1150          is too large, then you will get audio dropouts. If you even use loops in
1151          synchronized code blocks, then the entire sampler might even become
1152          unresponsive in case your script is buggy!
1153        </note>
1154    
1155      <h2>Operators</h2>      <h2>Operators</h2>
1156      <p>      <p>
1157        A programming language provides so called <i>operators</i> to perform        A programming language provides so called <i>operators</i> to perform
# Line 958  end on Line 1181  end on
1181      <h3>Boolean Operators</h3>      <h3>Boolean Operators</h3>
1182      <p>      <p>
1183        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
1184        following boolean operators:        following logical operators:
1185      </p>      </p>
1186      <code>      <code>
1187  on init  on init
# Line 971  on init Line 1194  on init
1194  end on  end on
1195      </code>      </code>
1196      <p>      <p>
1197        Remember that with boolean operations, all integer values other than <code>0</code>        Keep in mind that with logical operators shown above,
1198          all integer values other than <code>0</code>
1199        are interpreted as boolean <i>true</i> while an integer value of        are interpreted as boolean <i>true</i> while an integer value of
1200        precisely <code>0</code> is interpreted of being boolean <i>false</i>.        precisely <code>0</code> is interpreted of being boolean <i>false</i>.
1201      </p>      </p>
1202        <p>
1203          So the logical operators shown above always look at numbers at a whole.
1204          Sometimes however you might rather need to process numbers bit by bit. For
1205          that purpose the following bitwise operators exist.
1206        </p>
1207        <code>
1208    on init
1209      message("1 .and. 1 is " & 1 .and. 1)  { bitwise "and" }
1210      message("1 .and. 0 is " & 1 .and. 0)  { bitwise "and" }
1211      message("1 .or. 1 is " & 1 .or. 1)    { bitwise "or" }
1212      message("1 .or. 0 is " & 1 .or. 0)    { bitwise "or" }
1213      message(".not. 1 is " & .not. 1)      { bitwise "not" }
1214      message(".not. 0 is " & .not. 0)      { bitwise "not" }
1215    end on
1216        </code>
1217        <p>
1218          Bitwise operators work essentially like logical operators, with the
1219          difference that bitwise operators compare each bit independently.
1220          So a bitwise <code>.and.</code> operator for instance takes the 1st bit
1221          of the left hand's side value, the 1st bit of the right hand's side value,
1222          compares the two bits logically and then stores that result as 1st bit of
1223          the final result value, then it takes the 2nd bit of the left hand's side value
1224          and the 2nd bit of the right hand's side value, compares those two bits logically
1225          and then stores that result as 2nd bit of the final result value, and so on.
1226        </p>
1227    
1228            
1229      <h3>Comparison Operators</h3>      <h3>Comparison Operators</h3>
1230      <p>      <p>

Legend:
Removed from v.2872  
changed lines
  Added in v.3262

  ViewVC Help
Powered by ViewVC