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=
"949.54">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 20.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #001de0}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
; min-height: 17.0px}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #6f3424}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #a31917}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
21 p
.p12
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #000000; min-height: 14.0px}
22 p
.p13
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
23 p
.p14
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
24 p
.p15
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
25 p
.p16
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0000bf}
26 p
.p17
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #1429a1; min-height: 12.0px}
27 p
.p18
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #606060}
28 span
.s1
{color: #000000}
29 span
.s2
{text-decoration: underline
}
30 span
.s3
{font: 12.0px Helvetica
}
31 span
.s4
{color: #0728e8}
32 span
.s5
{color: #1429a1}
33 span
.s6
{color: #576831}
34 span
.s7
{color: #0017b3}
35 span
.s8
{color: #606060}
36 span
.s9
{color: #0000bf}
37 span
.s10
{color: #007300}
38 span
.Apple-tab-span
{white-space:pre
}
42 <p class=
"p1"><b>Order of execution
<span class=
"Apple-converted-space"> </span></b></p>
43 <p class=
"p2"><br></p>
44 <p class=
"p3"><span class=
"s1"><b>See also:
</b><a href=
"Server.html"><span class=
"s2">Server
</span></a>,
<a href=
"Node.html"><span class=
"s2">Node
</span></a>,
<a href=
"Group.html"><span class=
"s2">Group
</span></a>,
<a href=
"default_group.html"><span class=
"s2">default_group
</span></a>,
<a href=
"Bus.html"><span class=
"s2">Bus
</span></a>,
<a href=
"../UGens/InOut/Out.html"><span class=
"s2">Out
</span></a>,
<a href=
"../UGens/InOut/ReplaceOut.html"><span class=
"s2">ReplaceOut
</span></a>,
<a href=
"../UGens/InOut/XOut.html"><span class=
"s2">XOut
</span></a>,
<a href=
"../UGens/InOut/OffsetOut.html"><span class=
"s2">OffsetOut
</span></a>,
<a href=
"../UGens/InOut/In.html"><span class=
"s2">In
</span></a>,
<a href=
"../UGens/InOut/InFeedback.html"><span class=
"s2">InFeedback
</span></a>,
<a href=
"../UGens/InOut/LocalIn.html"><span class=
"s2">LocalIn
</span></a>,
<a href=
"../UGens/InOut/LocalOut.html"><span class=
"s2">LocalOut
</span></a>,
<a href=
"../UGens/InOut/SharedIn.html"><span class=
"s2">SharedIn
</span></a>,
<a href=
"../UGens/InOut/SharedOut.html"><span class=
"s2">SharedOut
</span></a></span></p>
45 <p class=
"p2"><br></p>
46 <p class=
"p4">Order of execution is one of the most critical and seemingly difficult aspects of using SuperCollider, but in reality it only takes a little thought in the early planning stages to make it work for you.
<span class=
"Apple-converted-space"> </span></p>
47 <p class=
"p2"><br></p>
48 <p class=
"p4">Order of execution in this context doesn't mean the order in which statements are executed in the language (the client). It refers to the ordering of synth nodes on the server, which corresponds to the order in which their output is calculated each control cycle (blockSize). Whether or not you specify the order of execution, each synth and each group goes into a specific place in the chain of execution.
</p>
49 <p class=
"p2"><br></p>
50 <p class=
"p4">If you have on the server:
</p>
51 <p class=
"p2"><br></p>
52 <p class=
"p4"><span class=
"Apple-tab-span"> </span>synth
1 ---
> synth
2<span class=
"Apple-converted-space"> </span></p>
53 <p class=
"p2"><br></p>
54 <p class=
"p4">... all the unit generators associated with synth
1 will execute before those in synth
2 during each control cycle.
<span class=
"Apple-converted-space"> </span></p>
55 <p class=
"p2"><br></p>
56 <p class=
"p4">If you don't have any synths that use In.ar, you don't have to worry about order of execution. It only matters when one synth is reading the output of another.
</p>
57 <p class=
"p2"><br></p>
58 <p class=
"p4">The rule is simple: if you have a synth on the server (i.e. an
"effect") that depends on the output from another synth (the
"source"), the effect must appear later in the chain of nodes on the server than the source.
</p>
59 <p class=
"p2"><br></p>
60 <p class=
"p4"><span class=
"Apple-tab-span"> </span>source ---
> effect
<span class=
"Apple-converted-space"> </span></p>
61 <p class=
"p2"><br></p>
62 <p class=
"p4">If you have:
</p>
63 <p class=
"p2"><br></p>
64 <p class=
"p4"><span class=
"Apple-tab-span"> </span>effect ---
> source
<span class=
"Apple-converted-space"> </span></p>
65 <p class=
"p2"><br></p>
66 <p class=
"p4">The effect synth will not hear the source synth, and you won't get the results you want.
<span class=
"Apple-converted-space"> </span></p>
67 <p class=
"p2"><br></p>
68 <p class=
"p4">Below is a diagram of a typical server configuration:
</p>
69 <p class=
"p2"><br></p>
70 <p class=
"p5"><span class=
"s3"><img src=
"attachments/Order-of-execution/server.png" alt=
"attachments/Order-of-execution/server.png"></span></p>
71 <p class=
"p2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
72 <p class=
"p4">On the server external signals can be received by synths from
"public" input busses (one in the represented case), while the different synths must be connected to
"public" out audio busses (two in the case) in order to output a signal externally to the soundcard (see
<a href=
"Bus.html"><span class=
"s4">Bus
</span></a>). Other busses (both control and audio) are internal. In general, busses can be thought as roughly analogous to sends, busses, or submixes on an analog mixer, or as pipes allowing one to route
"flowing" signals. If a synth is connected to a bus at a certain point (thus
"flowing" into it)
<span class=
"Apple-converted-space"> </span>a synth taking the signal from the same bus at a subsequent point will take as input the flowing signal (along with anything else previously output to the bus), just as would occur with a water pipe.
</p>
73 <p class=
"p2"><br></p>
74 <p class=
"p6"><b>Some Notes about Servers and Targets
</b></p>
75 <p class=
"p7"><br></p>
76 <p class=
"p4">There is always a default
<a href=
"Server.html"><span class=
"s4">Server
</span></a>, which can be accessed or set through the class method Server.default. At startup this is set to be the local Server, and is also assigned to the interpreter variable s.
</p>
77 <p class=
"p2"><br></p>
78 <p class=
"p8">// execute the following and watch the post window
</p>
79 <p class=
"p9">s ===
<span class=
"s5">Server
</span>.default;
</p>
80 <p class=
"p9">s ===
<span class=
"s5">Server
</span>.local;
</p>
81 <p class=
"p9"><span class=
"s5">Server
</span>.default =
<span class=
"s5">Server
</span>.internal; s ===
<span class=
"s5">Server
</span>.default;
</p>
82 <p class=
"p8"><span class=
"s5">Server
</span><span class=
"s1">.default =
</span><span class=
"s5">Server
</span><span class=
"s1">.local;
</span>// return it to the local server
</p>
83 <p class=
"p2"><br></p>
84 <p class=
"p4">When a
<a href=
"Server.html"><span class=
"s4">Server
</span></a> is booted there is a top level group with an ID of
0 that defines the root of the node tree. This is represented by a subclass of
<a href=
"Group.html"><span class=
"s4">Group
</span></a>:
<a href=
"RootNode.html"><span class=
"s4">RootNode
</span></a>. There is also a
<a href=
"default_group.html"><span class=
"s4">default_group
</span></a> with an ID of
1. This group is the default group for all Nodes. This is what you will get if you supply a Server as a target. If you don't specify a target or pass in nil, you will get the default group of the default Server.
<span class=
"Apple-converted-space"> </span></p>
85 <p class=
"p2"><br></p>
86 <p class=
"p4">The default group serves an important purpose: It provides a predictable basic Node tree so that methods such as Server:scope and Server:record can function without running into order of execution problems. Thus in general one should create new Nodes within the default group rather than in the RootNode. See
<a href=
"default_group.html"><span class=
"s4">default_group
</span></a> and
<a href=
"RootNode.html"><span class=
"s4">RootNode
</span></a><b> </b>for more detail.
</p>
87 <p class=
"p7"><br></p>
88 <p class=
"p6"><b>Controlling order of execution
<span class=
"Apple-converted-space"> </span></b></p>
89 <p class=
"p2"><br></p>
90 <p class=
"p4">There are three ways to control the order of execution: using addAction in your synth creation messages, moving nodes, and placing your synths in groups. Using groups is optional, but they are the most effective in helping you organize the order of execution.
</p>
91 <p class=
"p2"><br></p>
92 <p class=
"p4"><b>Add actions:
</b></p>
93 <p class=
"p2"><br></p>
94 <p class=
"p4">By specifying an addAction argument for
<b>Synth.new
</b> (or SynthDef.play, Function.play, etc.) one can specify the node's placement relative to a target. The target might be a group node, another synth node, or a server.
<span class=
"Apple-converted-space"> </span></p>
95 <p class=
"p2"><br></p>
96 <p class=
"p4">As noted above, the default target is the
<a href=
"default_group.html"><span class=
"s4">default_group
</span></a> (the group with
<b>nodeID
1</b>) of the default Server.
<span class=
"Apple-converted-space"> </span></p>
97 <p class=
"p2"><br></p>
98 <p class=
"p4"><span class=
"Apple-converted-space"> </span>The following Symbols are valid addActions for Synth.new:
<span class=
"s6">\addToHead
</span>,
<span class=
"s6">\addToTail
</span>,
<span class=
"s6">\addBefore
</span>,
<span class=
"s6">\addAfter
</span>,
<span class=
"s6">\addReplace
</span>.
</p>
99 <p class=
"p2"><br></p>
100 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.new(defName, args, target, addAction)
</b></p>
101 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is a Synth the
<span class=
"Apple-converted-space"> </span><span class=
"s6">\addToHead
</span>, and
<span class=
"s6">\addToTail
</span> methods will apply to that Synths group
</p>
102 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is a Server it will resolve to that Server's default group
</p>
103 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is nil it will resolve to the default group of the default Server
</p>
104 <p class=
"p2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-converted-space"> </span></p>
105 <p class=
"p4">For each addAction there is also a corresponding convenience method of class
<a href=
"Synth.html"><span class=
"s4">Synth
</span></a>:
</p>
106 <p class=
"p2"><b><span class=
"Apple-tab-span"> </span></b></p>
107 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.head(aGroup, defName, args)
</b></p>
108 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b>add the new synth to the the head of the group specified by aGroup
</p>
109 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if aGroup is a synth node, the new synth will be added to the head of that node's group
</p>
110 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is a Server it will resolve to that Server's default group
</p>
111 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is nil it will resolve to the default group of the default Server
</p>
112 <p class=
"p2"><br></p>
113 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.tail(aGroup, defName, args)
</b></p>
114 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b>add the new synth to the the tail of the group specified by aGroup
</p>
115 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if aGroup is a synth node, the new synth will be added to the tail of that node's group
</p>
116 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is a Server it will resolve to that Server's default group
</p>
117 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if target is nil it will resolve to the default group of the default Server
</p>
118 <p class=
"p2"><b><span class=
"Apple-tab-span"> </span></b></p>
119 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.before(aNode, defName, args)
</b></p>
120 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b>add the new node just before the node specified by aNode.
</p>
121 <p class=
"p2"><br></p>
122 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.after(aNode, defName, args)
</b></p>
123 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b>add the new node just after the node specified by aNode.
</p>
124 <p class=
"p2"><br></p>
125 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>Synth.replace(synthToReplace, defName, args)
</b></p>
126 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></b>the new node replaces the node specified by synthToReplace. The target node is freed.
</p>
127 <p class=
"p2"><br></p>
128 <p class=
"p4">Using Synth.new without an addAction will result in the default addAction. (You can check the default values for the arguments of any method by looking at a class' source code. See
<a href=
"../Other Topics/Internal-Snooping.html"><span class=
"s4">Internal-Snooping
</span></a> for more details.) Where order of execution matters, it is important that you specify an addAction, or use one of the convenience methods shown above.
</p>
129 <p class=
"p2"><br></p>
130 <p class=
"p2"><br></p>
131 <p class=
"p4"><b>Moving nodes:
</b></p>
132 <p class=
"p2"><br></p>
133 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>.moveBefore
</b></p>
134 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>.moveAfter
</b></p>
135 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>.moveToHead
</b></p>
136 <p class=
"p4"><b><span class=
"Apple-tab-span"> </span>.moveToTail
</b></p>
137 <p class=
"p2"><br></p>
138 <p class=
"p4">If you need to change the order of execution after synths and groups have been created, you can do this using move messages.
</p>
139 <p class=
"p2"><br></p>
140 <p class=
"p9"><span class=
"Apple-tab-span"> </span>~fx =
<span class=
"s7">Synth
</span>.tail(s,
<span class=
"s8">"fx"</span>);
</p>
141 <p class=
"p10"><span class=
"s1"><span class=
"Apple-tab-span"> </span>~src =
</span><span class=
"s7">Synth
</span><span class=
"s1">.tail(s,
</span><span class=
"s8">"src"</span><span class=
"s1">);
<span class=
"Apple-converted-space"> </span></span>// effect will not be heard b/c it's earlier
</p>
142 <p class=
"p10"><span class=
"s1"><span class=
"Apple-tab-span"> </span>~src.moveBefore(~fx);
<span class=
"Apple-converted-space"> </span></span>// place the source before the effect
</p>
143 <p class=
"p11"><span class=
"Apple-tab-span"> </span></p>
144 <p class=
"p2"><br></p>
145 <p class=
"p4"><b>Groups
<span class=
"Apple-converted-space"> </span></b></p>
146 <p class=
"p2"><br></p>
147 <p class=
"p4">Groups can be moved in the same way as synths. When you move a group, all the synths in that group move with it. This is why groups are such an important tool for managing order of execution. (See the
<b>Group
</b> helpfile for details on this and other convenient aspects of Groups.)
</p>
148 <p class=
"p2"><br></p>
149 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>Group
1 ---
> Group
2</p>
150 <p class=
"p2"><br></p>
151 <p class=
"p4">In the above configuration, all of the synths in group
1 will execute before all of the synths in group
2. This is an easy, easy way to make the order of execution happen the way you want it to.
<span class=
"Apple-converted-space"> </span></p>
152 <p class=
"p2"><br></p>
153 <p class=
"p4">Determine your architecture, then make groups to support the architecture.
</p>
154 <p class=
"p2"><br></p>
155 <p class=
"p2"><br></p>
156 <p class=
"p4"><b>Using order of execution to your advantage
<span class=
"Apple-converted-space"> </span></b></p>
157 <p class=
"p2"><br></p>
158 <p class=
"p4">Before you start coding, plan out what you want and decide where the synths need to go.
<span class=
"Apple-converted-space"> </span></p>
159 <p class=
"p2"><br></p>
160 <p class=
"p4">A common configuration is to have a routine playing nodes, all of which need to be processed by a single effect. Plus, you want this effect to be separate from other things running at the same time. To be sure, you should place the synth -
> effect chain on a private audio bus, then transfer it to the main output.
</p>
161 <p class=
"p2"><br></p>
162 <p class=
"p4"><span class=
"Apple-tab-span"> </span>[Lots of synths] ----
> effect ----
> transfer
</p>
163 <p class=
"p2"><br></p>
164 <p class=
"p4">This is a perfect place to use a group:
</p>
165 <p class=
"p2"><br></p>
166 <p class=
"p4"><span class=
"Apple-tab-span"> </span>Group ( [lots of synths] ) ----
> effect ----
> transfer
</p>
167 <p class=
"p2"><br></p>
168 <p class=
"p4">To make the structure clearer in the code, one can also make a group for the effect (even if there's only one synth in it):
</p>
169 <p class=
"p2"><br></p>
170 <p class=
"p4"><span class=
"Apple-tab-span"> </span>Group ( [lots of synths] ) ----
> Group ( [effect] ) ----
> transfer
<span class=
"Apple-converted-space"> </span></p>
171 <p class=
"p2"><br></p>
172 <p class=
"p4">I'm going to throw a further wrench into the example by modulating a parameter (note length) using a control rate synth.
</p>
173 <p class=
"p2"><br></p>
174 <p class=
"p4">So, at the beginning of your program:
</p>
175 <p class=
"p12"><br></p>
176 <p class=
"p13">s.boot;
</p>
177 <p class=
"p14"><br></p>
179 <p class=
"p15"><span class=
"s1">l =
</span><span class=
"s9">Bus
</span><span class=
"s1">.control(s,
1);
<span class=
"Apple-converted-space"> </span></span>// get a bus for the LFO--not relevant to order-of-exec
</p>
180 <p class=
"p15"><span class=
"s1">b =
</span><span class=
"s9">Bus
</span><span class=
"s1">.audio(s,
2);
<span class=
"Apple-tab-span"> </span></span>// assuming stereo--this is to keep the src-
>fx chain separate from
</p>
181 <p class=
"p15"><span class=
"s1"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// other similar chains
</p>
182 <p class=
"p13">~synthgroup =
<span class=
"s9">Group
</span>.tail(s);
</p>
183 <p class=
"p13">~fxgroup =
<span class=
"s9">Group
</span>.tail(s);
</p>
184 <p class=
"p14"><br></p>
185 <p class=
"p15">// now you have synthgroup --
> fxgroup within the default group of s
</p>
186 <p class=
"p14"><br></p>
187 <p class=
"p15">// make some synthdefs to play with
</p>
188 <p class=
"p13"><span class=
"s9">SynthDef
</span>(
<span class=
"s8">"order-of-ex-dist"</span>, {
<span class=
"s9">arg
</span> bus, preGain, postGain;
</p>
189 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">var
</span> sig;
</p>
190 <p class=
"p13"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s9">In
</span>.ar(bus,
2);
</p>
191 <p class=
"p13"><span class=
"Apple-tab-span"> </span>sig = (sig * preGain).distort;
</p>
192 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">ReplaceOut
</span>.ar(bus, sig * postGain);
</p>
193 <p class=
"p13">}).add;
</p>
194 <p class=
"p14"><br></p>
195 <p class=
"p13"><span class=
"s9">SynthDef
</span>(
<span class=
"s8">"order-of-ex-pulse"</span>, {
<span class=
"s9">arg
</span> freq, bus, ffreq, pan, lfobus;
</p>
196 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">var
</span> sig, noteLen;
</p>
197 <p class=
"p13"><span class=
"Apple-tab-span"> </span>noteLen =
<span class=
"s9">In
</span>.kr(lfobus,
1);
</p>
198 <p class=
"p13"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s9">RLPF
</span>.ar(
<span class=
"s9">Pulse
</span>.ar(freq,
0.2,
0.5), ffreq,
0.3);
</p>
199 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">Out
</span>.ar(bus,
<span class=
"s9">Pan2
</span>.ar(sig, pan)
</p>
200 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*
<span class=
"s9">EnvGen
</span>.kr(
<span class=
"s9">Env
</span>.perc(
0.1,
1), timeScale: noteLen, doneAction:
2));
</p>
201 <p class=
"p13">}).add;
</p>
202 <p class=
"p14"><br></p>
203 <p class=
"p13"><span class=
"s9">SynthDef
</span>(
<span class=
"s8">"LFNoise1"</span>, {
<span class=
"s9">arg
</span> freq, mul, add, bus;
</p>
204 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">Out
</span>.kr(bus,
<span class=
"s9">LFNoise1
</span>.kr(freq, mul:mul, add:add));
</p>
205 <p class=
"p13">}).add;
</p>
207 <p class=
"p14"><br></p>
208 <p class=
"p15">// Place LFO:
</p>
209 <p class=
"p14"><br></p>
210 <p class=
"p13">~lfo =
<span class=
"s9">Synth
</span>.head(s,
<span class=
"s8">"LFNoise1"</span>, [
<span class=
"s10">\freq
</span>,
0.3,
<span class=
"s10">\mul
</span>,
0.68,
<span class=
"s10">\add
</span>,
0.7,
<span class=
"s10">\bus
</span>, l]);
</p>
211 <p class=
"p14"><br></p>
212 <p class=
"p15">// Then place your effect:
<span class=
"Apple-converted-space"> </span></p>
213 <p class=
"p14"><br></p>
214 <p class=
"p13">~dist =
<span class=
"s9">Synth
</span>.tail(~fxgroup,
<span class=
"s8">"order-of-ex-dist"</span>, [
<span class=
"s10">\bus
</span>, b,
<span class=
"s10">\preGain
</span>,
8,
<span class=
"s10">\postGain
</span>,
0.6]);
</p>
215 <p class=
"p14"><br></p>
216 <p class=
"p15">// transfer the results to main out, with level scaling
</p>
217 <p class=
"p15">// play at tail of s's default group (note that Function-play also takes addActions!
</p>
218 <p class=
"p14"><br></p>
219 <p class=
"p13">~xfer = {
<span class=
"s9">Out
</span>.ar(
0,
0.25 *
<span class=
"s9">In
</span>.ar(b,
2)) }.play(s, addAction:
<span class=
"s10">\addToTail
</span>);
<span class=
"Apple-converted-space"> </span></p>
220 <p class=
"p14"><br></p>
221 <p class=
"p15">// And start your routine:
</p>
222 <p class=
"p14"><br></p>
224 <p class=
"p16"><span class=
"s1">r =
</span>Routine
<span class=
"s1">({
</span></p>
225 <p class=
"p13"><span class=
"Apple-tab-span"> </span>{
</p>
226 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s9">Synth
</span>.tail(~synthgroup,
<span class=
"s8">"order-of-ex-pulse"</span>,
</p>
227 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>[
<span class=
"s10">\freq
</span>, rrand(
200,
800),
<span class=
"s10">\ffreq
</span>, rrand(
1000,
15000),
<span class=
"s10">\pan
</span>,
1.0.rand2,
</p>
228 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s10">\bus
</span>, b,
<span class=
"s10">\lfobus
</span>, l]);
</p>
229 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.07.wait;
</p>
230 <p class=
"p13"><span class=
"Apple-tab-span"> </span>}.loop;
</p>
231 <p class=
"p16"><span class=
"s1">}).play(
</span>SystemClock
<span class=
"s1">);
</span></p>
233 <p class=
"p14"><br></p>
234 <p class=
"p15"><span class=
"s1">~dist.run(
</span><span class=
"s9">false
</span><span class=
"s1">);
<span class=
"Apple-tab-span"> </span></span>// proves that the distortion effect is doing something
</p>
235 <p class=
"p13">~dist.run(
<span class=
"s9">true
</span>);
</p>
236 <p class=
"p14"><br></p>
237 <p class=
"p15">// to clean up:
</p>
239 <p class=
"p13">r.stop;
</p>
240 <p class=
"p13">[~synthgroup, ~fxgroup, b, l, ~lfo, ~xfer].do({
<span class=
"s9">arg
</span> x; x.free });
</p>
241 <p class=
"p15"><span class=
"s1">currentEnvironment.clear;
</span>// clear all environment variables
</p>
243 <p class=
"p2"><br></p>
244 <p class=
"p4">Note that in the routine, using a Group for the source synths allows their order to easily be specified relative to each other (they are added with the .tail method), without worrying about their order relative to the effect synth.
</p>
245 <p class=
"p2"><br></p>
246 <p class=
"p4">Note that this arrangement prevents errors in order of execution, through the use of a small amount of organizational code. Although straightforward here, this arrangement could easily be scaled to a larger project.
</p>
247 <p class=
"p2"><br></p>
248 <p class=
"p2"><br></p>
249 <p class=
"p4"><b>Messaging Style
</b></p>
250 <p class=
"p2"><br></p>
251 <p class=
"p4">The above examples are in 'object style'. Should you prefer to work in 'messaging style' there are corresponding messages to all of the methods shown above. See
<a href=
"NodeMessaging.html"><span class=
"s4">NodeMessaging
</span></a>, and
<a href=
"Server-Command-Reference.html"><span class=
"s4">Server-Command-Reference
</span></a> for more details.
</p>
252 <p class=
"p2"><br></p>
253 <p class=
"p2"><br></p>
254 <p class=
"p6"><b>Feedback
</b></p>
255 <p class=
"p7"><br></p>
256 <p class=
"p4">When the various output ugens (
<a href=
"../UGens/InOut/Out.html"><span class=
"s4">Out
</span></a>,
<a href=
"../UGens/InOut/OffsetOut.html"><span class=
"s4">OffsetOut
</span></a>,
<a href=
"../UGens/InOut/XOut.html"><span class=
"s4">XOut
</span></a>) write data to a bus, they
<i>mix
</i> it with any data from the current cycle, but
<i>overwrite
</i> any data from the previous cycle. (
<a href=
"../UGens/InOut/ReplaceOut.html"><span class=
"s4">ReplaceOut
</span></a> overwrites all data regardless.) Thus depending on node order, the data on a given bus may be from the current cycle or be one cycle old. In the case of input ugens (see
<a href=
"../UGens/InOut/In.html"><span class=
"s4">In
</span></a> and
<a href=
"../UGens/InOut/InFeedback.html"><span class=
"s4">InFeedback
</span></a>)
<b>In.ar
</b> checks the timestamp of any data it reads in and zeros any data from the previous cycle (for use within that synth; the data remains on the bus). This is fine for audio data, as it avoids feedback, but for control data it is useful to be able to read data from any place in the node order. For this reason
<b>In.kr
</b> also reads data that is older than the current cycle.
</p>
257 <p class=
"p2"><br></p>
258 <p class=
"p4">In some cases we might also want to read audio from a node later in the current node order. This is the purpose of
<a href=
"../UGens/InOut/InFeedback.html"><span class=
"s4">InFeedback
</span></a>. The delay introduced by this is at maximum one block size, which equals about
0.0014 sec at the default block size and sample rate.
</p>
259 <p class=
"p2"><br></p>
260 <p class=
"p4">The variably mixing and overwriting behaviour of the output ugens can make order of execution crucial when using
<b>In.kr
</b> or
<b>InFeedback.ar
</b>. (No pun intended.) For example with a node order like the following the InFeedback ugen in Synth
2 will only receive data from Synth
1 (-
> = write out;
<- = read in):
</p>
261 <p class=
"p2"><br></p>
262 <p class=
"p4">Synth
1 -
> busA
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>this synth overwrites the output of Synth3 before it reaches Synth
2</p>
263 <p class=
"p4">Synth
2 (with InFeedback)
<- busA
<span class=
"Apple-converted-space"> </span></p>
264 <p class=
"p4">Synth
3 -
> busA
</p>
265 <p class=
"p2"><br></p>
266 <p class=
"p4">If Synth
1 were moved after Synth
2 then Synth
2's InFeedback would receive a mix of the output from Synth
1 and Synth
3. This would also be true if Synth
2 came after Synth1 and Synth
3. In both cases data from Synth
1 and Synth
3 would have the same time stamp (either current or from the previous cycle), so nothing would be overwritten.
</p>
267 <p class=
"p2"><br></p>
268 <p class=
"p4">(As well, if any In.ar wrote to busA earlier in the node order than Synth
2, it would zero the bus before Synth
3's data reached Synth
2. This is true even it there were no node before Synth
2 writing to busA.)
</p>
269 <p class=
"p2"><br></p>
270 <p class=
"p4">Because of this it is often useful to allocate a separate bus for feedback. With the following arrangement Synth
2 will receive data from Synth3 regardless of Synth
1's position in the node order.
</p>
271 <p class=
"p17"><br></p>
272 <p class=
"p4">Synth
1 -
> busA
</p>
273 <p class=
"p4">Synth
2 (with InFeedback)
<- busB
<span class=
"Apple-converted-space"> </span></p>
274 <p class=
"p4">Synth
3 -
> busB + busA
<span class=
"Apple-converted-space"> </span></p>
275 <p class=
"p2"><br></p>
276 <p class=
"p4">The following example demonstrates this issue with In.kr:
</p>
277 <p class=
"p14"><br></p>
279 <p class=
"p18"><span class=
"s9">SynthDef
</span><span class=
"s1">(
</span>"help-Infreq"<span class=
"s1">, {
</span><span class=
"s9">arg
</span><span class=
"s1"> bus;
</span></p>
280 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">Out
</span>.ar(
0,
<span class=
"s9">FSinOsc
</span>.ar(
<span class=
"s9">In
</span>.kr(bus),
0,
0.5));
</p>
281 <p class=
"p13">}).add;
</p>
282 <p class=
"p14"><br></p>
283 <p class=
"p13"><span class=
"s9">SynthDef
</span>(
<span class=
"s8">"help-Outfreq"</span>, {
<span class=
"s9">arg
</span> freq =
400, bus;
</p>
284 <p class=
"p13"><span class=
"Apple-tab-span"> </span><span class=
"s9">Out
</span>.kr(bus,
<span class=
"s9">SinOsc
</span>.kr(
1,
0, freq/
40, freq));
</p>
285 <p class=
"p13">}).add;
</p>
286 <p class=
"p14"><br></p>
287 <p class=
"p13">b =
<span class=
"s9">Bus
</span>.control(s,
1);
</p>
289 <p class=
"p14"><br></p>
290 <p class=
"p15">// add the first control Synth at the tail of the default server; no audio yet
</p>
291 <p class=
"p13">x =
<span class=
"s9">Synth
</span>.tail(s,
<span class=
"s8">"help-Outfreq"</span>, [
<span class=
"s10">\bus
</span>, b]);
</p>
292 <p class=
"p14"><br></p>
293 <p class=
"p15">// add the sound producing Synth BEFORE it; It receives x's data from the previous cycle
</p>
294 <p class=
"p13">y =
<span class=
"s9">Synth
</span>.before(x,
<span class=
"s8">"help-Infreq"</span>, [
<span class=
"s10">\bus
</span>, b]);
</p>
295 <p class=
"p14"><br></p>
296 <p class=
"p15">// add another control Synth before y, at the head of the server
</p>
297 <p class=
"p15">// It now overwrites x's cycle old data before y receives it
</p>
298 <p class=
"p13">z =
<span class=
"s9">Synth
</span>.head(s,
<span class=
"s8">"help-Outfreq"</span>, [
<span class=
"s10">\bus
</span>, b,
<span class=
"s10">\freq
</span>,
800]);
</p>
299 <p class=
"p14"><br></p>
300 <p class=
"p15">// get another bus
</p>
301 <p class=
"p13">c =
<span class=
"s9">Bus
</span>.control(s,
1);
</p>
302 <p class=
"p14"><br></p>
303 <p class=
"p15">// now y receives x's data even though z is still there
</p>
304 <p class=
"p13">y.set(
<span class=
"s10">\bus
</span>, c); x.set(
<span class=
"s10">\bus
</span>, c);
</p>
305 <p class=
"p14"><br></p>
306 <p class=
"p13">x.free; y.free; z.free;
</p>