67 |
end on |
end on |
68 |
</code> |
</code> |
69 |
<p> |
<p> |
70 |
There are currently four events available: |
There are currently six events available: |
71 |
</p> |
</p> |
72 |
<table> |
<table> |
73 |
<tr> |
<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> |
<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> |
</tr> |
85 |
<tr> |
<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> |
<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> |
</tr> |
94 |
</table> |
</table> |
153 |
Please note that you can hardly find MIDI keyboards which support release |
Please note that you can hardly find MIDI keyboards which support release |
154 |
velocity. So with most keyboards this value will be 127. |
velocity. So with most keyboards this value will be 127. |
155 |
</p> |
</p> |
156 |
|
|
157 |
<h3>Controller Events</h3> |
<h3>Controller Events</h3> |
158 |
<p> |
<p> |
159 |
Now let's extend the first script to not only show note-on and note-off |
Now let's extend the first script to not only show note-on and note-off |
193 |
<code>%CC[$VCC_MONO_AT]</code>, and to get the current pitch bend wheel |
<code>%CC[$VCC_MONO_AT]</code>, and to get the current pitch bend wheel |
194 |
value use <code>%CC[$VCC_PITCH_BEND]</code>. |
value use <code>%CC[$VCC_PITCH_BEND]</code>. |
195 |
</p> |
</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> |
<h3>Script Load Event</h3> |
248 |
<p> |
<p> |
249 |
As the last one of the four event types available with NKSP, the following |
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. |
is an example of an <code>init</code> event handler. |
251 |
</p> |
</p> |
252 |
<code> |
<code> |
474 |
triggered on a MIDI keyboard. The following example demonstrates how that |
triggered on a MIDI keyboard. The following example demonstrates how that |
475 |
could be achieved. |
could be achieved. |
476 |
</p> |
</p> |
|
<note> |
|
|
You need at least LinuxSampler 2.0.0.svn2 or higher for the following |
|
|
example to work as described and as expected. Refer to the notes of the |
|
|
<code>wait()</code> function reference documentation for more |
|
|
informations about this issue. |
|
|
</note> |
|
477 |
<code> |
<code> |
478 |
on init |
on init |
479 |
{ The amount of notes to play } |
{ The amount of notes to play } |
1071 |
|
|
1072 |
<h3>Synchronized Blocks</h3> |
<h3>Synchronized Blocks</h3> |
1073 |
<p> |
<p> |
1074 |
When we introduced the <a href="polyphonic_variables">polyphonic keyword</a> |
When we introduced the <a href="#polyphonic_variables">polyphonic keyword</a> |
1075 |
previously, we learned that a script may automatically be suspended by |
previously, we learned that a script may automatically be suspended by |
1076 |
the sampler at any time and then your script is thus sleeping for an |
the sampler at any time and then your script is thus sleeping for an |
1077 |
arbitrary while. The sampler must do such auto suspensions under certain |
arbitrary while. The sampler must do such auto suspensions under certain |
1154 |
</p> |
</p> |
1155 |
<note> |
<note> |
1156 |
Such <code>synchronized</code> blocks are a language extension which |
Such <code>synchronized</code> blocks are a language extension which |
1157 |
is only available with NKSP and requires at least LinuxSampler 2.0.0.svn60 |
is only available with NKSP. KSP does not support <code>synchronized</code> blocks. |
|
or higher. KSP does not support <code>synchronized</code> blocks. |
|
1158 |
</note> |
</note> |
1159 |
<p> |
<p> |
1160 |
So to make our previous example concurrency safe, we would |
So to make our previous example concurrency safe, we would |
1246 |
Keep in mind that with logical operators shown above, |
Keep in mind that with logical operators shown above, |
1247 |
all integer values other than <code>0</code> |
all integer values other than <code>0</code> |
1248 |
are interpreted as boolean <i>true</i> while an integer value of |
are interpreted as boolean <i>true</i> while an integer value of |
1249 |
precisely <code>0</code> is interpreted of being boolean <i>false</i>. |
precisely <code>0</code> is interpreted as being boolean <i>false</i>. |
1250 |
</p> |
</p> |
1251 |
<p> |
<p> |
1252 |
So the logical operators shown above always look at numbers at a whole. |
So the logical operators shown above always look at numbers at a whole. |
1293 |
</code> |
</code> |
1294 |
<p> |
<p> |
1295 |
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 |
1296 |
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. |
1297 |
</p> |
</p> |
1298 |
|
|
1299 |
<h3>String Operators</h3> |
<h3>String Operators</h3> |
1549 |
use the preprocessor instead for such things. And like stated above, |
use the preprocessor instead for such things. And like stated above, |
1550 |
there are certain things which you can only achieve with the preprocessor. |
there are certain things which you can only achieve with the preprocessor. |
1551 |
</p> |
</p> |
1552 |
|
|
1553 |
|
<h3>Disable Messages</h3> |
1554 |
|
<p> |
1555 |
|
Since it is quite common to switch a script between a development version |
1556 |
|
and a production version, you actually don't need to wrap all your |
1557 |
|
<code>message()</code> calls into preprocessor statements like in the |
1558 |
|
previous example just to disable messages. There is actually a built-in |
1559 |
|
preprocessor condition dedicated to perform that task much more conveniently for you. |
1560 |
|
To disable all messages in your script, simply add <code>SET_CONDITION(NKSP_NO_MESSAGE)</code> |
1561 |
|
i.e. at the very beginning of your script. |
1562 |
|
So the previous example can be simplified like this: |
1563 |
|
</p> |
1564 |
|
<code> |
1565 |
|
{ Enable debug mode, so show all debug messages. } |
1566 |
|
SET_CONDITION(DEBUG_MODE) |
1567 |
|
|
1568 |
|
{ If our user declared condition "DEBUG_MODE" is not set ... } |
1569 |
|
USE_CODE_IF_NOT(DEBUG_MODE) |
1570 |
|
{ ... then enable this built-in condition to disable all message() calls. } |
1571 |
|
SET_CONDITION(NKSP_NO_MESSAGE) |
1572 |
|
END_USE_CODE |
1573 |
|
|
1574 |
|
on init |
1575 |
|
declare const %primes[12] := ( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 ) |
1576 |
|
declare $i |
1577 |
|
|
1578 |
|
message("This script has just been loaded.") |
1579 |
|
|
1580 |
|
USE_CODE_IF(DEBUG_MODE) |
1581 |
|
$i := 0 |
1582 |
|
while ($i < num_elements(%primes)) |
1583 |
|
message("Prime " & $i & " is " & %primes[$i]) |
1584 |
|
$i := $i + 1 |
1585 |
|
end while |
1586 |
|
END_USE_CODE |
1587 |
|
end on |
1588 |
|
|
1589 |
|
on note |
1590 |
|
message("Note " & $EVENT_NOTE & " was triggered with velocity " & $EVENT_VELOCITY) |
1591 |
|
end on |
1592 |
|
|
1593 |
|
on release |
1594 |
|
message("Note " & $EVENT_NOTE & " was released with release velocity " & $EVENT_VELOCITY) |
1595 |
|
end on |
1596 |
|
|
1597 |
|
on controller |
1598 |
|
message("MIDI Controller " & $CC_NUM " changed its value to " & %CC[$CC_NUM]) |
1599 |
|
end on |
1600 |
|
</code> |
1601 |
|
<p> |
1602 |
|
You can then actually also add <code>RESET_CONDITION(NKSP_NO_MESSAGE)</code> |
1603 |
|
at another section of your script, which will cause all subsequent |
1604 |
|
<code>message()</code> calls to be processed again. So that way you can |
1605 |
|
easily enable and disable <code>message()</code> calls of entire individual |
1606 |
|
sections of your script, without having to wrap all <code>message()</code> |
1607 |
|
calls into preprocessor statements. |
1608 |
|
</p> |
1609 |
|
|
1610 |
<h2>What Next?</h2> |
<h2>What Next?</h2> |
1611 |
<p> |
<p> |
1612 |
You have completed the introduction of the NKSP real-time instrument |
You have completed the introduction of the NKSP real-time instrument |
1616 |
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 |
1617 |
built-in functions, built-in variables and more. |
built-in functions, built-in variables and more. |
1618 |
</p> |
</p> |
1619 |
|
<p> |
1620 |
|
You might also be interested to look at new <i>NKSP</i> core language |
1621 |
|
features being added to the latest development version of the sampler: |
1622 |
|
<a href="real_unit_final/01_nksp_real_unit_final.html"> |
1623 |
|
Real Numbers, Units and Finalness ... |
1624 |
|
</a> |
1625 |
|
</p> |
1626 |
|
|
1627 |
</body> |
</body> |
1628 |
</html> |
</html> |