2 summary:: Client-side representation of a synth node on the server
3 categories:: Server>Nodes, Server>Abstractions
4 related:: Classes/Node, Classes/SynthDef
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.
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.
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.
30 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.
32 private:: stop, play, sampleRate
34 subsection:: Creation with Immediate Instantiation on the Server
36 Create and return a new Synth object, and immediately start the corresponding synth node on the server.
39 A String or Symbol specifying the name of the SynthDef to use in creating the Synth.
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.
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.
49 one of the following Symbols:
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.
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)
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)));
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);
86 As code::new:: above, but creates a node which is paused. This can be started by calling code::run:: on it.
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
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.
100 subsection:: Convenience methods for add actions
101 The following convenience methods correspond to the add actions of code::Synth.new:: :
104 Create and return a Synth and add it immediately after aNode.
107 Create and return a Synth and add it immediately before aNode.
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.
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.
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.
123 Create and return a Synth object without creating a synth node on the server.
125 A String or Symbol specifying the name of the SynthDef to use in creating the Synth.
127 An optional instance of Server. If nil this will default to the default Server.
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.
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
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.
144 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.
146 private:: prepareForProxySynthDef, play
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:
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.
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.
178 For further methods of controlling Synths (set, map, etc.), see the link::Classes/Node:: helpfile.
181 Query the server for the current value of a link::Classes/Control:: (argument).
183 a control name or index
185 a Function which will be evaluated with the value passed as an argument when the reply is received.
190 SynthDef("help-Synth-get", { arg freq = 440;
191 Out.ar(0, SinOsc.ar(freq, 0, 0.1));
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; });
200 method:: getn, getnMsg
201 Query the server for the current values of a sequential range of link::Classes/Control::s (arguments).
203 a control name or index
205 the number of sequential controls to query, starting at index.
207 a Function which will be evaluated with an link::Classes/Array:: containing the values passed as an argument when the reply is received.
210 Set the values of one or more link::Classes/Control::s.
214 x.set(\freq, 440, \amp, 0.5)
218 Set part of an arrayed control.
220 A sequence of strong:: name, index, value :: triplets.
223 ## name || The name of the arrayed control
224 ## index || The index into the array
225 ## value || The new value to set, can be an array to set a range of elements.
230 The synthdef has to be .add'ed, so that it is stored in the link::Classes/SynthDescLib::.
236 SynthDef(\helpSeti, { |freqs = #[100,150,200,250]|
237 Out.ar(0, SinOsc.ar(freqs.poll,0,0.1).sum ! 2)
240 x = Synth(\helpSeti);
243 x.seti(\freqs,2,600); // set only the third element
244 x.seti(\freqs,1,[400,410]); // set second and third element
250 // boot the default server
251 s = Server.default; // just to be sure
256 // send a synth def to server
257 SynthDef("tpulse", { arg out = 0,freq = 700, sawFreq = 440.0;
258 Out.ar(out, SyncSaw.ar(freq, sawFreq, 0.1));
262 // Here the defaults for *new will result in a Synth at the head of the default group
263 // of the default Server. This will use the SynthDef's default arguments;
264 y = Synth.new("tpulse");
267 // The same done explicitly
268 y = Synth.new("tpulse", nil, s, \addToHead);
271 // With some arguments
272 y = Synth.new("tpulse", [\freq, 350, \sawFreq, 220]);
283 // set a control by argument name
289 // modulate out to bus number 1 (the right speaker)
292 // multiple set commands in one message
293 y.set("out", 0, "freq",300);
295 // free the synth from the server
299 subsection:: Filtering
302 // first collect some things to play with
303 SynthDef("moto-rev", { arg out=0;
305 x = RLPF.ar(LFPulse.ar(SinOsc.kr(0.2, 0, 10, 21), [0,0.1], 0.1),
306 100, 0.1).clip2(0.4);
310 SynthDef("bubbles", { arg out=0;
312 f = LFSaw.kr(0.4, 0, 24, LFSaw.kr([8,7.23], 0, 3, 80)).midicps;
313 zout = CombN.ar(SinOsc.ar(f, 0, 0.04), 0.2, 0.2, 4); // echoing sine wave
318 SynthDef("rlpf",{ arg out=0,ffreq=600,rq=0.1;
319 ReplaceOut.ar( out, RLPF.ar( In.ar(out), ffreq,rq) )
323 SynthDef("wah", { arg out, rate = 1.5, cfreq = 1400, mfreq = 1200, rq=0.1;
327 cfreq = Lag3.kr(cfreq, 0.1);
328 mfreq = Lag3.kr(mfreq, 0.1);
329 rq = Ramp.kr(rq, 0.1);
330 zout = RLPF.ar(zin, LFNoise1.kr(rate, mfreq, cfreq), rq, 10).distort
333 // replace the incoming bus with the effected version
334 ReplaceOut.ar( out , zout );
338 SynthDef("modulate",{ arg out = 0, freq = 1, center = 440, plusMinus = 110;
339 Out.kr(out, SinOsc.kr(freq, 0, plusMinus, center));
343 // execute these one at a time
345 // y is playing on bus 0
346 y = Synth("moto-rev",["out",0]);
348 // z is reading from bus 0 and replacing that; It must be *after* y
349 z = Synth.after(y,"wah",["out",0]);
354 // resume the wah-ing
357 // add a rlpf after that, reading and writing to the same buss
358 x = Synth.after(z,"rlpf",["out",0]);
360 // create another rlpf after x
361 t = Synth.after(x,"rlpf",["out",0]);
365 x.set(\ffreq, 800); // Symbols work for control names too
367 // Now let's modulate x's ffreq arg
368 // First get a control Bus
369 b = Bus.control(s, 1);
371 // now the modulator, *before* x
372 m = Synth.before(x, "modulate", [\out, b]);
374 // now map x's ffreq to b
377 m.set("freq", 4, "plusMinus", 20);
383 // now place another synth after y, on the same bus
384 // they both write to the buss, adding their outputs
385 r = Synth.after(y,"bubbles",["out",0]);
391 // look at the Server window
392 // still see 4 Ugens and 1 synth?
393 // you can't hear me, but don't forget to free me