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=
"824.44">
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: 12.0px Helvetica
; min-height: 14.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: 14.0px Helvetica
}
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: #bf0000}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #606060}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
; min-height: 17.0px}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco
; min-height: 12.0px}
21 p
.p12
{margin: 0.0px 0.0px 0.0px 56.0px; text-indent: -56.0px; font: 9.0px Monaco
; color: #000000}
22 p
.p13
{margin: 0.0px 0.0px 0.0px 56.0px; text-indent: -56.0px; font: 9.0px Monaco
; color: #bf0000}
23 p
.p14
{margin: 0.0px 0.0px 0.0px 56.0px; text-indent: -56.0px; font: 9.0px Monaco
; color: #000000; min-height: 12.0px}
24 p
.p15
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0016e6}
25 span
.s1
{color: #1031f7}
26 span
.s2
{color: #000000}
27 span
.s3
{color: #0000bf}
28 span
.s4
{color: #606060}
29 span
.s5
{color: #007300}
30 span
.s6
{color: #0018f7}
31 span
.s7
{font: 12.0px Helvetica
}
32 span
.s8
{font: 12.0px Helvetica
; color: #000000}
33 span
.s9
{text-decoration: underline
}
34 span
.s10
{font: 12.0px Helvetica
; color: #0016e6}
35 span
.Apple-tab-span
{white-space:pre
}
39 <p class=
"p1"><b>Busses
</b></p>
40 <p class=
"p2"><br></p>
41 <p class=
"p3">Now a little bit more about busses on the server. Busses are named after the busses or sends in analog mixing desks, and they serve a similar purpose: Routing signals from one place to another. In SC this means to or from the audio hardware, or between different synths. They come in two types: audio rate and control rate. As you've probably guessed, the former routes audio rate signals and the latter routes control rate signals.
</p>
42 <p class=
"p2"><br></p>
43 <p class=
"p3">The control rate busses are fairly simple to understand, each one has an index number, starting from
0.
</p>
44 <p class=
"p2"><br></p>
45 <p class=
"p3">Audio rate busses are similar, but require slightly more explanation. A server app will have a certain number of output and input channels. These correspond to the first audio busses, with outputs coming before inputs.
<span class=
"Apple-converted-space"> </span></p>
46 <p class=
"p2"><br></p>
47 <p class=
"p3">For example, if we imagine a server with two output channels and two input channels (i.e. stereo in and out) then the first two audio busses (index
0 and index
1) will be the outputs, and the two immediately following those (index
2 and index
3) will be the inputs. Writing audio out to one of the output busses will result in sound being played from your speakers, and reading audio in from the input busses will get sound into SC for things like recording and processing (providing you have a source such as a microphone connected to your computer's or audio interface's inputs).
</p>
48 <p class=
"p2"><br></p>
49 <p class=
"p3">The remaining audio busses will be 'private'. These are used simply to send audio and control signals between various synths. Sending audio to a private bus will not result in sound in your speakers unless you reroute it later to one of the output busses. These 'private' busses are often used for things like an 'effects send', i.e. something that requires further processing before it's output.
</p>
50 <p class=
"p2"><br></p>
51 <p class=
"p3">The number of control and audio busses available, as well as the number of input and output channels is set at the time the server app is booted.(See
<a href=
"../../ServerArchitecture/ServerOptions.html"><span class=
"s1">ServerOptions
</span></a> for information on how to set the number of input and output channels, and busses.)
</p>
52 <p class=
"p2"><br></p>
53 <p class=
"p4"><b>Writing to or Reading from Busses
</b></p>
54 <p class=
"p2"><br></p>
55 <p class=
"p3">We've already seen Out.ar, which allows you to write (i.e. play out) audio to a bus. Recall that it has two arguments, an index, and an output, which can be an array of UGens (i.e. a multichannel output) or a single UGen.
</p>
56 <p class=
"p2"><br></p>
57 <p class=
"p3">To read in from a bus you use another UGen: In. In's 'ar' method also takes two arguments: An index, and the number of channels to read in. If the number of channels is greater than one, than In's output will be an Array. Execute the following examples, and watch the post window:
</p>
58 <p class=
"p5"><br></p>
59 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s3">In
</span><span class=
"s2">.ar(
0,
1);
</span>// this will return 'an OutputProxy'
</p>
60 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s3">In
</span><span class=
"s2">.ar(
0,
4);
</span>// this will return an Array of
4 OutputProxies
</p>
61 <p class=
"p2"><br></p>
62 <p class=
"p3">An OutputProxy is a special kind of UGen that acts as a placeholder for some signal that will be present when the synth is running. You'll probably never need to deal with one directly, so don't worry about them, just understand what they are so that you'll recognise them when you see them in the post window and elsewhere.
</p>
63 <p class=
"p2"><br></p>
64 <p class=
"p3">In and Out also have 'kr' methods, which will read and write control rate signals to and from control rate busses. Note that Out.kr will convert an audio rate signal to control rate (this is called 'downsampling'), but that the reverse is not true: Out.ar needs an audio rate signal as its second arg.
</p>
65 <p class=
"p2"><br></p>
66 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// This throws an error. Can't write a control rate signal to an audio rate bus
</p>
67 <p class=
"p7"><span class=
"Apple-tab-span"> </span>{
<span class=
"s3">Out
</span>.ar(
0,
<span class=
"s3">SinOsc
</span>.kr)}.play;
</p>
68 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
69 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// This will work as the audio rate signal is downsampled to control rate
</p>
70 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">Server
</span>.internal.boot;
</p>
71 <p class=
"p7"><span class=
"Apple-tab-span"> </span>{
<span class=
"s3">Out
</span>.kr(
0,
<span class=
"s3">SinOsc
</span>.ar)}.scope;
<span class=
"s2"><span class=
"Apple-tab-span"> </span></span></p>
72 <p class=
"p2"><br></p>
73 <p class=
"p3">(This limitation is not universal amongst audio rate UGens however, and most will accept control rate signals for some or all of their arguments. Some will even convert control rate inputs to audio rate if needed, filling in the extra values through a process called interpolation.)
</p>
74 <p class=
"p2"><br></p>
75 <p class=
"p3">You'll note that when multiple Synths write to the same bus, there output is summed, or in other words, mixed.
</p>
76 <p class=
"p2"><br></p>
77 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
78 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-args"</span>, {
<span class=
"s3">arg
</span> freq =
440, out =
0;
<span class=
"Apple-converted-space"> </span></p>
79 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(out,
<span class=
"s3">SinOsc
</span>.ar(freq,
0,
0.2));
<span class=
"Apple-converted-space"> </span></p>
80 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
81 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
82 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// both write to bus
1, and their output is mixed
</p>
83 <p class=
"p9"><span class=
"s2"><span class=
"Apple-tab-span"> </span>x =
</span><span class=
"s3">Synth
</span><span class=
"s2">(
</span>"tutorial-args"<span class=
"s2">, [
</span>"out"<span class=
"s2">,
1,
</span>"freq"<span class=
"s2">,
660]);
</span></p>
84 <p class=
"p9"><span class=
"s2"><span class=
"Apple-tab-span"> </span>y =
</span><span class=
"s3">Synth
</span><span class=
"s2">(
</span>"tutorial-args"<span class=
"s2">, [
</span>"out"<span class=
"s2">,
1,
</span>"freq"<span class=
"s2">,
770]);
</span></p>
85 <p class=
"p2"><br></p>
86 <p class=
"p4"><b>Creating a Bus Object
</b></p>
87 <p class=
"p2"><br></p>
88 <p class=
"p3">There is a handy client-side object to represent server busses: Bus. Given that all you need is an In or Out Ugen and an index to write to a bus, you might wonder what one would need a full-fledged Bus object for. Well, much of the time you don't, particularly if all you're doing is playing audio in and out. But Bus does provide some useful functionality. We'll get to that in a second, but first lets look at how to make one.
</p>
89 <p class=
"p2"><br></p>
90 <p class=
"p3">Just as many UGens have ar and kr methods, Bus has two commonly used creation methods: Bus-audio and Bus-control. These each take two arguments: a Server object, and the number of channels.
</p>
91 <p class=
"p2"><br></p>
92 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b =
</span><span class=
"s3">Bus
</span><span class=
"s2">.control(s,
2);
</span>// Get a two channel control Bus
</p>
93 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>c =
</span><span class=
"s3">Bus
</span><span class=
"s2">.audio(s);
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// Get a one channel private audio Bus (one is the default)
</p>
94 <p class=
"p2"><br></p>
95 <p class=
"p3">You may be wondering what a 'two channel' bus is, since we haven't mentioned these before. You should recall that when Out has an Array as its second argument it will write the channels of the Array to consecutive busses. Recall this example from
<a href=
"SynthDefs and Synths.html"><span class=
"s1">SynthDefs and Synths
</span></a>:
</p>
96 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
97 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
98 <p class=
"p9"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s3">SynthDef
</span><span class=
"s2">.new(
</span>"tutorial-SinOsc-stereo"<span class=
"s2">, {
</span><span class=
"s3">var
</span><span class=
"s2"> outArray;
</span></p>
99 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>outArray = [
<span class=
"s3">SinOsc
</span>.ar(
440,
0,
0.2),
<span class=
"s3">SinOsc
</span>.ar(
442,
0,
0.2)];
</p>
100 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span><span class=
"s3">Out
</span><span class=
"s2">.ar(
0, outArray);
</span>// writes to busses
0 and
1<span class=
"Apple-converted-space"> </span></p>
101 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).play;
</p>
102 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
103 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
104 <p class=
"p3">The truth is that there aren't multichannel busses per se, but Bus objects are able to represent a series of busses with consecutive indices. The
<i>encapsulate
</i> several adjacent sever-side busses into a single Bus object, allowing you to treat them as a group. This turns out to be rather handy.
</p>
105 <p class=
"p2"><br></p>
106 <p class=
"p3">When you're working with so-called 'private' busses (i.e. anything besides the input and output channels; all control busses are 'private') you generally want to make sure that that bus is only used for exactly what you want. The point after all is to keep things separate. You could do this by carefully considering which indices to use, but Bus allows for this to be done automatically. Each Server object has a bus allocator, and when you make a Bus object, it reserves those private indices, and will not give them out again until freed. You can find out the index of a Bus by using its 'index' method. Normally however, you will not need to store this value, as instances of Bus can be passed directly as UGen inputs or Synth args.
</p>
107 <p class=
"p2"><br></p>
108 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>s.reboot;
</span>// this will restart the server app and thus reset the bus allocators
</p>
109 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
110 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b =
</span><span class=
"s3">Bus
</span><span class=
"s2">.control(s,
2);
<span class=
"Apple-tab-span"> </span></span>// a
2 channel control Bus
</p>
111 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b.index;
<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>// this should be zero
</p>
112 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b.numChannels
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// Bus also has a numChannels method
</p>
113 <p class=
"p7"><span class=
"Apple-tab-span"> </span>c =
<span class=
"s3">Bus
</span>.control(s);
<span class=
"Apple-tab-span"> </span></p>
114 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>c.numChannels;
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// the default number of channels is
1</p>
115 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>c.index;
<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>// note that this is
2; b uses
0 and
1</p>
116 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
117 <p class=
"p3">So by using Bus objects to represent adjacent busses, you can guarantee that there won't be a conflict. Since the indices are allocated dyamically, you can change the number of channels of a Bus in your code (for instance because you now need to route a multichannel signal), and you're still guaranteed to be safe. If you were simply 'hard allocating' busses by using index numbers, you might have to adjust them all to make room for an extra adjacent channel, since the indices need to be consecutive! This is a good example of the power of objects: By encapsulating things like index allocation, and providing a
<i>layer of abstraction
</i>, they can make your code more flexible.
</p>
118 <p class=
"p2"><br></p>
119 <p class=
"p3">You can free up the indices used by a Bus by calling its 'free' method. This allows them to be reallocated.
</p>
120 <p class=
"p2"><br></p>
121 <p class=
"p7"><span class=
"Apple-tab-span"> </span>b =
<span class=
"s3">Bus
</span>.control(s,
2);
</p>
122 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b.free;
</span>// free the indices. You can't use this Bus object after that
<span class=
"Apple-converted-space"> </span></p>
123 <p class=
"p5"><span class=
"Apple-tab-span"> </span></p>
124 <p class=
"p3">Note that this doesn't actually make the bus on the server go away, it's still there. 'free' just lets the allocator know that you're done using this bus for the moment, and it can freely reallocate its index.
</p>
125 <p class=
"p2"><br></p>
126 <p class=
"p3">Now here's another advantage when working with private audio rate busses. As we said above, the first few busses are the output and input channels. So if we want to use the first private bus, all we need to do is add those together, right? Consider our server app with
2 output and
2 input channels. The first private audio bus is index
4. (
0,
1,
2,
3 ...
4!) So we write our code, and give the appropriate Out UGen
4 as its index arg.
<span class=
"Apple-converted-space"> </span></p>
127 <p class=
"p2"><br></p>
128 <p class=
"p3">But what happens if we later decide to change the number of output channels to
6? Now everything that was written to our private bus is going out one of the output channels! A Server's audio bus allocator will only assign private indices, so if you change the number of input or output channels it will take this into account when you execute your code. Again this makes your code more flexible.
</p>
129 <p class=
"p2"><br></p>
130 <p class=
"p4"><b>Busses in Action
</b></p>
131 <p class=
"p2"><br></p>
132 <p class=
"p3">So here are two examples using busses. The first is with a control rate bus.
</p>
133 <p class=
"p2"><br></p>
134 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
135 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-Infreq"</span>, {
<span class=
"s3">arg
</span> bus, freqOffset =
0;
</p>
136 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// this will add freqOffset to whatever is read in from the bus
</p>
137 <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">SinOsc
</span>.ar(
<span class=
"s3">In
</span>.kr(bus) + freqOffset,
0,
0.5));
</p>
138 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
139 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
140 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-Outfreq"</span>, {
<span class=
"s3">arg
</span> freq =
400, bus;
</p>
141 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.kr(bus,
<span class=
"s3">SinOsc
</span>.kr(
1,
0, freq/
40, freq));
</p>
142 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
143 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
144 <p class=
"p7"><span class=
"Apple-tab-span"> </span>b =
<span class=
"s3">Bus
</span>.control(s,
1);
</p>
145 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
146 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
147 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
148 <p class=
"p7"><span class=
"Apple-tab-span"> </span>x =
<span class=
"s3">Synth
</span>.new(
<span class=
"s4">"tutorial-Outfreq"</span>, [
<span class=
"s5">\bus
</span>, b]);
</p>
149 <p class=
"p7"><span class=
"Apple-tab-span"> </span>y =
<span class=
"s3">Synth
</span>.after(x,
<span class=
"s4">"tutorial-Infreq"</span>, [
<span class=
"s5">\bus
</span>, b]);
</p>
150 <p class=
"p7"><span class=
"Apple-tab-span"> </span>z =
<span class=
"s3">Synth
</span>.after(x,
<span class=
"s4">"tutorial-Infreq"</span>, [
<span class=
"s5">\bus
</span>, b,
<span class=
"s5">\freqOffset
</span>,
200]);
</p>
151 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
152 <p class=
"p7"><span class=
"Apple-tab-span"> </span>x.free; y.free; z.free; b.free;
</p>
153 <p class=
"p2"><br></p>
154 <p class=
"p3">Both y and z read from the same bus, the latter just modifies the frequency control signal by adding a constant value of
200 to it. This is more efficient than having two separate control oscillators to control frequency. This sort of strategy of connecting together synths, each of which does different things in a larger process, can be very effective in SC.
</p>
155 <p class=
"p2"><br></p>
156 <p class=
"p3">Now an example with an audio bus. This is the most complicated example we've seen so far, but should give you some idea of how to start putting all the things we've learned together. The code below will use two Synths as sources, one creating pulses of PinkNoise (a kind of Noise which has less energy at high frequencies than at low), and another creating pulses of Sine Waves. The pulses are created using the UGens
<a href=
"../../UGens/Oscillators/Impulse.html"><span class=
"s1">Impulse
</span></a><b> </b>and
<a href=
"../../UGens/Synth control/Envelopes/Decay2.html"><span class=
"s6">Decay2
</span></a>. These are then reverberated using a chain of
<a href=
"../../UGens/Delays/AllpassC.html"><span class=
"s1">AllpassC
</span></a>, which is a kind of delay.
</p>
157 <p class=
"p2"><br></p>
158 <p class=
"p3">Note the construction
16.do({ ... }), below. This makes the chain by evaluating the function
16 times. This is a very powerful and flexible technique, as by simply changing the number, I can change the number of evaluations. See
<a href=
"../../Math/Integer.html"><span class=
"s1">Integer
</span></a><b> </b>for more info on Integer-do.
</p>
159 <p class=
"p2"><br></p>
160 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
161 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// the arg direct will control the proportion of direct to processed signal
</p>
162 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-DecayPink"</span>, {
<span class=
"s3">arg
</span> outBus =
0, effectBus, direct =
0.5;
</p>
163 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span> source;
</p>
164 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// Decaying pulses of PinkNoise. We'll add reverb later.
</p>
165 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>source =
<span class=
"s3">Decay2
</span>.ar(
<span class=
"s3">Impulse
</span>.ar(
1,
0.25),
0.01,
0.2,
<span class=
"s3">PinkNoise
</span>.ar);
</p>
166 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// this will be our main output
</p>
167 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(outBus, source * direct);
</p>
168 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// this will be our effects output
</p>
169 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(effectBus, source * (
1 - direct));
</p>
170 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
171 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
172 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-DecaySin"</span>, {
<span class=
"s3">arg
</span> outBus =
0, effectBus, direct =
0.5;
</p>
173 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span> source;
</p>
174 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// Decaying pulses of a modulating Sine wave. We'll add reverb later.
</p>
175 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>source =
<span class=
"s3">Decay2
</span>.ar(
<span class=
"s3">Impulse
</span>.ar(
0.3,
0.25),
0.3,
1,
<span class=
"s3">SinOsc
</span>.ar(
<span class=
"s3">SinOsc
</span>.kr(
0.2,
0,
110,
440)));
</p>
176 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// this will be our main output
</p>
177 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(outBus, source * direct);
</p>
178 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// this will be our effects output
</p>
179 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(effectBus, source * (
1 - direct));
</p>
180 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
181 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
182 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-Reverb"</span>, {
<span class=
"s3">arg
</span> outBus =
0, inBus;
</p>
183 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">var
</span> input;
</p>
184 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>input =
<span class=
"s3">In
</span>.ar(inBus,
1);
</p>
185 <p class=
"p8"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
186 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// a low rent reverb
</p>
187 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// aNumber.do will evaluate it's function argument a corresponding number of times
</p>
188 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// {}.dup(n) will evaluate the function n times, and return an Array of the results
</p>
189 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// The default for n is
2, so this makes a stereo reverb
</p>
190 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>16.do({ input =
<span class=
"s3">AllpassC
</span>.ar(input,
0.04, {
<span class=
"s3">Rand
</span>(
0.001,
0.04) }.dup,
3)});
</p>
191 <p class=
"p8"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></p>
192 <p class=
"p7"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(outBus, input);
</p>
193 <p class=
"p7"><span class=
"Apple-tab-span"> </span>}).send(s);
</p>
194 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
195 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>b =
</span><span class=
"s3">Bus
</span><span class=
"s2">.audio(s,
1);
</span>// this will be our effects bus
</p>
196 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
197 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
198 <p class=
"p7"><span class=
"Apple-tab-span"> </span>(
</p>
199 <p class=
"p7"><span class=
"Apple-tab-span"> </span>x =
<span class=
"s3">Synth
</span>.new(
<span class=
"s4">"tutorial-Reverb"</span>, [
<span class=
"s5">\inBus
</span>, b]);
</p>
200 <p class=
"p7"><span class=
"Apple-tab-span"> </span>y =
<span class=
"s3">Synth
</span>.before(x,
<span class=
"s4">"tutorial-DecayPink"</span>, [
<span class=
"s5">\effectBus
</span>, b]);
</p>
201 <p class=
"p7"><span class=
"Apple-tab-span"> </span>z =
<span class=
"s3">Synth
</span>.before(x,
<span class=
"s4">"tutorial-DecaySin"</span>, [
<span class=
"s5">\effectBus
</span>, b,
<span class=
"s5">\outBus
</span>,
1]);
</p>
202 <p class=
"p7"><span class=
"Apple-tab-span"> </span>)
</p>
203 <p class=
"p8"><span class=
"Apple-tab-span"> </span></p>
204 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// Change the balance of wet to dry
</p>
205 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>y.set(
</span><span class=
"s5">\direct
</span><span class=
"s2">,
1);
</span>// only direct PinkNoise
</p>
206 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>z.set(
</span><span class=
"s5">\direct
</span><span class=
"s2">,
1);
</span>// only direct Sine wave
</p>
207 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>y.set(
</span><span class=
"s5">\direct
</span><span class=
"s2">,
0);
</span>// only reverberated PinkNoise
</p>
208 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span>z.set(
</span><span class=
"s5">\direct
</span><span class=
"s2">,
0);
</span>// only reverberated Sine wave
</p>
209 <p class=
"p7"><span class=
"Apple-tab-span"> </span>x.free; y.free; z.free; b.free;
</p>
210 <p class=
"p10"><br></p>
211 <p class=
"p3">Note that we could easily have many more source synths being processed by the single reverb synth. If we'd built the reverb into the source synths we'd be duplicating effort. But by using a private bus, we're able to be more efficient.
</p>
212 <p class=
"p10"><br></p>
213 <p class=
"p4"><b>More Fun with Control Busses
</b></p>
214 <p class=
"p2"><br></p>
215 <p class=
"p3">There are some other powerful things that you can do with control rate busses. For instance, you can map any arg in a running synth to read from a control bus. This means you don't need an In UGen. You can also write constant values to control busses using Bus' 'set' method, and poll values using its 'get' method.
<span class=
"Apple-converted-space"> </span></p>
216 <p class=
"p11"><br></p>
217 <p class=
"p12"><span class=
"Apple-tab-span"> </span>(
</p>
218 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// make two control rate busses and set their values to
880 and
884.
<span class=
"Apple-converted-space"> </span></p>
219 <p class=
"p12"><span class=
"Apple-tab-span"> </span>b =
<span class=
"s3">Bus
</span>.control(s,
1); b.set(
880);
</p>
220 <p class=
"p12"><span class=
"Apple-tab-span"> </span>c =
<span class=
"s3">Bus
</span>.control(s,
1);
<span class=
"Apple-tab-span"> </span>c.set(
884);
</p>
221 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// and make a synth with two frequency arguments
</p>
222 <p class=
"p12"><span class=
"Apple-tab-span"> </span>x =
<span class=
"s3">SynthDef
</span>(
<span class=
"s4">"tutorial-map"</span>, {
<span class=
"s3">arg
</span> freq1 =
440, freq2 =
440;
<span class=
"Apple-converted-space"> </span></p>
223 <p class=
"p12"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s3">Out
</span>.ar(
0,
<span class=
"s3">SinOsc
</span>.ar([freq1, freq2],
0,
0.1));
</p>
224 <p class=
"p12"><span class=
"Apple-tab-span"> </span>}).play(s);
</p>
225 <p class=
"p12"><span class=
"Apple-tab-span"> </span>)
</p>
226 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// Now map freq1 and freq2 to read from the two busses
</p>
227 <p class=
"p12"><span class=
"Apple-tab-span"> </span>x.map(
<span class=
"s5">\freq1
</span>, b,
<span class=
"s5">\freq2
</span>, c);
</p>
228 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
229 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// Now make a Synth to write to the one of the busses
</p>
230 <p class=
"p12"><span class=
"Apple-tab-span"> </span>y = {
<span class=
"s3">Out
</span>.kr(b,
<span class=
"s3">SinOsc
</span>.kr(
1,
0,
50,
880))}.play(addAction:
<span class=
"s5">\addToHead
</span>);
</p>
231 <p class=
"p14"><br></p>
232 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// free y, and b holds its last value
</p>
233 <p class=
"p12"><span class=
"Apple-tab-span"> </span>y.free;
</p>
234 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
235 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// use Bus-get to see what the value is. Watch the post window
</p>
236 <p class=
"p12"><span class=
"Apple-tab-span"> </span>b.get({
<span class=
"s3">arg
</span> val; val.postln; f = val; });
</p>
237 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
238 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// set the freq2, this 'unmaps' it from c
</p>
239 <p class=
"p12"><span class=
"Apple-tab-span"> </span>x.set(
<span class=
"s5">\freq2
</span>, f /
2);
</p>
240 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
241 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// freq2 is no longer mapped, so setting c to a different value has no effect
</p>
242 <p class=
"p12"><span class=
"Apple-tab-span"> </span>c.set(
200);
</p>
243 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
244 <p class=
"p12"><span class=
"Apple-tab-span"> </span>x.free; b.free; c.free;
</p>
245 <p class=
"p2"><br></p>
246 <p class=
"p3">Note that unlike audio rate busses, control rate busses hold their last value until something new is written.
<span class=
"Apple-converted-space"> </span></p>
247 <p class=
"p2"><br></p>
248 <p class=
"p3">Also note that Bus-get takes a Function (called an action function) as an argument. This is because it takes a small amount of time for the server to get the reply and send it back. The function, which is passed the value (or Array of values in the case of a multichannel bus) as an argument, allows you to do something with the value once its come back.
</p>
249 <p class=
"p2"><br></p>
250 <p class=
"p3">This concept of things taking a small amount of time to respond (usually called
<i>latency
</i>) is quite important to understand. There are a number of other methods in SC which function this way, and it can cause you problems if you're not careful. To illustrate this consider the example below.
</p>
251 <p class=
"p2"><br></p>
252 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// make a Bus object and set its values
<span class=
"Apple-converted-space"> </span></p>
253 <p class=
"p12"><span class=
"Apple-tab-span"> </span>b =
<span class=
"s3">Bus
</span>.control(s,
1); b.set(
880);
</p>
254 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
255 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// execute this altogether
</p>
256 <p class=
"p12"><span class=
"Apple-tab-span"> </span>(
</p>
257 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span>f =
</span><span class=
"s3">nil
</span><span class=
"s2">;
</span>// just to be sure
</p>
258 <p class=
"p12"><span class=
"Apple-tab-span"> </span>b.get({
<span class=
"s3">arg
</span> val; f = val; });
</p>
259 <p class=
"p12"><span class=
"Apple-tab-span"> </span>f.postln;
</p>
260 <p class=
"p12"><span class=
"Apple-tab-span"> </span>)
</p>
261 <p class=
"p14"><span class=
"Apple-tab-span"> </span></p>
262 <p class=
"p13"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// f equals nil, but try it again and it's as we expected!
</p>
263 <p class=
"p12"><span class=
"Apple-tab-span"> </span>f.postln;
</p>
264 <p class=
"p2"><br></p>
265 <p class=
"p3">So why was f nil the first time but not the second time? The part of the language app which executes your code (called the
<i>interpreter
</i>), does what you tell it, as fast as it can, when you tell it to. So in the block of code between the parentheses above it sends the 'get' message to the server, schedules the Function to execute when a reply is received, and then moves on to posting f. Since it hasn't received the reply yet f is still nil when it's posted the first time.
</p>
266 <p class=
"p2"><br></p>
267 <p class=
"p3">It only takes a tiny amount of time for the server to send a reply, so by the time we get around to executing the last line of code f has been set to
880, as we expected. In the previous example this wasn't a problem, as we were only executing a line at a time. But there will be cases where you will need to execute things as a block, and the action function technique is very useful for that.
</p>
268 <p class=
"p2"><br></p>
269 <p class=
"p4"><b>Getting it all in the Right Order
</b></p>
270 <p class=
"p2"><br></p>
271 <p class=
"p3">In the examples above, you may have wondered about things like Synth.after, and addAction: \addToHead. During each cycle (the period in which a block of samples is calculated) the server calculates things in a particular order, according to its list of running synths.
</p>
272 <p class=
"p2"><br></p>
273 <p class=
"p3">It starts with the first synth in its list, and calculates a block of samples for its first UGen. It then takes that and calculates a block of samples for each of its remaining UGens in turn (any of which may take the output of an earlier UGen as an input.) This synth's output is written to a bus or busses, as the case may be. The server then moves on to the next synth in its list, and the process repeats, until all running synths have calculated a block of samples. At this point the server can move on to the next cycle.
</p>
274 <p class=
"p2"><br></p>
275 <p class=
"p3">The important thing to understand is that
<i>as a general rule
</i>, when you are connecting synths together using busses it is important that synths which write signals to busses are earlier in the server's order than synths which read those signals from those busses. For instance in the audio bus example above it was important that the 'reverb' synth is calculated
<i>after
</i> the noise and sine wave synths that it processes.
</p>
276 <p class=
"p2"><br></p>
277 <p class=
"p3">This is a complicated topic, and there are some exceptions to this, but you should be aware that ordering is crucial when interconnecting synths. The file
<a href=
"../../ServerArchitecture/Order-of-execution.html"><span class=
"s1">Order-of-execution
</span></a><b> </b>covers this topic in greater detail.
</p>
278 <p class=
"p2"><br></p>
279 <p class=
"p3">Synth-new has two arguments which allow you to specify where in the order a synth is added. The first is a
<i>target
</i>, and the second is an
<i>addAction
</i>. The latter specifies the new synth's position in relation to the target.
</p>
280 <p class=
"p2"><br></p>
281 <p class=
"p7"><span class=
"s7"><span class=
"Apple-tab-span"> </span></span>x =
<span class=
"s3">Synth
</span>(
<span class=
"s4">"default"</span>, [
<span class=
"s5">\freq
</span>,
300]);
</p>
282 <p class=
"p6"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>// add a second synth immediately after x
</p>
283 <p class=
"p7"><span class=
"Apple-tab-span"> </span>y =
<span class=
"s3">Synth
</span>(
<span class=
"s4">"default"</span>, [
<span class=
"s5">\freq
</span>,
450], x,
<span class=
"s5">\addAfter
</span>);
</p>
284 <p class=
"p7"><span class=
"Apple-tab-span"> </span>x.free; y.free;
</p>
285 <p class=
"p2"><br></p>
286 <p class=
"p3">A target can be another Synth (or some other things; more on that soon), and an addAction is a symbol. See
<a href=
"../../ServerArchitecture/Synth.html"><span class=
"s1">Synth
</span></a> for a complete list of possible addActions.
</p>
287 <p class=
"p2"><br></p>
288 <p class=
"p3">Methods like Synth-after are simply convenient ways of doing the same thing, the difference being that they take a target as their first argument.
</p>
289 <p class=
"p2"><br></p>
290 <p class=
"p6"><span class=
"s8"><span class=
"Apple-tab-span"> </span></span>// These two lines of code are equivalent
</p>
291 <p class=
"p7"><span class=
"Apple-tab-span"> </span>y =
<span class=
"s3">Synth
</span>.new(
<span class=
"s4">"default"</span>, [
<span class=
"s5">\freq
</span>,
450], x,
<span class=
"s5">\addAfter
</span>);
</p>
292 <p class=
"p7"><span class=
"s7"><span class=
"Apple-tab-span"> </span></span>y =
<span class=
"s3">Synth
</span>.after(x,
<span class=
"s4">"default"</span>, [
<span class=
"s5">\freq
</span>,
450]);
</p>
293 <p class=
"p2"><br></p>
294 <p class=
"p3">For more information see:
<b><span class=
"Apple-converted-space"> </span></b></p>
295 <p class=
"p2"><br></p>
296 <p class=
"p15"><span class=
"s9"><a href=
"../../ServerArchitecture/Bus.html">Bus
</a></span><span class=
"s2"><b> </b><a href=
"../../UGens/InOut/In.html"><span class=
"s10">In
</span></a><b> </b><a href=
"../../UGens/Multichannel/OutputProxy.html"><span class=
"s10">OutputProxy
</span></a><b> </b><a href=
"../../ServerArchitecture/Order-of-execution.html"><span class=
"s10">Order-of-execution
</span></a><b> </b><a href=
"../../ServerArchitecture/Synth.html"><span class=
"s10">Synth
</span></a></span></p>
297 <p class=
"p2"><br></p>
298 <p class=
"p4"><b>Suggested Exercise:
</b></p>
299 <p class=
"p10"><br></p>
300 <p class=
"p3">Experiment with interconnecting different synths using audio and control busses. When doing so be mindful of their ordering on the server.
</p>
301 <p class=
"p2"><br></p>
302 <p class=
"p3">____________________
</p>
303 <p class=
"p2"><br></p>
304 <p class=
"p3">This document is part of the tutorial
<b>Getting Started With SuperCollider
</b>.
</p>
305 <p class=
"p2"><br></p>
306 <p class=
"p3">Click here to go on to the next section:
<a href=
"Groups.html"><span class=
"s1">Groups
</span></a></p>
307 <p class=
"p2"><br></p>
308 <p class=
"p3">Click here to return to the table of Contents:
<a href=
"Getting Started With SC.html"><span class=
"s1">Getting Started With SC
</span></a></p>