Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Classes / TaskProxy.schelp
bloba9c098cf17eace0d214e33f3883756e109c39e99
1 class:: TaskProxy
2 summary:: event stream reference
3 categories:: Libraries>JITLib>Patterns
4 related:: Classes/Tdef
6 description::
7 Keeps a reference to a task (time pattern) that can be replaced while playing. It plays on when the old stream ended and a new stream is set and schedules the changes to the beat.
9 ClassMethods::
11 method::new
12 create a new instance with a function (the source). the source should be a strong::routine function:: (see link::Classes/Tdef::) or a strong::pattern:: of time values.
14 method::default
15 a default source, if none is given. the default is a loop that does nothing with a 1.0 beat wait time.
17 method::defaultQuant
18 set the default quantization value for the class. (default: 1.0). can be a pair [quant, offset]
20 InstanceMethods::
22 method::source
23 set the source. If a quantization is given, schedule this change to the next beat the object is a strong::routine function::, which is evaluated in a protected way, so that failure will notify the proxy that it has stopped. The object can also be a strong::pattern:: of time values.
25 method::clear
26 set the source to nil
28 method::quant
29 get or set the quantization value. can be a pair [quant, offset]
31 method::condition
32 provide a condition under which the pattern is switched when a new one is inserted. the stream value and a count is passed into the function. the methods strong::count_(n):: simply counts up to n and switches the pattern then
34 method::reset
35 switch the pattern immediately. (stuck conditions can be subverted by this)
37 method::envir
38 provide a default environment for the proxy. If given, it is used as an environment for the routine function. When set for the first time, the routine pattern is rebuilt.
40 method::set
41 set arguments in the environment. If there is none, it is created and the routine pattern is rebuilt.
43 method::endless
44 returns a link::Classes/Proutine:: that plays the proxy endlessly, replacing strong::nil:: with a strong::default:: value (1 s. wait time). This allows to create streams that idle on until a new pattern is inserted.
46 subsection::a) using it as stream reference
48 method::source
49 set the routine function / pattern (internally done by *new(key, obj)
51 method::embedInStream
52 just like any stream, embeds itself in stream
54 subsection::b) using it as EventStreamPlayer
56 method::play
57 starts the TaskProxy and creates a player. if you want to play multiple instances, use strong::.playOnce(clock, protoEvent, quant)::
59 argument::argClock
60 which clock to use. if nil then the TempoClock.default is used.
62 argument::doReset
63 A link::Classes/Boolean::
65 argument::quant
66 can be an array of [quant, phase]
68 method::stop
69 stops the player
71 method::player
72 the current player (if the TaskProxy is simply used in other streams this is nil)
74 method::pause, resume, reset
75 perform player method
77 method::isPlaying
78 returns true if TaskProxy is running. if a TaskProxy is playing and its stream ends, it will schedule a stream for playing as soon as a new one is assigned to it.
80 Examples::
82 subsection::a) using TaskProxy as a player
84 code::
85 // create an empty Tdef and play it.
86 x = TaskProxy.new;
87 x.play;
90 x.source = { loop { "ggggggggggggggggg9999ggg999ggg999gg".scramble.postln; 0.5.wait; } };
93 x.source = { loop { "---------////----------------------".scramble.postln; 0.25.wait; } };
94 x.source = { loop { thisThread.seconds.postln; 1.wait; } };
95 x.source = { loop { thisThread.seconds.postln; 1.01.wait; } };
97 TempoClock.default.tempo = 2;
99 x.source = { "the end".postln };
100 x.source = { "one more".postln };
101 x.source = { 10.do { "ten more".scramble.postln; 0.25.wait; } };
102 x.source = { loop { "many more".scramble.postln; 0.25.wait; } };
104 TempoClock.default.tempo = 1;
106 x.stop;
107 x.play;
108 x.stop;
112 code::
113 // sound example
116 // load a synthdef
117 s.boot;
118 SynthDef("pdef_grainlet",
119         { arg out=0, freq=440, sustain=0.05;
120                 var env;
121                 env = EnvGen.kr(Env.perc(0.01, sustain, 0.3), doneAction:2);
122                 Out.ar(out, SinOsc.ar(freq, 0, env))
123         }).add;
125 x.play;
128 x.source = {
129         loop {
130                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, rrand(600, 640));
131                 0.1.wait;
132         }
137 x.source = {
138         var x;
139         x = Pseries(300, 20, 100).loop.asStream;
140         loop {
141                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
142                 0.05.wait;
143         }
148 x.source = {
149         var x;
150         x = Plazy { Pseries(300 + 300.rand, 10 + 30.rand, 10 + 30.rand) }.loop.asStream;
151         loop {
152                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
153                 0.05.wait;
154         }
158 // metronome
160 y = TaskProxy {
161         loop { s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, 1500); 1.wait; }
163 y.play;
166 // play ending stream once
168 x.source = {
169         var x, dt;
170         dt = [0.1, 0.125, 0.05].choose;
171         x = Plazy { Pseries(1300 + 300.rand, 110 + 130.rand, 16) }.asStream;
172         x.do { arg item;
173                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, item);
174                 dt.wait;
175         }
179 ... and so on ...
181 x.stop;
182 y.stop;
185 subsection::b) embedding TaskProxy into other Tasks / Routines
187 code::
189 #a, c = { TaskProxy.new } ! 2;
190 a.source = { "one".postln; 1.wait; "two".postln };
191 c.source = { var z; z = Synth(\default); 0.5.wait; z.release };
192 r = Task {
193         "counting...".postln;
194         2.wait;
195         a.embedInStream;
196         1.wait;
197         c.embedInStream;
198         "done.".postln;
202 r.play; // play a stream
204 c.source = { var z; z = Synth(\default, [\freq, 300]); 1.5.wait; z.release }; // change the def
206 r.reset;
207 r.play;
209 // of course TaskProxies can be used in other Tdefs:
211 b = TaskProxy.new;
212 b.source = {
213         "counting...".postln;
214         2.wait;
215         a.embedInStream;
216         1.wait;
217         c.embedInStream;
218         "done.".postln;
221 b.playOnce;
223 // if one wants to branch off a stream in a separate thread, asStream is used.
225 Routine {
226         c.asStream.play;
227         0.1.wait;
228         c.asStream.play;
229         0.1.wait;
230         a.asStream.play;
232 }.play;