mirror of
https://github.com/thestk/stk
synced 2026-04-19 22:16:54 +00:00
Release 4.1.3 tarball
This commit is contained in:
committed by
Stephen Sinclair
parent
503ed3cc9f
commit
e11bff2fe8
@@ -8,12 +8,12 @@
|
||||
<img src="princeton.gif"> <img src="ccrma.gif"> <img src="mcgill.gif"><P>
|
||||
<a class="qindex" href="index.html">Home</a> <a class="qindex" href="information.html">Information</a> <a class="qindex" href="classes.html">Classes</a> <a class="qindex" href="download.html">Download</a> <a class="qindex" href="usage.html">Usage</a> <a class="qindex" href="maillist.html">Mail List</a> <a class="qindex" href="system.html">Requirements</a> <a class="qindex" href="links.html">Links</a> <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
|
||||
<HR>
|
||||
<!-- Generated by Doxygen 1.3.6 -->
|
||||
<!-- Generated by Doxygen 1.3.4 -->
|
||||
<h1><a class="anchor" name="skini">Synthesis toolKit Instrument Network Interface (SKINI)</a></h1>This describes the latest (version 1.1) implementation of <a class="el" href="classSKINI.html">SKINI</a> for the Synthesis ToolKit in C++ (STK) by Perry R. Cook.<p>
|
||||
<pre class="fragment"><div> Too good to be <span class="keyword">true</span>?
|
||||
<div class="fragment"><pre> Too good to be <span class="keyword">true</span>?
|
||||
Have control and read it too?
|
||||
A <a class="code" href="classSKINI.html">SKINI</a> haiku.
|
||||
</div></pre><p>
|
||||
</pre></div><p>
|
||||
Profound thanks to Dan Trueman, Brad Garton, and Gary Scavone for input on this revision. Thanks also to MIDI, the NeXT MusicKit, ZIPI and all the creators and modifiers of these for good bases upon/from which to build and depart.<h2><a class="anchor" name="compatibility">
|
||||
MIDI Compatibility</a></h2>
|
||||
<a class="el" href="classSKINI.html">SKINI</a> was designed to be MIDI compatible wherever possible, and extend MIDI in incremental, then maybe profound ways.<p>
|
||||
@@ -61,7 +61,7 @@ The parser isn't all that smart, but neither am I. Here are the basic rules gove
|
||||
<li>All remaining fields are specified in the SKINI.tbl file. In general, there are maximum two more fields, which are either SK_INT (long), SK_DBL (double float), or SK_STR (string). The latter is the mechanism by which more arguments can be specified on the line, but the object using <a class="el" href="classSKINI.html">SKINI</a> must take that string apart (retrived by using getRemainderString()) and scan it. Any excess fields are stashed in remainderString.</li></ul>
|
||||
<h2><a class="anchor" name="file">
|
||||
A Short SKINI File:</a></h2>
|
||||
<pre class="fragment"><div> <span class="comment">/* Howdy!!! Welcome to SKINI, by P. Cook 1999</span>
|
||||
<div class="fragment"><pre> <span class="comment">/* Howdy!!! Welcome to SKINI, by P. Cook 1999</span>
|
||||
<span class="comment"></span>
|
||||
<span class="comment"> NoteOn 0.000082 2 55 82</span>
|
||||
<span class="comment"> NoteOff 1.000000 2 55 0</span>
|
||||
@@ -92,19 +92,19 @@ A Short SKINI File:</a></h2>
|
||||
<span class="comment"> NoteOff 0.000000 2 62 82</span>
|
||||
<span class="comment"> NoteOff 0.000000 2 71 82</span>
|
||||
<span class="comment"> NoteOff 0.000000 2 79 82</span>
|
||||
</div></pre><h2><a class="anchor" name="table">
|
||||
</pre></div><h2><a class="anchor" name="table">
|
||||
The SKINI.tbl File and Message Parsing:</a></h2>
|
||||
The SKINI.tbl file contains an array of structures which are accessed by the parser object SKINI.cpp. The struct is:<p>
|
||||
<pre class="fragment"><div><span class="keyword">struct </span>SKINISpec {
|
||||
<div class="fragment"><pre><span class="keyword">struct </span>SKINISpec {
|
||||
<span class="keywordtype">char</span> messageString[32];
|
||||
<span class="keywordtype">long</span> type;
|
||||
<span class="keywordtype">long</span> data2;
|
||||
<span class="keywordtype">long</span> data3;
|
||||
};
|
||||
</div></pre><p>
|
||||
</pre></div><p>
|
||||
so an assignment of one of these structs looks like:<p>
|
||||
<pre class="fragment"><div> MessageStr$ ,type, data2, data3,
|
||||
</div></pre><p>
|
||||
<div class="fragment"><pre> MessageStr$ ,type, data2, data3,
|
||||
</pre></div><p>
|
||||
<code>type</code> is the message type sent back from the <a class="el" href="classSKINI.html">SKINI</a> line parser.<p>
|
||||
<code>data<n></code> is either:<p>
|
||||
<ul>
|
||||
@@ -120,7 +120,7 @@ so an assignment of one of these structs looks like:<p>
|
||||
<li>SK_STR : only valid in final field. This allows (nearly) arbitrary message types to be supported by simply scanning the string to EndOfLine and then passing it to a more intellegent handler. For example, MIDI SYSEX (system exclusive) messages of up to 256 bytes can be read as space-delimited integers into the 1K SK_STR buffer. Longer bulk dumps, soundfiles, etc. should be handled as a new message type pointing to a FileName, <a class="el" href="classSocket.html">Socket</a>, or something else stored in the SK_STR field, or as a new type of multi-line message.</li></ul>
|
||||
<p>
|
||||
Here's a couple of lines from the SKINI.tbl file<p>
|
||||
<pre class="fragment"><div> {<span class="stringliteral">"NoteOff"</span> , __SK_NoteOff_, SK_DBL, SK_DBL},
|
||||
<div class="fragment"><pre> {<span class="stringliteral">"NoteOff"</span> , __SK_NoteOff_, SK_DBL, SK_DBL},
|
||||
{<span class="stringliteral">"NoteOn"</span> , __SK_NoteOn_, SK_DBL, SK_DBL},
|
||||
|
||||
{<span class="stringliteral">"ControlChange"</span> , __SK_ControlChange_, SK_INT, SK_DBL},
|
||||
@@ -128,18 +128,18 @@ Here's a couple of lines from the SKINI.tbl file<p>
|
||||
|
||||
{<span class="stringliteral">"StringDamping"</span> , __SK_ControlChange_, __SK_StringDamping_, SK_DBL},
|
||||
{<span class="stringliteral">"StringDetune"</span> , __SK_ControlChange_, __SK_StringDetune_, SK_DBL},
|
||||
</div></pre><p>
|
||||
</pre></div><p>
|
||||
The first three are basic MIDI messages. The first two would cause the parser, after recognizing a match of the string "NoteOff" or "NoteOn", to set the message type to 128 or 144 (__SK_NoteOff_ and __SK_NoteOn_ are #defined in the file SKINI.msg to be the MIDI byte value, without channel, of the actual MIDI messages for NoteOn and NoteOff). The parser would then set the time or delta time (this is always done and is therefore not described in the <a class="el" href="classSKINI.html">SKINI</a> Message Struct). The next two fields would be scanned as double-precision floats and assigned to the byteTwo and byteThree variables of the <a class="el" href="classSKINI.html">SKINI</a> parser. The remainder of the line is stashed in the remainderString variable.<p>
|
||||
The ControlChange spec is basically the same as NoteOn and NoteOff, but the second data byte is set to an integer (for checking later as to what MIDI control is being changed).<p>
|
||||
The Volume spec is a MIDI Extension message, which behaves like a ControlChange message with the controller number set explicitly to the value for MIDI Volume (7). Thus the following two lines would accomplish the same changing of MIDI volume on channel 2:<p>
|
||||
<pre class="fragment"><div> ControlChange 0.000000 2 7 64.1
|
||||
<div class="fragment"><pre> ControlChange 0.000000 2 7 64.1
|
||||
Volume 0.000000 2 64.1
|
||||
</div></pre><p>
|
||||
</pre></div><p>
|
||||
I like the 2nd line better, thus my motivation for <a class="el" href="classSKINI.html">SKINI</a> in the first place.<p>
|
||||
The StringDamping and StringDetune messages behave the same as the Volume message, but use Control Numbers which aren't specifically nailed-down in MIDI. Note that these Control Numbers are carried around as long ints, so we're not limited to 0-127. If, however, you want to use a MIDI controller to play an instrument, using controller numbers in the 0-127 range might make sense.<h2><a class="anchor" name="using">
|
||||
Using SKINI:</a></h2>
|
||||
Here's a simple example of code which uses the <a class="el" href="classSKINI.html">SKINI</a> object to read a <a class="el" href="classSKINI.html">SKINI</a> file and control a single instrument.<p>
|
||||
<pre class="fragment"><div> instrument = <span class="keyword">new</span> <a class="code" href="classMandolin.html">Mandolin</a>(50.0);
|
||||
<div class="fragment"><pre> instrument = <span class="keyword">new</span> <a class="code" href="classMandolin.html">Mandolin</a>(50.0);
|
||||
score = <span class="keyword">new</span> <a class="code" href="classSKINI.html">SKINI</a>(argv[1]);
|
||||
<span class="keywordflow">while</span>(score->getType() > 0) {
|
||||
tempDouble = score->getDelta();
|
||||
@@ -178,7 +178,7 @@ Here's a simple example of code which uses the <a class="el" href="classSKINI.ht
|
||||
}
|
||||
score->nextMessage();
|
||||
}
|
||||
</div></pre><p>
|
||||
</pre></div><p>
|
||||
When the score (<a class="el" href="classSKINI.html">SKINI</a> object) object is created from the filename in argv[1], the first valid command line is read from the file and parsed.<p>
|
||||
The score->getType() retrieves the messageType. If this is -1, there are no more valid messages in the file and the synthesis loop terminates. Otherwise, the message type is returned.<p>
|
||||
getDelta() retrieves the deltaTime until the current message should occur. If this is greater than 0, synthesis occurs until the deltaTime has elapsed. If deltaTime is less than zero, the time is interpreted as absolute time and the output device is queried as to what time it is now. That is used to form a deltaTime, and if it's positive we synthesize. If it's negative, we print an error and pretend this never happened and we hang around hoping to eventually catch up.<p>
|
||||
|
||||
Reference in New Issue
Block a user