1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"1038.25">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
; min-height: 17.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #c40000}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #606060}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0010c4}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
20 span
.s1
{color: #606060}
21 span
.s2
{color: #000000}
22 span
.s3
{color: #0010c4}
23 span
.s4
{color: #007200}
24 span
.s5
{font: 12.0px Helvetica
}
25 span
.s6
{color: #007300}
26 span
.Apple-tab-span
{white-space:pre
}
30 <p class=
"p1"><b>Node Messaging
</b></p>
31 <p class=
"p2"><br></p>
32 <p class=
"p2"><br></p>
33 <p class=
"p3">The most direct and fast way to send commands to the server is to send messages to the Server object, if you are within sc-lang.
<span class=
"Apple-converted-space"> </span>If you are in a shell you can use
<b>sendOSC
</b> (available from CNMAT).
</p>
34 <p class=
"p4"><br></p>
35 <p class=
"p3">this messaging scheme is explained in detail in
<span class=
"Apple-converted-space"> </span></p>
36 <p class=
"p4"><br></p>
37 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Server-Architecture
</b></p>
38 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Server-Command-Reference
</b></p>
39 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Tutorial
</b></p>
40 <p class=
"p4"><br></p>
41 <p class=
"p3">When creating nodes on the server (synths and groups) the only things we need to know are the nodeID and the server (its address to be precise).
</p>
42 <p class=
"p4"><br></p>
43 <p class=
"p3">In order to communicate with a synth, one sends messages with its nodeID. If you do not intend to communicate with the node after its creation (and the node will cause itself to end without external messaging), the node id can be set to -
1, which is the server's equivalent to nil.
</p>
44 <p class=
"p4"><br></p>
45 <p class=
"p3">As soon as you want to pass around the reference to a certain node, assuming that you might not have only one server, it can be useful to create a Synth or Group object. These objects also respond to messages, and when needed can be used to obtain the state of the server side node.
</p>
46 <p class=
"p4"><br></p>
47 <p class=
"p3">see
<b>Node
</b>,
<b>Synth
</b>, and
<b>Group
</b> help for more detailed helpfiles on node objects.
</p>
48 <p class=
"p5"><br></p>
49 <p class=
"p5"><br></p>
50 <p class=
"p6">// the equivalent of
</p>
51 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n = s.nextNodeID;
</p>
52 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/s_new"</span>,
<span class=
"s1">"default"</span>, n);
</p>
53 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/n_free"</span>, n);
</p>
54 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
55 <p class=
"p6">// is
<span class=
"Apple-converted-space"> </span></p>
56 <p class=
"p8"><span class=
"s2"><span class=
"Apple-tab-span"> </span>n =
</span><span class=
"s3">Synth
</span><span class=
"s2">(
</span>"default"<span class=
"s2">);
</span></p>
57 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.free;
</p>
58 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
59 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
60 <p class=
"p6">// when passing arguments:
</p>
61 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n = s.nextNodeID;
</p>
62 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/s_new"</span>,
<span class=
"s1">"default"</span>, n,
0,
0,
<span class=
"s1">"freq"</span>,
850);
</p>
63 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/n_set"</span>, n,
<span class=
"s1">"freq"</span>,
500);
</p>
64 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/n_free"</span>, n);
</p>
65 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
66 <p class=
"p6">// it is
</p>
67 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n =
<span class=
"s3">Synth
</span>(
<span class=
"s1">"default"</span>, [
<span class=
"s4">\freq
</span>,
850]);
</p>
68 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.set(
<span class=
"s4">\freq
</span>,
500)
</p>
69 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.free;
</p>
70 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
71 <p class=
"p6">// note that Symbols may be used instead of Strings:
</p>
72 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n = s.nextNodeID;
</p>
73 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\s_new
</span>,
<span class=
"s4">\default
</span>, n,
0,
0,
<span class=
"s4">\freq
</span>,
850);
</p>
74 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\n_set
</span>, n,
<span class=
"s4">\freq
</span>,
500);
</p>
75 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\n_free
</span>, n);
</p>
76 <p class=
"p5"><br></p>
77 <p class=
"p6">// and:
</p>
78 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n =
<span class=
"s3">Synth
</span>(
<span class=
"s4">\default
</span>, [
<span class=
"s4">\freq
</span>,
850]);
</p>
79 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.set(
<span class=
"s4">\freq
</span>,
500)
</p>
80 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.free;
</p>
81 <p class=
"p5"><br></p>
82 <p class=
"p3">The answer to the question of whether one should work with
<b>node objects
</b>or
<b>directly with messages
</b> depends to some extent on context, and to some extent is a matter of personal taste.
</p>
83 <p class=
"p4"><br></p>
84 <p class=
"p3">The encapsulation of node objects results in a certain generalization, meaning that other compound objects can respond to the same messages and thus exploit polymorphism. They also provide a certain level of convienence, keeping track of indexes and IDs, etc.
</p>
85 <p class=
"p5"><br></p>
86 <p class=
"p3">In certain cases, such as for granular synthesis it is recommended to use messages directly, because there is no benefit to be gained from the node objects (i.e. no need to message them) and they add cpu load to the client side.
</p>
87 <p class=
"p4"><span class=
"Apple-tab-span"> </span></p>
88 <p class=
"p7"><span class=
"s5"><span class=
"Apple-tab-span"> </span></span>(
</p>
89 <p class=
"p9"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>SynthDef
<span class=
"s2">(
</span><span class=
"s1">"grain"</span><span class=
"s2">, {
<span class=
"Apple-converted-space"> </span></span></p>
90 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(
0,
<span class=
"s3">Line
</span>.kr(
0.1,
0,
0.01, doneAction:
2) *
<span class=
"s3">FSinOsc
</span>.ar(
12000))
</p>
91 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
92 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
93 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
94 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
95 <p class=
"p9"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>Routine
<span class=
"s2">({
<span class=
"Apple-converted-space"> </span></span></p>
96 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>20.do({
</p>
97 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s1">"/s_new"</span>,
<span class=
"s1">"grain"</span>, -
1);
<span class=
"Apple-converted-space"> </span></p>
98 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.01.wait;
</p>
99 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>})
</p>
100 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).play;
</p>
101 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
102 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
103 <p class=
"p5"><br></p>
104 <p class=
"p3">In cases where you need to keep track of the synth's state, it is advisable to use node objects and register them with a
<b>NodeWatcher
</b>. (see helpfile)
</p>
105 <p class=
"p4"><br></p>
106 <p class=
"p3">Apart from such cases it is a matter of taste whether you want to use the combination of message and a numerical global representation or an object representation. The two can be mixed, and certain advantages of the object style can be accessed when using messaging style. For instance Server.nextNodeID allows one to use dynamically assigned IDs in messaging style. As a gross generalization, it is probably fair to say that object style is more convienent, but messaging style is more efficient, due to reduce client-side CPU load.
</p>
107 <p class=
"p4"><br></p>
108 <p class=
"p3"><b>IMPORTANT NOTE:
</b> If you wish to have the functionality of the
<b>default_group
</b> (e.g. problem free use of Server's record and scope functionality) you should treat ID
1 (the default_group) as the root of your node tree rather than ID
0 (the
<b>RootNode
</b>). See
<b>default_group
</b> for more details.
</p>
109 <p class=
"p5"><br></p>
110 <p class=
"p3">Note that
<b>Function-play
</b> and
<b>SynthDef-play
</b> return a synth object that can be used to send messages to.
</p>
111 <p class=
"p5"><br></p>
112 <p class=
"p7">x = {
<span class=
"s3">arg
</span> freq=
1000;
<span class=
"s3">Ringz
</span>.ar(
<span class=
"s3">Crackle
</span>.ar(
1.95,
0.1), freq,
0.05) }.play(s);
</p>
113 <p class=
"p7">x.set(
<span class=
"s4">\freq
</span>,
1500);
</p>
114 <p class=
"p7">x.free;
</p>
115 <p class=
"p5"><br></p>
116 <p class=
"p4"><br></p>
117 <p class=
"p10"><b>Argument lists in node messages
</b></p>
118 <p class=
"p4"><br></p>
119 <p class=
"p3">Several node messages accept lists of values to map onto the controls of Synth nodes, as in some of the examples already given:
</p>
120 <p class=
"p4"><br></p>
121 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\s_new
</span>,
<span class=
"s4">\default
</span>, n,
0,
0,
<span class=
"s4">\freq
</span>,
850);
</p>
122 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n =
<span class=
"s3">Synth
</span>(
<span class=
"s4">\default
</span>, [
<span class=
"s4">\freq
</span>,
850]);
</p>
123 <p class=
"p4"><br></p>
124 <p class=
"p3">Argument lists generally appear as alternating pairs, with the control identifier preceding the value. Usually the control identifier is a name, as above, but it could also be an integer index. (Using integers is slightly faster for the server, but it makes the code harder to read and can introduce bugs if the SynthDef structure changes.) One way to find out control indices is to .add the SynthDef into a SynthDescLib, then get the list of all controls out of the SynthDesc.
</p>
125 <p class=
"p4"><br></p>
127 <p class=
"p9">SynthDef
<span class=
"s2">(
</span><span class=
"s4">\controlList
</span><span class=
"s2">, {
</span>|freq =
440, amp =
0.1, detune = #[
0.999,
1.001], gate =
1, out =
0|
</p>
128 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s3">Mix
</span>(
<span class=
"s3">Saw
</span>.ar(freq * (detune ++ [
1]), amp)),
</p>
129 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>env =
<span class=
"s3">EnvGen
</span>.kr(
<span class=
"s3">Env
</span>.adsr, gate, doneAction:
2);
</p>
130 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(
0, (sig * env) !
2);
</p>
131 <p class=
"p7">}).add;
</p>
132 <p class=
"p5"><br></p>
133 <p class=
"p9">SynthDescLib
<span class=
"s2">.global[
</span><span class=
"s4">\controlList
</span><span class=
"s2">]
</span></p>
135 <p class=
"p4"><br></p>
136 <p class=
"p3">Prints:
</p>
137 <p class=
"p4"><br></p>
138 <p class=
"p7">SynthDesc 'controlList'
<span class=
"Apple-converted-space"> </span></p>
139 <p class=
"p7">Controls:
</p>
140 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
0 freq control
440</p>
141 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
1 amp control
0.10000000149012</p>
142 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
2 detune control
0.9990000128746</p>
143 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
3 ? control
1.00100004673</p>
144 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
4 gate control
1</p>
145 <p class=
"p7">ControlName
<span class=
"Apple-converted-space"> </span>P
5 out control
0</p>
146 <p class=
"p7"><span class=
"Apple-converted-space"> </span>O audio
0 2</p>
147 <p class=
"p4"><br></p>
148 <p class=
"p3">The list shows that the 'freq' control has index
0, 'amp' is
1 and so on. Detune is defined as an
"array argument," occupying indices
2-
3.
</p>
149 <p class=
"p4"><br></p>
150 <p class=
"p3">SynthDefs with a large number of controls may need a little extra code to print the entire list.
</p>
151 <p class=
"p4"><br></p>
152 <p class=
"p7"><span class=
"s3">SynthDescLib
</span>.global[
<span class=
"s4">\controlList
</span>].controls.do(
<span class=
"s3">_
</span>.postln);
<span class=
"s1">""</span></p>
153 <p class=
"p4"><br></p>
154 <p class=
"p3">Prior to SuperCollider
3.3, the only way to set array arguments by name was using n_setn (or Node's setn method). Beginning in version
3.3, array arguments can be included in s_new or n_set messages transparently.
</p>
155 <p class=
"p4"><br></p>
156 <p class=
"p3"><b>Messaging style
</b> (note the characters $[ and $] delimiting the array in the list):
</p>
157 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n = s.nextNodeID;
</p>
158 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\s_new
</span>,
<span class=
"s4">\controlList
</span>, n,
0,
0,
<span class=
"s4">\detune
</span>, $[,
0.95,
1.005, $],
<span class=
"s4">\freq
</span>,
220);
</p>
159 <p class=
"p7"><span class=
"Apple-tab-span"> </span>s.sendMsg(
<span class=
"s4">\n_set
</span>, n,
<span class=
"s4">\gate
</span>,
0);
</p>
160 <p class=
"p4"><br></p>
161 <p class=
"p3"><b>Object style
</b> (the Node object automatically inserts $[ and $] for you):
</p>
162 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n =
<span class=
"s3">Synth
</span>(
<span class=
"s4">\controlList
</span>, [
<span class=
"s4">\detune
</span>, [
0.95,
1.005],
<span class=
"s4">\freq
</span>,
220]);
</p>
163 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.set(
<span class=
"s6">\detune
</span>, [
0.99,
1.01]);
</p>
164 <p class=
"p7"><span class=
"Apple-tab-span"> </span>n.release;
</p>
165 <p class=
"p4"><br></p>
166 <p class=
"p3"><b>Event style:
</b></p>
167 <p class=
"p4"><br></p>
168 <p class=
"p3">Supplying an array for an argument in an event already has another meaning: multichannel expansion, in which a separate node is created for each array item. If all items of the array should be sent to the same node, then the array argument should be enclosed in another array level:
</p>
169 <p class=
"p4"><br></p>
170 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(instrument:
<span class=
"s4">\controlList
</span>, freq:
220, detune: [[
0.95,
1.005]], sustain:
2).play;
</p>