sclang: ServerShmInterface - try to avoid multiple destructor calls
[supercollider.git] / HelpSource / Classes / Pdef.schelp
blob65f77894861ff0758f38a0f993986704944c39d8
1 class:: Pdef
2 summary:: stream reference definition
3 categories:: Libraries>JITLib>Patterns
4 related:: Classes/Pdefn, Classes/PdefGui
6 description::
7 Pdef is a class that provides an interface to its superclass link::Classes/EventPatternProxy::, keeping a reference to a stream that can be replaced while playing. One pattern may be used in many streams in different places. A change in the pattern definition propagates through all streams.
9 code::
10 Pdef(key)       //returns the instance
11 Pdef(key, pat)  //stores the pattern and returns the instance, like Tdef and Ndef.
14 It can be used to store event Patterns globally. Changes in this global library have immediate effect.
16 For strong::non-event patterns:: link::Classes/Pdefn:: is used instead. For another use of Pdef see also link::Tutorials/JITLib/recursive_phrasing::. Graphical overview over all current Pdefs: link::Classes/PdefAllGui::. Overview: link::Overviews/JITLib::.
18 subsection::First Example
20 code::
21 s.boot;
23 Pdef(\x, Pbind(\note, Pbrown(0, 6, 0.1, inf)));
24 Pdef(\x).quant = 0; // no waiting.
25 Pbindf(Pdef(\x), \dur, 0.03).play;
26 Pbindf(Pdef(\x), \dur, 0.1, \ctranspose, 15).play;
27 Pbindf(Pdef(\x), \dur, 0.3, \ctranspose, 2).play;
28 // now change the definition
29 Pdef(\x, Pbind(\note, Pseq([0, 3, 5, 7, 9, 11], inf)));
30 Pdef(\x, Pbind(\freq, Pseq([1000, 1923, 245.2, 1718] / 1.2 + 0.1, inf)));
33 ClassMethods::
35 private::initClass
37 subsection::Creation
39 method::new
40 Store the pattern in a global dictionary under key, replacing its pattern with the new one. If the pattern is a strong::function::, Pdef creates a link::Classes/PlazyEnvir:: internall that dynamically creates the pattern returned from the function, applying the arguments from the inevent.
42 Using strong::*new(key):: you can access the pattern at that key (if none is given, a default silent event is created)
44 method::default
45 Default source, if none is given. The default is an Event.silent of 1.0 beat duration.
47 method::removeAll
48 Remove all proxies from the global dictionary ( link::#*all:: )
50 method::clear
51 Clear all proxies, setting their source to silence.
53 method::all
54 Set or return the environment ( link::Classes/IdentityDictionary:: ) that stores all Pdefs.
56 method::defaultQuant
57 Set the default quantisation for new instances (default: 1.0). This can be an array [quant, phase, timingOffset, outset]
59 InstanceMethods::
61 subsection::Changing the definition / setting the source
63 One pattern may have many streams in different places. A change in the pattern definition Pdef propagates through all streams. The change does not have to be immediate - there is a scheme to schedule when the change becomes effective: a strong::quant:: and strong::clock:: (like elsewhere) and a strong::condition::.
65 method::quant
66 Set the quantisation time for beat accurate scheduling.
68 argument::val
69 can be an array strong::[quant, phase, timingOffset, outset] ::, or just strong::[quant, phase]:: etc.
71 method::condition
72 Provide a condition under which the pattern is switched when a new one is inserted. The stream value and a count value is passed into the function.
74 method::count
75 Create and update condition that simply counts up to n and switches the pattern then
77 method::reset
78 Switch the pattern immediately (stuck conditions can be subverted by this).
80 method::fadeTime
81 When the synthdefs that are used contain an code::\amp:: control, the patterns are replaced by crossfading the previous with the new over this time (in beats)
83 method::envir
84 Set the event for the Pdef. It is used to filter the incoming stream before it is passed to the source pattern. This is similar to link::Classes/NodeProxy#-nodeMap::. When set for the first time, the pattern is rebuilt.
86 method::set
87 Set arguments in the default event. If there is none, it is created and the pattern is rebuilt.
89 method::map
90 Map Pdefn to the keys in the event.
92 method::clear
93 Set the source to nil
95 method::endless
96 Returns a link::Classes/Prout:: that plays the proxy endlessly, replacing strong::nil:: with a strong::default:: value (silent event). This allows to create streams that idle on until a new pattern is inserted.
98 subsection::Pdef as stream reference
100 A single Pdef may serve as a definition for multiple streams. These methods show how to fork off separate streams from one instance. Even if they run in different contexts, their definition may still be changed.
102 method::fork
103 Play an independent stream in parallel.
105 argument::quant
106 can be an array of [quant, phase, offset], or a link::Classes/Quant:: value.
108 method::embed
109 Pass a value (typically an link::Classes/Event::) into the pattern inval, and embed the Pdef in the stream.
111 embedInStream
112 just like any pattern, embeds itself in stream
114 subsection::Pdef as EventStreamPlayer
116 For live coding, each Pdef also may control one instance that plays one stream off it. This is an link::Classes/EventStreamPlayer::, accessible in the instance variable link::#-player::.
118 method::play
119 Starts the Pdef and creates a player.
121 argument::quant
122 can be an array of [quant, phase, offset] or a link::Classes/Quant:: value.
124 method::stop
125 Stops the player
127 method::player
128 Return the current player (if the Pdef is simply used in other streams this is nil)
130 method::pause, resume, reset
131 Perform this method on the player.
133 method::isPlaying
134 Returns true if player is running. If a Pdef is playing and its stream ends, it will schedule a stream for playing strong::as soon as a new one is assigned to it::. If it is stopped by strong::stop::, it won't.
136 Examples::
138 subsection::Pdef as stream reference
140 code::
142 SynthDef("Pdefhelp", { arg out, freq, sustain=1, amp=1, pan;
143         var env, u=1;
144         env = EnvGen.kr(Env.perc(0.03, sustain), 1, doneAction:2);
145         3.do { var d; d = exprand(0.01, 1); u = SinOsc.ar(d * 300, u, rrand(0.1,1.2) * d, 1) };
146         Out.ar(out, Pan2.ar(SinOsc.ar(u + 1 * freq, 0, amp * env), pan));
148 }).add;
150 s.boot;
152 Pdef(\metronom, Pbind(\instrument, \Pdefhelp, \dur, 1, \degree, 16, \legato, 0.1)).play;
154 x = Pseq([Pdef(\a), Pdef(\b), Pdef(\c)], inf).play;
156 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 5, 4, 3])));
157 Pdef(\b, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[7, 8, 7, 8])));
158 Pdef(\c, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 1, 2], 2)));
163 Pdef(\c, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[4, 3, 1, 2]*3)));
166 // infinite loops are scheduled (to ths clock's next beat by default) and released:
168 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.753, \degree, Pseq(#[0, 5, 4, 3, 2], inf)));
169 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[0, 5, 4, 3] + 1, 1)));
170 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 5, 4, 3] - 4, 1)));
172 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[0, 5] - 1, 1)));
173 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.753, \degree, Pshuf(#[0, 5, 4, 3, 2], inf)));
175 x.stop;
176 Pdef(\metronom).stop;
178 // Pdef can be used in multiple patterns:
181 x = Ppar([
182         Pbindf(Pn(Pdef(\a), inf),
183                 \gtranspose, Pstutter(8, Pseq(#[0, 2, 0, 3],inf))
184         ),
185         Pbindf(Pn(Pdef(\a), inf),
186                 \gtranspose, Pstutter(8, Pseq(#[7, 4, 0, 3],inf)),
187                 \dur, 0.6
188         ),
189         Pbindf(Pn(Pdef(\a), inf),
190                 \degree, Pseq(#[0, 5, 4, 3, 2, 3, 2], 1)
191         )
192 ]).play;
195 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.1, \degree, Pseq(#[0, 1, 0, 1, 2], inf)));
197 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4], inf)));
199 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 1, \degree, Pseq([0, 4], inf)));
201 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4, Prand([6, 8b],2)], inf)));
203 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.1, \degree, Pseq(#[0, 1b, 1, 2b, 2, 3, 4b, 4, 5], inf)));
205 // using a fade time, the above changes are crossfaded
206 Pdef(\a).fadeTime = 2;
208 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4, Prand([6, 8b],2)], inf)));
210 // ...
212 Pdef(\a).set(\detune, -50); // set environment
213 Pdef(\a).set(\detune, 0);
215 x.stop;
218 subsection::Pdef as EventStreamPlayer
220 code::
222 // load a synthdef
223 s.boot;
224 SynthDef("gpdef",
225         { arg out=0, freq=440, sustain=0.05, amp=0.1, pan;
226                 var env;
227                 env = EnvGen.kr(Env.perc(0.01, sustain), doneAction:2) * amp;
228                 Out.ar(out, Pan2.ar(SinOsc.ar(freq, 0, env), pan))
229         }).add;
233 Pdef(\x); // creates a Pdef with a default pattern.
236 Pdef(\x).play; // play it. A silent resting pattern is used.
237 Pdef(\y).play; // play a second one (automatically instantiated)
240 // assign various patterns to it:
242 Pdef(\x, Pbind(\dur, 0.25, \instrument, \gpdef));
243 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6], inf), \instrument, \gpdef));
244 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]+1, inf), \instrument, \gpdef));
245 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]-1, inf), \instrument, \gpdef));
246 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b]-2, inf), \instrument, \gpdef));
248 // using fadeTime:
250 Pdef(\y).fadeTime = 8.0;
251 Pdef(\y, Pbind(\dur, 0.125, \degree, Pseq([3, 4, 5b, 6]+4.rand, inf), \instrument, \gpdef));
252 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]-2, inf), \instrument, \gpdef));
255 Pdef(\x, Pbind(
256                 \dur, 1 / 6,
257                 \degree, Pseq([3, 4, Prand([8, 2, 3, 9, 10],1) - 5, 6]+1, inf),
258                 \instrument, \gpdef
259                 )
260         );
263 Pdef(\x, Pbind(
264                 \dur, 0.25,
265                 \degree, Pseq([3, 4, Prand([8, 2, 3, 9, 10],1), 6], inf),
266                 \instrument, \gpdef)
267         );
269 Pdef(\x).stop;
271 Pdef(\x).play;
273 // tempo change
274 TempoClock.default.tempo = 1.3;
275 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5, 6]+1, inf), \instrument, \gpdef));
277 // drop in ending patterns
279 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, [7,4], 5, 6]-2), \instrument, \gpdef));
280 Pdef(\x, Pbind(\dur, 0.125, \degree, Pseq([3, [7,4], 5, 4]-3), \instrument, \gpdef));
281 Pdef(\x, Pbind(\dur, 0.35, \degree, Pseq([3, [7,4], 5, 4, 3]-3), \instrument, \gpdef));
282 Pdef(\x, Pbind(\dur, 0.25, \degree, Pshuf([3, [7,4], 5, 6]-2), \instrument, \gpdef));
285 // clear all.
286 Pdef(\x).clear;
287 Pdef(\y).clear;
288 TempoClock.default.tempo = 1.0;
291 // GUI example: see also
292 PdefAllGui(18);
295 subsection::Recursion
297 Pdefs can be used recursively under the condition that the stream call structure allows it. a structure like the following works:
299 code::
300 Pdef(\x, Pseq([Pbind(\instrument, \gpdef), Pdef(\x)], inf));
301 Pdef(\x).play;
304 but the following would crash, because code::.embedInStream:: is called recursively with no limit:
306 code::
307 // Pdef(\y, Pseq([Pdef(\y), Pbind(\instrument, \gpdef)], inf));
310 subsection::Quantizing and outset
312 When quantizing to a larger number of beats, the changes become very slow if one has to wait for the next beat. Providing an strong::outset:: quant value is a way to make the change so that it appears as if it had been done at the previous grid point already. The stream is fast forwarded to the current position relative to the quant grid. Providing a number larger than zero, the next possible quant point is used as outset.
314 For example, if quant is 32, and one has just missed the first beat when changing the pattern,
315 one has to wait for 32 beats until the change happens. Using an outset of 1, it is assumed that you had already
316 changed the pattern at the first beat, the stream is fast forwarded to the time it would be at now if you had done so. The new pattern is inserted at the next beat (outset=1).
318 quant can be: strong::[quant, phase, timingOffset, outset]::
320 note::
321 This fast forwarding might create a cpu peak if the pattern is very complex/fast or quant is very long. This is hard to avoid, so it simply has to be taken into account.
324 code::
326 Pdef(\x).quant_([8, 0, 0, 1]);
327 Pdef(\y).quant_([8, 0.5, 0, 1]); // phase: half a beat
328 Pdef(\x).play;
329 Pdef(\y).play;
332 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf)));
333 Pdef(\y, Pbind(\degree, Pseq((0..7)-2, inf)));
334 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf), \dur, 0.5));
335 Pdef(\y, Pbind(\degree, Pseq((0..7).scramble-2, inf), \dur, 0.25, \legato, 0.3));
336 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)));
338 Pdef(\x, Pbind(\degree, Pseq([ 1, 5, 6, 7, 0, 3, 2, 4 ], inf), \dur, 1));
339 Pdef(\x, Pbind(\degree, Pseq([ 0, 2, 2, 4, 0, 4, 0, 4 ], inf), \dur, 1));
341 Pdef(\x).quant_([8, 1/3, 0, 1]); // phase: 1/6 beat relative to y
342 Pdef(\x, Pbind(\degree, Pseq([ 1, 1, 1, 7, 0, 2, 2, 4 ], inf), \legato, 0.1));
343 Pdef(\x, Pbind(\degree, Pseq([ 3, 3, 3, 4b ], inf), \legato, 0.1));
344 Pdef(\y, Pbind(\degree, Pseq((0..7).scramble-4, inf), \dur, 0.25, \legato, 0.3));
349 // some testing
351 var quant = #[8, 0, 0, 1]; // quantise to 8 beats, no phase, insert quant to 1 beat
352 Pdef(\x).quant_(quant);
353 Pdef(\x).play;
354 Routine { loop { 8.do { |i| ("uhr:"+i).postln; 1.wait } } }.play(quant:quant);
355 Pbind(\degree, Pseq((0..7), inf)).play(quant:quant);
358 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf)).trace(\degree));
359 Pdef(\x, Pbind(\degree, Pseq((0..7), inf) + [0, 3]).trace(\degree));
360 Pdef(\x, Pbind(\degree, Pseq((0..7), inf) + [0, 6], \dur, 0.5).trace(\degree));
363 Pdef(\x).fadeTime = 8;
365 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
366 Pdef(\x, Pbind(\degree, Pseq((0..7).reverse, inf) + [0, 6], \dur, 0.5));
368 Pdef(\x).fadeTime = nil;
369 Pdef(\x).quant = 1;
371 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
373 Pdef(\x).quant = 8;
374 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
377 subsection::Update condition
379 In order to be able to switch to a new pattern under a certain link::#-condition::, the instance variable condition can be set to a function that returns a boolean. Value and a count index are passed to the function. The condition is always valid for the strong::next pattern:: inserted. For stuck conditions, the link::#-reset:: message can be used.
381 As counting up (such as emphasis::"every nth event, a swap can happen"::) is a common task, there is a method for this, called link::#-count::(n).
383 code::
384 Pdef(\x).play;
385 Pdef(\x).quant = 0; // we don't want quant here.
386 Pdef(\x, Pbind(\degree, Pseq((0..5), inf), \dur, 0.3)).condition_({ |val, i| i.postln % 6 == 0 });
387 Pdef(\x, Pbind(\degree, Pseq((0..7) + 5.rand, inf), \dur, 0.3)).condition_({ |val, i| (i % 8).postln == 0 });
389 // the above is equivalent to:
390 Pdef(\x, Pbind(\degree, Pseq((0..7) + 5.rand, inf), \dur, 0.3)).count(8);
392 // the value that is sent in is the event, so decisions can be made dependent on the event's fields
395 subsection::reset
397 code::
398 // reset to change immediately:
399 Pdef(\x).reset;