scide: implement selectionLength for openDocument
[supercollider.git] / HelpSource / Classes / Pdef.schelp
blob5bb9f2945adeb0fac0ea99575753f601cd45aedc
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 Pdef and Pdefn use separate global collections.
11 code::
12 Pdef(key)       //returns the instance
13 Pdef(key, pat)  //stores the pattern and returns the instance, like Tdef and Ndef.
16 It can be used to store event Patterns globally. Changes in this global library have immediate effect.
18 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::.
20 subsection::First Example
22 code::
23 s.boot;
25 Pdef(\x, Pbind(\note, Pbrown(0, 6, 0.1, inf)));
26 Pdef(\x).quant = 0; // no waiting.
27 Pbindf(Pdef(\x), \dur, 0.03).play;
28 Pbindf(Pdef(\x), \dur, 0.1, \ctranspose, 15).play;
29 Pbindf(Pdef(\x), \dur, 0.3, \ctranspose, 2).play;
30 // now change the definition
31 Pdef(\x, Pbind(\note, Pseq([0, 3, 5, 7, 9, 11], inf)));
32 Pdef(\x, Pbind(\freq, Pseq([1000, 1923, 245.2, 1718] / 1.2 + 0.1, inf)));
35 ClassMethods::
37 private::initClass
39 subsection::Creation
41 method::new
42 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.
44 Using strong::*new(key):: you can access the pattern at that key (if none is given, a default silent event is created)
46 method::default
47 Default source, if none is given. The default is an Event.silent of 1.0 beat duration.
49 method::removeAll
50 Remove all proxies from the global dictionary ( link::#*all:: )
52 method::clear
53 Clear all proxies, setting their source to silence.
55 method::all
56 Set or return the environment ( link::Classes/IdentityDictionary:: ) that stores all Pdefs.
58 method::defaultQuant
59 Set the default quantisation for new instances (default: 1.0). This can be an array [quant, phase, timingOffset, outset]
61 InstanceMethods::
63 subsection::Changing the definition / setting the source
65 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::.
67 method::quant
68 Set the quantisation time for beat accurate scheduling.
70 argument::val
71 can be an array strong::[quant, phase, timingOffset, outset] ::, or just strong::[quant, phase]:: etc.
73 method::condition
74 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.
76 method::count
77 Create and update condition that simply counts up to n and switches the pattern then
79 method::reset
80 Switch the pattern immediately (stuck conditions can be subverted by this).
82 method::fadeTime
83 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)
85 method::envir
86 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.
88 method::set
89 Set arguments in the default event. If there is none, it is created and the pattern is rebuilt.
91 method::map
92 Map Pdefn to the keys in the event.
94 method::clear
95 Set the source to nil
97 method::endless
98 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.
100 subsection::Pdef as stream reference
102 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.
104 method::fork
105 Play an independent stream in parallel.
107 argument::quant
108 can be an array of [quant, phase, offset], or a link::Classes/Quant:: value.
110 method::embed
111 Pass a value (typically an link::Classes/Event::) into the pattern inval, and embed the Pdef in the stream.
113 embedInStream
114 just like any pattern, embeds itself in stream
116 subsection::Pdef as EventStreamPlayer
118 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::.
120 method::play
121 Starts the Pdef and creates a player.
123 argument::quant
124 can be an array of [quant, phase, offset] or a link::Classes/Quant:: value.
126 method::stop
127 Stops the player
129 method::player
130 Return the current player (if the Pdef is simply used in other streams this is nil)
132 method::pause, resume, reset
133 Perform this method on the player.
135 method::isPlaying
136 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.
138 Examples::
140 subsection::Pdef as stream reference
142 code::
144 SynthDef("Pdefhelp", { arg out, freq, sustain=1, amp=1, pan;
145         var env, u=1;
146         env = EnvGen.kr(Env.perc(0.03, sustain), 1, doneAction:2);
147         3.do { var d; d = exprand(0.01, 1); u = SinOsc.ar(d * 300, u, rrand(0.1,1.2) * d, 1) };
148         Out.ar(out, Pan2.ar(SinOsc.ar(u + 1 * freq, 0, amp * env), pan));
150 }).add;
152 s.boot;
154 Pdef(\metronom, Pbind(\instrument, \Pdefhelp, \dur, 1, \degree, 16, \legato, 0.1)).play;
156 x = Pseq([Pdef(\a), Pdef(\b), Pdef(\c)], inf).play;
158 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 5, 4, 3])));
159 Pdef(\b, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[7, 8, 7, 8])));
160 Pdef(\c, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 1, 2], 2)));
165 Pdef(\c, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[4, 3, 1, 2]*3)));
168 // infinite loops are scheduled (to ths clock's next beat by default) and released:
170 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.753, \degree, Pseq(#[0, 5, 4, 3, 2], inf)));
171 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[0, 5, 4, 3] + 1, 1)));
172 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.25, \degree, Pseq(#[0, 5, 4, 3] - 4, 1)));
174 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.125, \degree, Pseq(#[0, 5] - 1, 1)));
175 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.753, \degree, Pshuf(#[0, 5, 4, 3, 2], inf)));
177 x.stop;
178 Pdef(\metronom).stop;
180 // Pdef can be used in multiple patterns:
183 x = Ppar([
184         Pbindf(Pn(Pdef(\a), inf),
185                 \gtranspose, Pstutter(8, Pseq(#[0, 2, 0, 3],inf))
186         ),
187         Pbindf(Pn(Pdef(\a), inf),
188                 \gtranspose, Pstutter(8, Pseq(#[7, 4, 0, 3],inf)),
189                 \dur, 0.6
190         ),
191         Pbindf(Pn(Pdef(\a), inf),
192                 \degree, Pseq(#[0, 5, 4, 3, 2, 3, 2], 1)
193         )
194 ]).play;
197 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.1, \degree, Pseq(#[0, 1, 0, 1, 2], inf)));
199 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4], inf)));
201 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 1, \degree, Pseq([0, 4], inf)));
203 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4, Prand([6, 8b],2)], inf)));
205 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.1, \degree, Pseq(#[0, 1b, 1, 2b, 2, 3, 4b, 4, 5], inf)));
207 // using a fade time, the above changes are crossfaded
208 Pdef(\a).fadeTime = 2;
210 Pdef(\a, Pbind(\instrument, \Pdefhelp, \dur, 0.2, \degree, Pseq([0, 4, Prand([6, 8b],2)], inf)));
212 // ...
214 Pdef(\a).set(\detune, -50); // set environment
215 Pdef(\a).set(\detune, 0);
217 x.stop;
220 subsection::Pdef as EventStreamPlayer
222 code::
224 // load a synthdef
225 s.boot;
226 SynthDef("gpdef",
227         { arg out=0, freq=440, sustain=0.05, amp=0.1, pan;
228                 var env;
229                 env = EnvGen.kr(Env.perc(0.01, sustain), doneAction:2) * amp;
230                 Out.ar(out, Pan2.ar(SinOsc.ar(freq, 0, env), pan))
231         }).add;
235 Pdef(\x); // creates a Pdef with a default pattern.
238 Pdef(\x).play; // play it. A silent resting pattern is used.
239 Pdef(\y).play; // play a second one (automatically instantiated)
242 // assign various patterns to it:
244 Pdef(\x, Pbind(\dur, 0.25, \instrument, \gpdef));
245 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6], inf), \instrument, \gpdef));
246 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]+1, inf), \instrument, \gpdef));
247 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]-1, inf), \instrument, \gpdef));
248 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b]-2, inf), \instrument, \gpdef));
250 // using fadeTime:
252 Pdef(\y).fadeTime = 8.0;
253 Pdef(\y, Pbind(\dur, 0.125, \degree, Pseq([3, 4, 5b, 6]+4.rand, inf), \instrument, \gpdef));
254 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5b, 6]-2, inf), \instrument, \gpdef));
257 Pdef(\x, Pbind(
258                 \dur, 1 / 6,
259                 \degree, Pseq([3, 4, Prand([8, 2, 3, 9, 10],1) - 5, 6]+1, inf),
260                 \instrument, \gpdef
261                 )
262         );
265 Pdef(\x, Pbind(
266                 \dur, 0.25,
267                 \degree, Pseq([3, 4, Prand([8, 2, 3, 9, 10],1), 6], inf),
268                 \instrument, \gpdef)
269         );
271 Pdef(\x).stop;
273 Pdef(\x).play;
275 // tempo change
276 TempoClock.default.tempo = 1.3;
277 Pdef(\y, Pbind(\dur, 0.25, \degree, Pseq([3, 4, 5, 6]+1, inf), \instrument, \gpdef));
279 // drop in ending patterns
281 Pdef(\x, Pbind(\dur, 0.25, \degree, Pseq([3, [7,4], 5, 6]-2), \instrument, \gpdef));
282 Pdef(\x, Pbind(\dur, 0.125, \degree, Pseq([3, [7,4], 5, 4]-3), \instrument, \gpdef));
283 Pdef(\x, Pbind(\dur, 0.35, \degree, Pseq([3, [7,4], 5, 4, 3]-3), \instrument, \gpdef));
284 Pdef(\x, Pbind(\dur, 0.25, \degree, Pshuf([3, [7,4], 5, 6]-2), \instrument, \gpdef));
287 // clear all.
288 Pdef(\x).clear;
289 Pdef(\y).clear;
290 TempoClock.default.tempo = 1.0;
293 // GUI example: see also
294 PdefAllGui(18);
297 subsection::Recursion
299 Pdefs can be used recursively under the condition that the stream call structure allows it. a structure like the following works:
301 code::
302 Pdef(\x, Pseq([Pbind(\instrument, \gpdef), Pdef(\x)], inf));
303 Pdef(\x).play;
306 but the following would crash, because code::.embedInStream:: is called recursively with no limit:
308 code::
309 // Pdef(\y, Pseq([Pdef(\y), Pbind(\instrument, \gpdef)], inf));
312 subsection::Quantizing and outset
314 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.
316 For example, if quant is 32, and one has just missed the first beat when changing the pattern,
317 one has to wait for 32 beats until the change happens. Using an outset of 1, it is assumed that you had already
318 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).
320 quant can be: strong::[quant, phase, timingOffset, outset]::
322 note::
323 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.
326 code::
328 Pdef(\x).quant_([8, 0, 0, 1]);
329 Pdef(\y).quant_([8, 0.5, 0, 1]); // phase: half a beat
330 Pdef(\x).play;
331 Pdef(\y).play;
334 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf)));
335 Pdef(\y, Pbind(\degree, Pseq((0..7)-2, inf)));
336 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf), \dur, 0.5));
337 Pdef(\y, Pbind(\degree, Pseq((0..7).scramble-2, inf), \dur, 0.25, \legato, 0.3));
338 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)));
340 Pdef(\x, Pbind(\degree, Pseq([ 1, 5, 6, 7, 0, 3, 2, 4 ], inf), \dur, 1));
341 Pdef(\x, Pbind(\degree, Pseq([ 0, 2, 2, 4, 0, 4, 0, 4 ], inf), \dur, 1));
343 Pdef(\x).quant_([8, 1/3, 0, 1]); // phase: 1/6 beat relative to y
344 Pdef(\x, Pbind(\degree, Pseq([ 1, 1, 1, 7, 0, 2, 2, 4 ], inf), \legato, 0.1));
345 Pdef(\x, Pbind(\degree, Pseq([ 3, 3, 3, 4b ], inf), \legato, 0.1));
346 Pdef(\y, Pbind(\degree, Pseq((0..7).scramble-4, inf), \dur, 0.25, \legato, 0.3));
351 // some testing
353 var quant = #[8, 0, 0, 1]; // quantise to 8 beats, no phase, insert quant to 1 beat
354 Pdef(\x).quant_(quant);
355 Pdef(\x).play;
356 Routine { loop { 8.do { |i| ("uhr:"+i).postln; 1.wait } } }.play(quant:quant);
357 Pbind(\degree, Pseq((0..7), inf)).play(quant:quant);
360 Pdef(\x, Pbind(\degree, Pseq((0..7)+2, inf)).trace(\degree));
361 Pdef(\x, Pbind(\degree, Pseq((0..7), inf) + [0, 3]).trace(\degree));
362 Pdef(\x, Pbind(\degree, Pseq((0..7), inf) + [0, 6], \dur, 0.5).trace(\degree));
365 Pdef(\x).fadeTime = 8;
367 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
368 Pdef(\x, Pbind(\degree, Pseq((0..7).reverse, inf) + [0, 6], \dur, 0.5));
370 Pdef(\x).fadeTime = nil;
371 Pdef(\x).quant = 1;
373 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
375 Pdef(\x).quant = 8;
376 Pdef(\x, Pbind(\degree, Pseq((0..7), inf)).trace(\degree));
379 subsection::Update condition
381 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.
383 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).
385 code::
386 Pdef(\x).play;
387 Pdef(\x).quant = 0; // we don't want quant here.
388 Pdef(\x, Pbind(\degree, Pseq((0..5), inf), \dur, 0.3)).condition_({ |val, i| i.postln % 6 == 0 });
389 Pdef(\x, Pbind(\degree, Pseq((0..7) + 5.rand, inf), \dur, 0.3)).condition_({ |val, i| (i % 8).postln == 0 });
391 // the above is equivalent to:
392 Pdef(\x, Pbind(\degree, Pseq((0..7) + 5.rand, inf), \dur, 0.3)).count(8);
394 // the value that is sent in is the event, so decisions can be made dependent on the event's fields
397 subsection::reset
399 code::
400 // reset to change immediately:
401 Pdef(\x).reset;