Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / Pdefn.schelp
blob946b23c58e15b43e939ea403637e5ff644eb35c9
1 class:: Pdefn
2 summary:: non event stream reference definition
3 categories:: Libraries>JITLib>Patterns
4 related:: Classes/Pdef
6 description::
7 Pdefn provides an interface to its superclass link::Classes/PatternProxy::, 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 Pdefn(key)      //returns the instance
13 Pdefn(key, pat) //defines the pattern and returns the instance, like Pdef, Tdef and Ndef.
16 It is very similar to link::Classes/PatternProxy::.
18 Pdefn can be used to store value patterns globally (for strong::event patterns::, see link::Classes/Pdef::). Overview: link::Overviews/JITLib::
20 subsection::First Example
22 code::
23 s.boot;
25 Pdefn(\x, Pbrown(0, 6, 0.1, inf));
26 Pbind(\note, Pdefn(\x), \dur, 0.3).play;
27 Pbind(\note, Pdefn(\x), \dur, 0.1, \ctranspose, 15).play;
28 // now change the definition
29 Pdefn(\x, Pseq([0, 3, 5, 7, 9, 11], inf));
30 Pdefn(\x, Pseq([0, 3, 3, 7], inf) + Pseq([0, [0, 3], [0, 5, 7]], 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::, Pdefn creates a link::Classes/Prout:: with this function, passing in the envir, if given(see below).
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 a Pattern that returns 1.0 (This is 1 and not 0 to avoid deadlocks when used as a duration pattern. In a sense, 1 is just as generic as 0).
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 Pdefns.
56 InstanceMethods::
58 private::prAdd
60 Examples::
62 subsection::Pdefn in expressions
64 code::
65 Pdefn(\c, Pdefn(\a) + Pdefn(\b));
67 t = Pdefn(\c).asStream; // create a stream from Pdefn(\c)
69 t.value; // default value for a Pdefn is 1, so that it is a good time value default.
71 Pdefn(\a, 100); // (re)define Pdefn(\a) as 100
73 t.value;
75 Pdefn(\b, Pseq([1, 2, 3], inf)); // (re)define Pdefn(\b) as Pseq([1, 2, 3], inf)
77 3.do { t.value.postln };
79 Pdefn(\c, Pdefn(\a) * Pdefn(\b) - Pdefn(\a)); // (re)define Pdefn(\c)
81 8.do { t.value.postln };
83 Pdefn(\a, Prand([1, 4, 2], inf)); // (re)define Pdefn(\a)
86 subsection::Embedding Pdefn in other patterns
88 code::
89 Pdefn(\x, Pseq([1, 2, 3], inf));
91 x = Pseq([0, 0, Pdefn(\x)], inf).asStream;
93 t = Task({ loop({ x.next.postln; 0.3.wait }) }).play;
96 Pdefn(\x, Pseq([55, 66, 77],inf));
97 Pdefn(\x, Pseq([55, 66, 77],1));
99 t.stop;
103 // Pdefn can be accessed in multiple streams
106 SynthDef("Pdefhelp", { arg out, freq, sustain=1, amp=1, pan;
107         var env, u=1;
108         env = EnvGen.kr(Env.perc(0.03, sustain), 1, doneAction:2);
109         5.do { var d; d = exprand(0.01, 1); u = SinOsc.ar(d * 300, u, rrand(0.1,1.2) * d, 1) };
110         Out.ar(out, Pan2.ar(SinOsc.ar(u + 1 * freq, 0, amp * env), pan));
112 }).add;
113 s.boot;
117 Pdefn(\deg, Pseq([0, 3, 2],inf));
119 Pset(\instrument, \Pdefhelp,
120         Ppar([
121                 Pbind(\degree, Pdefn(\deg), \pan, -0.8),
122                 Pbind(\degree, Pdefn(\deg), \dur, 1/3, \pan, 0.8)
124 ).play;
127 Pdefn(\deg, Prand([0, 3, [1s, 4]],inf));
129 Pdefn(\deg, Pn(Pshuf([0, 3, 2, 7, 6],2),inf));
132 Pdefn(\deg, Plazy { var pat;
133         pat = [Pshuf([0, 3, 2, 7, 6],2), Pseries(0, 1, 11), Pseries(11, -1, 11)].choose;
134         Pn(pat, inf)
139 subsection::Timing
141 When does the definition change?
143 If quant is set, the update is done at the next beat or whatever is specified:
145 code::
146 Pdefn(\deg).quant = 4;
147 Pdefn(\deg, Pn(Pseries(0, 1, 8),inf));
149 Pdefn(\deg).quant = nil; // activate immediately again
152 Pdefn(\deg, {
153         loop {
154         5.do { |i|
155                 #[1, 3, 4].choose.yield;
156                 #[5, 0, 12].choose.yield;
157                 #[14, 3, 4].choose.do { |j| (i % j).postln.yield };
158         }
159         }
164 subsection::update condition
166 In order to be able to switch to a new pattern under a certain condition, the instance variable strong::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 strong::reset:: message can be used.
168 As counting up (such as emphasis::"every nth event, a swap can happen"::) is a common task, there is a method for this, called strong::count(n)::.
170 code::
171 z = Pbind(\degree, Pdefn(\x, \), \dur, 0.25).play;
172 Pdefn(\x, Pseq((0..5), inf)).condition_({ |val, i| i.postln % 6 == 0 });
173 Pdefn(\x, Pseq((7..0), inf)).condition_({ |val, i| i.postln % 8 == 0 });
176 // the above is equvalent to:
177 Pdefn(\x, Pseq((7..0), inf)).count(8);
180 subsection::Reset
182 code::
183 // reset to change immediately:
184 Pdefn(\x).reset;
186 Pdefn(\x).stop;
189 subsection::Functions as arguments to Pdefn
191 code::
192 Pdefn(\deg, { loop { yield(0.1.rand.round(0.01) + [2, 3, 9].choose) } });
194 // equivalent to:
196 Pdefn(\deg, Proutine { loop { yield(0.1.rand.round(0.01) + [2, 3, 9].choose) } });
198 // this is not exactly true, see below..
201 subsection::The (inner) environment
203 code::
204 // set() creates a local environment that overrides the outer currentEnvironment
206 Pdefn(\z).set(\a, 1, \b, 5);
208 Pdefn(\z, { |e|
209         loop { yield((e.a + e.b) + 0.1.rand.round(0.01)) }
211 ); // [1]
213 t = Pdefn(\z).asStream;
215 t.nextN(3);
218 Pdefn(\z, { |e|
219         //(e.a + e.b) + 0.1.rand.round(0.01) 1
220         Pseq([1, 2, e.a], 1)
224 Pdefn(\z, Pseq([1, 2, 3], 1));
226 e = Pdefn(\z).envir
229 Pdefn(\z).set(\a, 3);
231 t.next;
233 Pdefn(\z).set(\a, Pseq([1, 2, 3], inf));
235 t.reset;
236 t.nextN(3);
238 Pdefn(\z).envir; // post the envir
242 // if you want to keep using the currentEnvironment at the same time,
243 // assign the currentEnvironment to the envir's parent (or proto) field
244 // (this shouldn't be a proxy space of course.)
246 Pdefn(\z).envir.parent = currentEnvironment;
247 ~a = 9;
248 ~b = 10;
250 t.nextN(3);