sclang: ServerShmInterface - try to avoid multiple destructor calls
[supercollider.git] / HelpSource / Classes / Node.schelp
blob47a84c7dd64190ff6c75282c0f9af783ebce8616
1 class:: Node
2 summary:: Abstract superclass of Synth and Group
3 related:: Reference/Server-Architecture, Classes/Synth, Classes/Group, Classes/RootNode
4 categories:: Server>Nodes, Server>Abstractions
6 Description::
7 This class is the abstract super class of Synth and Group, which represent synth and group nodes on the server.  Node objects are not made explicitly, but Synth and Group are subclasses, and inherit the methods  documented below.
9 subsection:: Freed Nodes and Node Status
11 Nodes which you explicitly free using the methods free or release will have their group instance variable set to nil. However Nodes which are automatically freed after a certain time (for instance by an link::Classes/EnvGen:: with a doneAction of 2) will not.
12 This keeps the implementation of the classes simple and lightweight.
14 To have the current state of a Node tracked you can register it with an instance of link::Classes/NodeWatcher::, either by calling register on the Node instance or on the NodeWatcher singleton. This will enable two variables, isPlaying and isRunning, which you can use for checking purposes.
16 subsection:: Bundling
18 Many 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.
19 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.
21 classmethods::
22 private:: initClass
24 method:: addActions
25 Returns:: the list of addActions as an event.
26 discussion::
27 Useful for converting addAction symbols to their corresponding integer codes.
28 code::
30 Node.addActions.at(\addToTail)
32 // returns 1
35 instancemethods::
37 subsection:: Instance Variables
39 The following getter methods also have corresponding setters, but they should be used with extreme care and only if you are sure you know what you're doing.
41 method:: nodeID
42 Returns:: the Node's node ID number.
43 discussion::
44 Normally you should not need to access this since instances of Node can be passed directly as link::Classes/UGen:: inputs or link::Classes/Synth:: args.
46 method:: group
47 Returns:: an instance of Group or RootNode corresponding to this Node's group on the server.
49 method:: server
50 Returns:: an instance of Server corresponding to this Node's server app.
52 method:: isPlaying
53 Returns:: a boolean indicating if this node is currently on the server, providing this Node has been registered with a link::Classes/NodeWatcher::.
54 discussion::
55 N.B. If this Node has not been registered this will likely be false in any case.
57 method:: isRunning
58 Returns:: a boolean indicating if this node is currently on the server, providing this Node has been registered with a link::Classes/NodeWatcher::.
59 discussion::
60 N.B. If this Node has not been registered this will likely be false in any case.
62 subsection:: Node Commands
64 See the Node Commands section in link::Reference/Server-Command-Reference:: for the OSC equivalents of the methods outlined below.
66 method:: free, freeMsg
67 Stop this Node and free it from its parent group on the server. Once a Node has been freed, you cannot restart it.
68 argument:: sendFlag
69 a boolean indicating whether the free message should be sent. If false an n_free message will not be sent to this Node's server, but its isPlaying and isRunning variables will be set to false. The default for sendFlag is true.
70 discussion::
71 If this Node is a link::Classes/Group:: this will free all Nodes within the Group.
72 code::
73 s.boot;
74 x = Synth("default");
75 x.free;
78 method:: run, runMsg
79 Set the running state of this Node according to a boolean. False will pause the node without freeing it. The default is true.
80 discussion::
81 If this Node is a Group this will set the running state of all Nodes within the Group.
82 code::
83 s.boot;
85 x = SynthDef("help-node-set", {arg freq = 440, out = 0;
86         Out.ar(out, SinOsc.ar(freq, 0, 0.1));}).play(s);
88 x.run(false);
89 x.run; // default is true
90 x.free;
93 method:: set, setMsg
94 Set controls in this Node to values.
95 discussion::
96 Controls are defined in a SynthDef as args or instances of link::Classes/Control::. They are specified here using symbols, strings, or indices, and are listed in pairs with values. If this Node is a Group this will set all Nodes within the Group.
97 code::
98 s.boot;
100 x = SynthDef("help-node-set", {| freq = 440, out = 0 |
101         Out.ar(out, SinOsc.ar(freq, 0, 0.1));
103 x = x.play(s);
105 x.set(\freq, 880, \out, 1); // two pairs
106 x.set(0, 660, 1, 0); // freq is the first argument, so it's index is 0. out is index 1.
107 x.free;
109 Values that are arrays are sent using the OSC array type-tags ($[ and $]).  These values will be assigned to subsequent controls in the manner of setn.
110 code::
111 s.boot;
113 x = SynthDef("help-node-set", {| freq = #[440, 450, 460], out = 0 |
114         Out.ar(out, Mix(SinOsc.ar(freq, 0, 0.1)));
116 x = x.play(s);
118 x.set(\freq, [1,2,3] * 400 + [1,2,3], \out, 1); // two pairs
119 x.set(\freq, [3] * 400 + [1,2,3], \out, 1); // two pairs
120 x.set(0, [660, 680, 720], 1, 0); // freq is the first argument, so it's index is 0. out is index 1.
121 x.free;
124 method:: setn, setnMsg
125 Set sequential ranges of controls in this Node to values.
126 discussion::
127 Controls are defined in a SynthDef as args or instances of link::Classes/Control::. They are specified here using symbols, strings, or indices, and are listed in pairs with arrays of values. If this Node is a Group this will setn all Nodes within the Group.
128 code::
129 s.boot;
131 x = SynthDef("help-node-setn", {
132         arg freq1 = 440, freq2 = 440, freq3 = 440, amp1 = 0.05, amp2 = 0.05, amp3 = 0.05;
133         Out.ar(0, Mix(SinOsc.ar([freq1, freq2, freq3], 0, [amp1, amp2, amp3])));}).play(s);
135 // set 3 controls starting from \freq1, and 3 controls starting from \amp1
136 x.setn(\freq1, [440, 880, 441], \amp1, [0.3, 0.1, 0.3]);
137 x.free;
140 method:: fill, fillMsg
141 Set sequential ranges of controls in this Node to a single value.
142 discussion::
143 Controls are defined in a SynthDef as args or instances of link::Classes/Control::. They are specified here using symbols, strings, or indices, and are listed in groups of three along with an integer indicating the number of controls to set, and the value to set them to. If this Node is a Group this will fill all Nodes within the Group.
145 method:: map, mapMsg
146 Map controls in this Node to read from control or audio rate link::Classes/Bus::es.
147 discussion::
148 Controls are defined in a SynthDef as args or instances of link::Classes/Control:: or its subclasses. They are specified here using symbols, strings, or indices, and are listed in pairs with Bus objects. The number of sequential controls mapped corresponds to the Bus' number of channels.
150 If this Node is a Group this will map all Nodes within the Group.
152 Note that with mapMsg if you mix audio and control rate busses you will get an Array of two messages rather than a single message. Integer bus indices are assumed to refer to control buses. To map a control to an audio bus, you must use a Bus object.
153 code::
154 s.boot;
156 b = Bus.control(s, 1); b.set(880);
157 c = Bus.control(s, 1);  c.set(884);
158 x = SynthDef("help-Node-map", { arg freq1 = 440, freq2 = 440;
159         Out.ar(0, SinOsc.ar([freq1, freq2], 0, 0.1));
160 }).play(s);)
161 x.map(\freq1, b, \freq2, c);
162 x.free; b.free; c.free;
164 // same as above with a multichannel Bus and Control
166 b = Bus.control(s, 2); b.set(880, 884);
167 x = SynthDef("help-Node-map2", { arg freqs = #[440, 440];
168         Out.ar(0, SinOsc.ar(freqs, 0, 0.1));
169 }).play(s);)
170 x.map(\freqs, b);
171 x.free; b.free;
174 method:: mapn, mapnMsg
175 Map sequential ranges of controls in this Node to read from control rate Buses.
176 discussion::
177 This is similar to map above, but you specify the number of sequential Controls to map. If this Node is a Group this will mapn all Nodes within the Group.
179 method:: release, releaseMsg
180 This is a convenience method which assumes that the synth contains an envelope generator (an EnvGen, Linen, or similar UGen) running a sustaining envelope (see Env) and that it's gate argument is set to a control called \gate. This method will cause the envelope to release.
181 argument:: releaseTime
182 if not nil, it will override the envelope's decay or release time.
183 discussion::
184 If this Node is a Group this will release all Nodes within the Group.
185 code::
186 x = { arg gate=1; BrownNoise.ar(0.5) * EnvGen.kr(Env.cutoff(1), gate, doneAction:2) }.play;
187 x.release(5); // overide the Env's specified 1 second release time
190 method:: query
191 Sends an n_query message to the server, which will reply with a message containing information about this node and its place in the server's node tree.
192 discussion::
193 This information will be printed to the post window. (See also the queryAllNodes method of Server.) "parent" indicates the Node's enclosing group. If "prev" or "next" are equal to -1 that indicates that there are no other nodes in the enclosing group before or after this one, respectively.
194 code::
195 g = Group.new;
196 x = Synth.head(g, "default");
197 x.query;
198 g.query;
199 s.queryAllNodes; // Note the RootNode (ID 0) and the default Group (ID 1)
200 x.free; g.free;
203 method:: trace
204 Causes a synth to print out the values of the inputs and outputs of its unit generators for one control period to the post window. Causes a group to print the node IDs and names of each node in the group for one control period.
205 code::
206 g = Group.new;
207 x = Synth.head(g, "default");
208 x.trace;
209 g.trace;
210 x.free; g.free;
213 method:: register
214 Registers the node at the link::Classes/NodeWatcher:: object.
215 discussion::
216 This will enable two variables, isPlaying and isRunning, which you can use for checking purposes.
217 code::
219 b = s.makeBundle(false, {
220         a = Group.new(s); //create a node object
221         a.register; // register before creating on the server
224 a.isPlaying;
225 s.listSendBundle(nil, b); //start the node on the server
226 a.isPlaying;
227 a.isRunning;
228 a.run(false);
229 a.isRunning;
230 s.freeAll; //free all nodes
231 a.isPlaying;
232 a.isRunning;
235 subsection:: Changing the order of execution
237 The following methods can be used to change the Node's place in the order of execution. See the link::Guides/Order-of-execution:: help file for more information on this important topic. See link::Reference/Server-Command-Reference:: for the OSC equivalents of these methods.
239 method:: moveAfter, moveAfterMsg
240 Move this Node to be directly after aNode. N.B. n_after, the OSC message which this method encapsulates, allows already freed nodes as targets. This is so that one may attempt a series of moves, with the last successful one taking effect. For this reason this method will fail silently if either the target or this node have already been freed. If you will need to check, you may register the relevant nodes with a NodeWatcher.
242 method:: moveBefore, moveBeforeMsg
243 Move this Node to be directly before aNode. N.B. n_before, the OSC message which this method encapsulates, allows already freed nodes as targets. This is so that one may attempt a series of moves, with the last successful one taking effect. For this reason this method will fail silently if either the target or this node have already been freed. If you will need to check, you may register the relevant nodes with a NodeWatcher.
245 method:: moveToHead, moveToHeadMsg
246 If aGroup is a Group then this method will move this Node to the head of that Group. If it is nil this will move this Node to the head of the default_group of this Node's Server.
248 method:: moveToTail, moveToTailMsg
249 If aGroup is a Group then this method will move this Node to the tail of that Group. If it is nil this will move this Node to the tail of the default_group of this Node's Server.
251 subsection:: Other Methods
253 method:: asTarget
254 Returns:: this Node. See the link::Reference/asTarget:: help file for more details.
256 method:: printOn
257 Prints this Node's link::Classes/Class:: (link::Classes/Synth:: or link::Classes/Group::) and nodeID on stream.
259 method:: hash
260 Returns:: server.hash bitXor: nodeID.hash
262 method:: ==
263 Returns:: true if this Node and aNode have the same nodeID and the same Server object, otherwise returns false.
264 discussion::
265 Under certain circumstances this Node and aNode might not be the same object, even though this returns true.
266 code::
267 g = Group.basicNew(s, 1); // the default group of s
268 h = Group.basicNew(s, 1); // and again
269 g == h;         // true
270 g === h;        // false
273 method:: onFree
274 Evaluate function when this Node is freed.
275 discussion::
276 code::
277 {PinkNoise.ar(1) * Line.kr(1,0,2,doneAction:2)}.play.onFree {"done".postln};
280 method:: waitForFree
281 Wait until this Node is freed. Should be used inside a Routine or similar.
282 discussion::
283 code::
284 fork {
285     {SinOsc.ar(440!2) * Line.kr(0,1,5,doneAction:2)}.play.waitForFree;
286     {PinkNoise.ar(1) * Line.kr(1,0,2,doneAction:2)}.play.onFree {"done".postln};