clean up indentation and spacing
[supercollider.git] / HelpSource / Classes / Tdef.schelp
blobdded85e725604df96231e0be1e53a23122b04743
1 class:: Tdef
2 summary:: task reference definition
3 categories:: Libraries>JITLib>Patterns
4 related:: Classes/TaskProxy, Classes/Task, Classes/Routine
6 description::
7 Pdefn provides an interface to its superclass TaskProxy. Tdef keeps a reference to a task ( strong::time pattern:: ) that can be replaced while playing. It continues playing when the old stream ended and a new stream is set and schedules the changes to the beat. One Tdef may be used in many tasks in different places. A change in the task definition Tdef propagates through all tasks.
9 code::
10 Tdef(key)       //returns the instance
11 Tdef(key, func) //defines the task and returns the instance, like Pdef and Ndef.
14 Graphical overview over all current Tdefs: link::Classes/TdefAllGui::. Overview: link::Overviews/JITLib::
16 subsection::First Example
18 code::
19 Tdef(\x, { loop { 0.5.wait; "aaaaaaaaaaaaaazz".scramble.postln } }).play;
20 Tdef(\x, { loop { 0.125.wait; "aazz".scramble.postln } });
21 Tdef(\x, { loop { 0.5.wait; (note: 14.rand).play } });
22 Tdef(\x, { loop { 0.5.wait; (note: 14.rand + [0, 3, 6, 7].keep(4.rand)).play } });
23 Tdef(\x).stop;
24 Tdef(\x).play;
25 Tdef(\x).clear;
28 ClassMethods::
30 private::initClass
32 subsection::Creation
34 method::new
35 Store the task in a global dictionary under key, replacing its routine function with the new one.
37 Using strong::*new(key):: you can access the pattern at that key (if none is given, a default task is created)
39 method::default
40 Default source, if none is given. The default task has a function that waits in 1.0 beat steps and does nothing.
42 method::removeAll
43 Remove all proxies from the global dictionary ( link::#*all:: )
45 method::clear
46 Clear all proxies, setting their source to silence.
48 method::all
49 Set or return the environment ( link::Classes/IdentityDictionary:: ) that stores all instances.
51 method::defaultQuant
52 Set the default quantisation for new instances (default: 1.0). This can be an array [quant, phase, timingOffset, outset]
54 InstanceMethods::
56 subsection::Changing the definition / setting the source
58 One Tdef may have many tasks in different places. A change in the task definition Tdef propagates through all tasks. 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::.
60 method::quant
61 Set the quantisation time for beat accurate scheduling.
63 argument::quant
64 can be an array strong::[quant, phase, timingOffset, outset] ::, or just strong::[quant, phase]:: etc.
66 method::condition
67 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.
69 method::count
70 Create and update condition that simply counts up to n and switches the pattern then
72 method::reset
73 Switch the task immediately (stuck conditions can be subverted by this).
75 method::envir
76 Set the environment (an link::Classes/Event::) for the Tdef. strong::It is passed as first argument into the Task function::.
78 method::set
79 Set arguments in the default event. If there is none, it is created and the task routine is rebuilt.
81 method::clear
82 Set the source to nil
84 method::endless
85 Returns a link::Classes/Prout:: that plays the task endlessly, replacing strong::nil:: with a strong::default:: value 1. This allows to create streams that idle on until a new pattern is inserted.
87 subsection::Tdef as stream reference
89 A single Tdef may serve as a definition for multiple tasks. These methods show how to fork off separate routines from one instance. Even if they run in different contexts, their definition may still be changed.
91 method::fork
92 Play an independent task in parallel.
94 argument::quant
95 can be an array of [quant, phase, offset], or a link::Classes/Quant:: value.
97 method::embed
98 Pass a value (typically an link::Classes/Event::) into the task function, and embed the Tdef in the stream.
100 method::embedInStream
101 just like any pattern, embeds itself in stream
103 subsection::Tdef as EventStreamPlayer
105 For live coding, each Tdef also may control one instance that plays one task. This is a link::Classes/PauseStream::, accessible in the instance variable link::#-player::.
107 method::play
108 Starts the Tdef and creates a player.
110 argument::quant
111 can be an array of [quant, phase, offset] or a link::Classes/Quant:: value.
113 method::stop
114 Stops the player
116 method::player
117 Return the current player (if the Tdef is simply used in other streams this is nil)
119 method::pause, resume, reset
120 Perform this method on the player.
122 method::isPlaying
123 Returns true if player is running. If a Tdef 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.
125 Examples::
127 subsection::Tdef as a Task player
129 code::
130 Tdef(\x).play; // create an empty Tdef and play it.
132 Tdef(\x, { loop({ "ggggggggggggggggg9999ggg999ggg999gg".scramble.postln; 0.5.wait; }) });
135 Tdef(\x, { loop({ "---------////----------------------".scramble.postln; 0.25.wait; }) });
136 Tdef(\x, { loop({ thisThread.seconds.postln; 1.wait; }) });
137 Tdef(\x, { loop({ thisThread.seconds.postln; 1.01.wait; }) });
139 TempoClock.default.tempo = 2;
141 Tdef(\x, { "the end".postln });
142 Tdef(\x, { "one more".postln });
143 Tdef(\x, { 10.do({ "ten more".scramble.postln; 0.25.wait; }) });
144 Tdef(\x, { loop({ "lots more".scramble.postln; 0.25.wait; }) });
146 TempoClock.default.tempo = 1;
148 Tdef(\x).stop;
149 Tdef(\x).play;
151 Tdef(\x).clear;
154 code::
155 // sound example
158 // load a synthdef
159 s.boot;
160 SynthDef(\pdef_grainlet,
161         { arg out=0, freq=440, sustain=0.05;
162                 var env;
163                 env = EnvGen.kr(Env.perc(0.01, sustain, 0.3), doneAction:2);
164                 Out.ar(out, SinOsc.ar(freq, 0, env))
165         }).add;
167 Tdef(\x).play;
170 Tdef(\x, {
171         loop({
172                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, rrand(600, 640));
173                 0.1.wait;
174         })
179 Tdef(\x, {
180         var x;
181         x = Pseries(300, 20, 100).loop.asStream;
182         loop({
183                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
184                 0.05.wait;
185         })
190 Tdef(\x, {
191         var x;
192         x = Plazy({ Pseries(300 + 300.rand, 10 + 30.rand, 10 + 30.rand) }).loop.asStream;
193         loop({
194                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
195                 0.05.wait;
196         })
200 // metronome
201 Tdef(\y, { loop({ s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, 1500); 1.wait; }) }).play;
203 // play ending stream once
205 Tdef(\x, {
206         var x, dt;
207         dt = [0.1, 0.125, 0.05].choose;
208         x = Plazy({ Pseries(1300 + 300.rand, 110 + 130.rand, 16) }).asStream;
209         x.do({ arg item;
210                 s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, item);
211                 dt.wait;
212         })
216 // ... and so on ...
218 Tdef(\x).stop;
219 Tdef.removeAll;
222 subsection::Embed and fork: Tdef within other Tasks / Routines
224 code::
225 // embed plays tdefs in sequence within a task.
227 Tdef(\a, { "one".postln; 1.wait; "two".postln });
228 Tdef(\c, { var z; z = Synth(\default); 0.5.wait; z.release });
229 r = Task({
230         "counting...".postln;
231         2.wait;
232         Tdef(\a).embed;
233         1.wait;
234         Tdef(\c).embed;
235         "done.".postln;
239 r.play; // play a stream
241 Tdef(\c, { var z; z = Synth(\default, [\freq, 300]); 1.5.wait; z.release }); // change the def
243 r.reset;
244 r.play;
246 // of course Tdefs can be used in other Tdefs:
248 Tdef(\a, { 10.do { |i| (" a: " + i).postln; 0.3.wait; } });
249 Tdef(\b, { 15.do { |i| ("\t\t b: " + i).postln; 0.2.wait; } });
250 Tdef(\c, { 5.do { |i| ("\t\t\t\t c: " + i).postln; 0.5.wait; } });
252 Tdef(\d, {
253         "embed - sequence.".postln;
254         1.wait;
255         Tdef(\a).embed;
256         1.wait;
257         Tdef(\b).embed;
258         1.wait;
259         Tdef(\c).embed;
261         "done.".postln;
264 Tdef(\d).play;
266 // to start a tdef in its own separate thread, thus branching into parallel threads,
267 // one can use .fork, or .playOnce
269 Tdef(\a, { 10.do { |i| (" a: " + i).postln; 0.3.wait; } });
270 Tdef(\b, { 15.do { |i| ("\t\t b: " + i).postln; 0.2.wait; } });
271 Tdef(\c, { 5.do { |i| ("\t\t\t\t c: " + i).postln; 0.5.wait; } });
273 Tdef(\d, {
274         "fork - parallel.".postln;
275         1.wait;
276         Tdef(\a).fork;
277         1.wait;
278         Tdef(\b).fork;
279         1.wait;
280         Tdef(\c).fork;
282         "done.".postln;
287 subsection::Tdef as a time pattern
289 Instead of using a link::Classes/Pdefn:: for time values, it can be useful to use a Tdef. When changing its source, it keeps the stream of values synchronized to its clock.
291 code::
293 // load a synthdef
294 s.boot;
295 SynthDef("pdef_grainlet",
296         { arg out=0, freq=440, sustain=0.05;
297                 var env;
298                 env = EnvGen.kr(Env.perc(0.01, sustain, 0.3), doneAction:2);
299                 Out.ar(out, SinOsc.ar(freq, 0, env))
300         }).add;
305 Tdef(\z, Pseq([1, 1, 1, 0.5, 0.5], inf));
308 Pset(\instrument, \pdef_grainlet,
309         Ppar([
310                 Pbind(
311                         \dur, Tdef(\z),
312                         \note, Pseq([1, 3, 2, 1, 0], inf),
313                         \x, Pfunc { TempoClock.default.elapsedBeats.postln } // posts the onset times
314                 ),
315                 Pbind(
316                         \dur, 4, // reference beat
317                         \sustain, 0.1,
318                         \note, 8
319                 )
320         ])
321 ).play(quant:1);
325 Tdef(\z, Prand([1, 1, 0.23, 0.5, 0.5], inf)); // exchange time pattern
326 Tdef(\z, Pseq([1, 1, 1, 1], inf)); // pattern stays in sync.
327 Tdef(\z, Pseq([1, 1, 1, 0.5, 0.5], inf)); // but might be in different order.
328                                         // to avoid this, set quant to an appropriate value.