/[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 3119 by schoenebeck, Fri Apr 21 16:02:47 2017 UTC revision 3312 by schoenebeck, Sat Jul 15 17:04:05 2017 UTC
# Line 254  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 1018  end on Line 1019  end on
1019        substantially differs calling built-in functions from calling user functions.        substantially differs calling built-in functions from calling user functions.
1020      </p>      </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 1366  end on Line 1500  end on
1500        use the preprocessor instead for such things. And like stated above,        use the preprocessor instead for such things. And like stated above,
1501        there are certain things which you can only achieve with the preprocessor.        there are certain things which you can only achieve with the preprocessor.
1502      </p>      </p>
1503            <p>
1504          Since it is quite common to switch a script between a development version
1505          and a production version, you actually don't need to wrap all your
1506          <code>message()</code> calls into preprocessor statements like in the
1507          previous example. There is actually a built-in preprocessor dedicated to
1508          perform that task much more conveniently for you. So the previous example
1509          can be simplified like this:
1510        </p>
1511        <code>
1512    { Enable debug mode, so show all debug messages. }
1513    SET_CONDITION(DEBUG_MODE)
1514    
1515    { If our user declared condition "DEBUG_MODE" is not set ... }
1516    USE_CODE_IF_NOT(DEBUG_MODE)
1517      { ... then enable this built-in condition to disable all message() calls. }
1518      SET_CONDITION(NKSP_NO_MESSAGE)
1519    END_USE_CODE
1520    
1521    on init
1522      declare const %primes[12] :=  ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 )
1523      declare $i
1524    
1525      message("This script has just been loaded.")
1526    
1527      USE_CODE_IF(DEBUG_MODE)
1528      $i := 0
1529      while ($i < num_elements(%primes))
1530        message("Prime " & $i & " is " & %primes[$i])
1531        $i := $i + 1
1532      end while
1533      END_USE_CODE
1534    end on
1535    
1536    on note
1537      message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY)
1538    end on
1539    
1540    on release
1541      message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY)
1542    end on
1543    
1544    on controller
1545      message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM])
1546    end on
1547        </code>
1548        <p>
1549          You can then actually also add <code>RESET_CONDITION(NKSP_NO_MESSAGE)</code>
1550          at another section of your script, which will cause all subsequent
1551          <code>message()</code> calls to be processed again. So that way you can
1552          easily enable and disable <code>message()</code> calls of entire individual
1553          sections of your script, without having to wrap all <code>message()</code>
1554          calls into preprocessor statements.
1555        </p>
1556    
1557      <h2>What Next?</h2>      <h2>What Next?</h2>
1558      <p>      <p>
1559        You have completed the introduction of the NKSP real-time instrument        You have completed the introduction of the NKSP real-time instrument

Legend:
Removed from v.3119  
changed lines
  Added in v.3312

  ViewVC Help
Powered by ViewVC