class library: SynthDef - lazy implementation of removeUGen
[supercollider.git] / HelpSource / Classes / Synth.schelp
blob20fa4af1af40a7912c89b3bdb0b7c3438e01779a
1 class:: Synth
2 summary:: Client-side representation of a synth node on the server
3 categories:: Server>Nodes, Server>Abstractions
4 related:: Classes/Node, Classes/SynthDef
6 description::
8 A Synth is the client-side representation of a synth node on the server. A Synth represents a single sound producing unit.  What it does is defined in a link::Classes/SynthDef::, which specifies what link::Classes/UGen::s are used and how they are patched together.
9 It also specifies what inputs and outputs the Synth will have. A SynthDef is thus a kind of fixed pattern, upon which Synths are be based. (Despite this, a given SynthDef can provide a surprising amount of variation.) For more detail on SynthDefs, their construction, and how to send them to a server, see the link::Classes/SynthDef:: help file.
11 For more on the important distinction between client objects and server nodes, see link::Guides/ClientVsServer::. For information on creating nodes without using objects, see link::Guides/NodeMessaging::.
13 subsection:: Order of Execution
14 Order of execution is a crucial issue when creating Synths which interact with each other.
15 code::
16         sound ->  filter
18 If a sound is to be passed through a filter, the synth that does the filtering must be later in the order of execution than the synth which is its input.  The computer must calculate a buffer's worth of sound, and then the computer moves on to calculate a buffer's worth of the filtered version of that sound.
20 The actual interconnection between synth nodes is accomplished with buses. See link::Classes/Bus:: and link::Reference/Server-Architecture:: for details.
22 See the link::Guides/Order-of-execution:: help file for a more detailed discussion of this important topic.
24 subsection:: Bundling
26 Some of the methods below have two versions: a regular one which sends its corresponding message to the server immediately, and one which returns the message in an link::Classes/Array:: so that it can be added to a bundle.
27 It is also possible to capture the messages generated by the regular methods using Server's automated bundling capabilities. See link::Classes/Server:: and link::Guides/Bundled-Messages:: for more details.
29 classmethods::
30 private:: stop, play, sampleRate
32 Synth is a subclass of Node, and thus many of its most useful and important methods are documented in the link::Classes/Node:: help file.
34 subsection:: Creation with Immediate Instantiation on the Server
35 method:: new
36 Create and return a new Synth object, and immediately start the corresponding synth node on the server.
38 argument:: defName
39 A String or Symbol specifying the name of the SynthDef to use in creating the Synth.
41 argument:: args
42 An optional link::Classes/Array:: specifying initial values for the link::Classes/SynthDef::'s arguments (controls). These are specified in pairs of control name or index and value. If names are used they can be specified with either link::Classes/String::s or link::Classes/Symbol::s. e.g. code:: [\frequency, 440, \amplitude, 1, ...] ::.
43 Values that are arrays are sent using OSC array type-tags ($[ and $]).  These values will be assigned to subsequent controls.
45 argument:: target
46 A target for this Synth. If target is not a link::Classes/Group:: or Synth, it will be converted as follows: If it is a link::Classes/Server::, it will be converted to the link::Reference/default_group:: of that server. If it is nil, to the default_group of the default Server. If it is an integer, it is created relative to a group with that id.
48 argument:: addAction
49 one of the following Symbols:
50 definitionlist::
51 ## \addToHead || (the default) add at the head of the group specified by target
52 ## \addToTail || add at the tail of the group specified by target
53 ## \addAfter || add immediately after target in its server's node order
54 ## \addBefore || add immediately before target in its server's node order
55 ## \addReplace || replace target and take its place in its server's node order
57 Note: A Synth is not a valid target for \addToHead and \addToTail.
59 discussion::
60 code::
61 s.boot;
62 // create a Synth at the head of the default Server's default group
63 // based on the SynthDef "default"
64 x = Synth.new("default");
65 s.queryAllNodes; // note the default group (ID 1)
66 x.free;
68 // Using an arrayed control
69 // run this block first to make the SynthDef
71 SynthDef("help-synth", {| freq = #[440, 450, 460], out = 0 |
72         Out.ar(out, Mix(SinOsc.ar(freq, 0, 0.1)));
73 }).add;
76 // then this a short while later
77 x = Synth("help-synth", [freq: [500,501,510] ]);
79 x = Synth("help-synth", [freq: [500,501,510] ]);
80 x.set(\freq, [1,2,3] * 400 + [1,2,3], \out, 1);
81 x.set(\freq, [3] * 400 + [1,2,3], \out, 1);
82 x.free;
85 method:: newPaused
86 As code::new:: above, but creates a node which is paused. This can be started by calling code::run:: on it.
87 code::
88 s.boot;
89 x = Synth.newPaused("default");
90 s.queryAllNodes; // see I'm here
91 x.run; // true is the default
92 x.run(false); // pause me again
93 x.free;
96 method:: grain
97 A convenience method which will create a synth node with an node ID of -1. Such a node cannot be messaged after creation. As such this method does not create an object, and returns nil. For details of its arguments see code::new:: above.
98 returns:: nil
100 subsection:: Convenience methods for add actions
101 The following convenience methods correspond to the add actions of code::Synth.new:: :
103 method:: after
104 Create and return a Synth and add it immediately after aNode.
106 method:: before
107 Create and return a Synth and add it immediately before aNode.
109 method:: head
110 Create and return a Synth. If code::aGroup:: is a link::Classes/Group:: add it at the head of that group. If it is a link::Classes/Server::, add it at the head of the link::Reference/default_group:: of that server. If it is nil, add it at the head of the default_group of the default server. If it is an integer, it is created relative to a group with that id.
112 method:: tail
113 Create and return a Synth. If code::aGroup:: is a link::Classes/Group:: add it at the tail of that group. If it is a link::Classes/Server::, add it at the tail of the link::Reference/default_group:: of that server. If it is nil, add it at the tail of the default_group of the the default server. If it is an integer, it is created relative to a group with that id.
115 method:: replace
116 Create and return a Synth and use it to replace code::nodeToReplace::, taking its place in its server's node order.
118 subsection:: Creation without Instantiation on the Server
120 For use in message bundles it is also possible to create a Synth object in the client app without immediately creating a synth node on the server. Once done one can call methods which create messages to add to a bundle, which when sent to the server will instantiate the synth.
122 method:: basicNew
123 Create and return a Synth object without creating a synth node on the server.
124 argument:: defName
125 A String or Symbol specifying the name of the SynthDef to use in creating the Synth.
126 argument:: server
127 An optional instance of Server. If nil this will default to the default Server.
128 argument:: nodeID
129 An optional node ID number. If not supplied one will be generated by the Server's NodeIDAllocator. Normally you should not need to supply an ID.
130 discussion::
131 code::
132 s.boot;
133 x = Synth.basicNew("default", s); // Create without sending
134 s.sendBundle(nil, x.newMsg;); // Now send a message; create at the head of s' default group
135 s.queryAllNodes;
136 x.free;
139 After creation, use instance methods code::newMsg, addToHeadMsg, addToTailMsg, addBeforeMsg, addAfterMsg, addReplaceMsg:: to instantiate this synth on the server. See link::#instancemethods#Instance Methods:: below.
143 instancemethods::
144 private:: prepareForProxySynthDef, play
146 Synth is a subclass of Node, and thus many of its most useful and important methods are documented in the link::Classes/Node:: help file.
148 method:: defName
149 Returns:: the name of this Synth's SynthDef.
151 subsection:: Creation without Instantiation on the Server
152 Use class method code::basicNew:: to create a Synth without instantiating it on the server. Then use the following instance methods:
153 method:: newMsg
154 See *new above for details of addActions and args.
155 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth. If target is nil, it will default to the default_group of the Server specified in *basicNew when this Synth was created. The default addAction is \addToHead.
157 method:: addToHeadMsg
158 See *new above for details on args.
159 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth. If aGroup is a Group it will be added at the head of that group. If it is nil, it will be added at the head of the default_group of this Synth's server (as specified when *basicNew was called).
161 method:: addToTailMsg
162 See *new above for details on args.
163 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth. If aGroup is a Group it will be added at the tail of that group. If it is nil, it will be added at the tail of the default_group of this Synth's server (as specified when *basicNew was called).
165 method:: addBeforeMsg
166 See *new above for details on args.
167 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth, immediately before aNode.
169 method:: addAfterMsg
170 See *new above for details on args.
171 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth, immediately after aNode.
173 method:: addReplaceMsg
174 See *new above for details on args.
175 Returns:: a message of the type s_new which can be bundled. When sent to the server this message will instantiate this synth, replacing nodeToReplace in the server's node order.
177 subsection:: Control
178 For further methods of controlling Synths (set, map, etc.), see the link::Classes/Node:: helpfile.
180 method:: get, getMsg
181 Query the server for the current value of a link::Classes/Control:: (argument).
182 argument:: index
183 a control name or index
184 argument:: action
185 a Function which will be evaluated with the value passed as an argument when the reply is received.
186 discussion::
187 code::
188 s.boot;
190 SynthDef("help-Synth-get", { arg freq = 440;
191         Out.ar(0, SinOsc.ar(freq, 0, 0.1));
192 }).add;
194 x = Synth("help-Synth-get");
195 x.set(\freq, 220 + 440.rand);
196 x.get(\freq, { arg value; ("freq is now:" + value + "Hz").postln; });
197 x.free;
200 method:: getn, getnMsg
201 Query the server for the current values of a sequential range of link::Classes/Control::s (arguments).
202 argument:: index
203 a control name or index
204 argument:: count
205 the number of sequential controls to query, starting at index.
206 argument:: action
207 a Function which will be evaluated with an link::Classes/Array:: containing the values passed as an argument when the reply is received.
209 method:: set
210 Set the values of one or more link::Classes/Control::s.
211 discussion::
212 Example:
213 code::
214 x.set(\freq, 440, \amp, 0.5)
217 Examples::
218 code::
219 // boot the default server
220 s = Server.default; // just to be sure
221 s.boot;
225 // send a synth def to server
226 SynthDef("tpulse", { arg out = 0,freq = 700, sawFreq = 440.0;
227         Out.ar(out, SyncSaw.ar(freq, sawFreq, 0.1));
228 }).add;
231 // Here the defaults for *new will result in a Synth at the head of the default group
232 // of the default Server. This will use the SynthDef's default arguments;
233 y = Synth.new("tpulse");
234 y.free;
236 // The same done explicitly
237 y = Synth.new("tpulse", nil, s, \addToHead);
238 y.free;
240 // With some arguments
241 y = Synth.new("tpulse", [\freq, 350, \sawFreq, 220]);
242 y.free;
244 // make a new synth
245 y = Synth("tpulse");
247 // pause
248 y.run(false);
250 y.run(true);
252 // set a control by argument name
253 y.set("freq", 200);
255 // or by index
256 y.set(2, 100.0);
258 // modulate out to bus number 1 (the right speaker)
259 y.set(0, 1);
261 //  multiple set commands in one message
262 y.set("out", 0, "freq",300);
264 // free the synth from the server
265 y.free;
268 subsection:: Filtering
269 code::
271 // first collect some things to play with
272 SynthDef("moto-rev", { arg out=0;
273         var x;
274         x = RLPF.ar(LFPulse.ar(SinOsc.kr(0.2, 0, 10, 21), [0,0.1], 0.1),
275                 100, 0.1).clip2(0.4);
276         Out.ar(out, x);
277 }).add;
279 SynthDef("bubbles", { arg out=0;
280         var f, zout;
281         f = LFSaw.kr(0.4, 0, 24, LFSaw.kr([8,7.23], 0, 3, 80)).midicps;
282         zout = CombN.ar(SinOsc.ar(f, 0, 0.04), 0.2, 0.2, 4); // echoing sine wave
283         Out.ar(out, zout);
284 }).add;
287 SynthDef("rlpf",{ arg out=0,ffreq=600,rq=0.1;
288         ReplaceOut.ar( out, RLPF.ar( In.ar(out), ffreq,rq) )
289 }).add;
292 SynthDef("wah", { arg out, rate = 1.5, cfreq = 1400, mfreq = 1200, rq=0.1;
293         var zin, zout;
295         zin = In.ar(out, 2);
296         cfreq = Lag3.kr(cfreq, 0.1);
297         mfreq = Lag3.kr(mfreq, 0.1);
298         rq   = Ramp.kr(rq, 0.1);
299         zout = RLPF.ar(zin, LFNoise1.kr(rate, mfreq, cfreq), rq, 10).distort
300                                         * 0.15;
302         // replace the incoming bus with the effected version
303         ReplaceOut.ar( out , zout );
305 }).add;
307 SynthDef("modulate",{ arg out = 0, freq = 1, center = 440, plusMinus = 110;
308         Out.kr(out, SinOsc.kr(freq, 0, plusMinus, center));
309 }).add;
312 // execute these one at a time
314 // y is playing on bus 0
315 y = Synth("moto-rev",["out",0]);
317 // z is reading from bus 0 and replacing that; It must be *after* y
318 z = Synth.after(y,"wah",["out",0]);
320 // stop the wah-ing
321 z.run(false);
323 // resume the wah-ing
324 z.run(true);
326 // add a rlpf after that, reading and writing to the same buss
327 x = Synth.after(z,"rlpf",["out",0]);
329 // create another rlpf after x
330 t = Synth.after(x,"rlpf",["out",0]);
332 x.set("ffreq", 400);
334 x.set(\ffreq, 800); // Symbols work for control names too
336 // Now let's modulate x's ffreq arg
337 // First get a control Bus
338 b = Bus.control(s, 1);
340 // now the modulator, *before* x
341 m = Synth.before(x, "modulate", [\out, b]);
343 // now map x's ffreq to b
344 x.map("ffreq", b);
346 m.set("freq", 4, "plusMinus", 20);
348 x.free;
349 z.free;
350 m.free;
352 // now place another synth after y, on the same bus
353 // they both write to the buss, adding their outputs
354 r = Synth.after(y,"bubbles",["out",0]);
356 y.free;
358 r.free;
360 // look at the Server window
361 // still see 4 Ugens and 1 synth?
362 // you can't hear me, but don't forget to free me
363 t.free;