This file is indexed.

/usr/share/SuperCollider/HelpSource/Classes/Tdef.schelp is in supercollider-common 1:3.8.0~repack-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
class:: Tdef
summary:: task reference definition
categories:: Libraries>JITLib>Patterns
related:: Classes/TaskProxy, Classes/Task, Classes/Routine

description::
Tdef 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.

code::
Tdef(key)	//returns the instance
Tdef(key, func)	//defines the task and returns the instance, like Pdef and Ndef.
::

Graphical overview over all current Tdefs: link::Classes/TdefAllGui::. Overview: link::Overviews/JITLib::

subsection::First Example

code::
Tdef(\x, { loop { 0.5.wait; "aaaaaaaaaaaaaazz".scramble.postln } }).play;
Tdef(\x, { loop { 0.125.wait; "aazz".scramble.postln } });
Tdef(\x, { loop { 0.5.wait; (note: 14.rand).play } });
Tdef(\x, { loop { 0.5.wait; (note: 14.rand + [0, 3, 6, 7].keep(4.rand)).play } });
Tdef(\x).stop;
Tdef(\x).play;
Tdef(\x).clear;
::

ClassMethods::

private::initClass

subsection::Creation

method::new
Store the task in a global dictionary under key, replacing its routine function with the new one.

Using strong::*new(key):: you can access the pattern at that key (if none is given, a default task is created)

method::default
Default source, if none is given. The default task has a function that waits in 1.0 beat steps and does nothing.

method::removeAll
Remove all proxies from the global dictionary ( link::#*all:: )

method::clear
Clear all proxies, setting their source to silence.

method::all
Set or return the environment ( link::Classes/IdentityDictionary:: ) that stores all instances.

method::defaultQuant
Set the default quantisation for new instances (default: 1.0). This can be an array [quant, phase, timingOffset, outset]

InstanceMethods::

subsection::Changing the definition / setting the source

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::.

method::quant
Set the quantisation time for beat accurate scheduling.

argument::val
can be an array strong::[quant, phase, timingOffset, outset] ::, or just strong::[quant, phase]:: etc.

method::condition
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.

method::count
Create and update condition that simply counts up to n and switches the pattern then

method::reset
Switch the task immediately (stuck conditions can be subverted by this).

method::envir
Set the environment (an link::Classes/Event::) for the Tdef. strong::It is passed as first argument into the Task function::.

method::set
Set arguments in the default event. If there is none, it is created and the task routine is rebuilt.

method::clear
Set the source to nil

method::endless
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.

subsection::Tdef as stream reference

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.

method::fork
Play an independent task in parallel.

argument::clock
the clock on which to play the forked task

argument::quant
can be an array of [quant, phase, offset], or a link::Classes/Quant:: value.

argument::event
an event to pass into the forked task

method::embed
Pass a value (typically an link::Classes/Event::) into the task function, and embed the Tdef in the stream.

method::embedInStream
just like any pattern, embeds itself in stream

subsection::Tdef as EventStreamPlayer

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::.

method::play
Starts the Tdef and creates a player.

argument::argClock
a clock on which to play the Tdef
argument::doReset
a flag whether to reset the task if already playing
argument::quant
can be an array of [quant, phase, offset] or a link::Classes/Quant:: value.

method::stop
Stops the player

method::player
Return the current player (if the Tdef is simply used in other streams this is nil)

method::pause, resume, reset
Perform this method on the player.

method::isPlaying
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.

Examples::

subsection::Tdef as a Task player

code::
Tdef(\x).play; // create an empty Tdef and play it.

Tdef(\x, { loop({ "ggggggggggggggggg9999ggg999ggg999gg".scramble.postln; 0.5.wait; }) });


Tdef(\x, { loop({ "---------////----------------------".scramble.postln; 0.25.wait; }) });
Tdef(\x, { loop({ thisThread.seconds.postln; 1.wait; }) });
Tdef(\x, { loop({ thisThread.seconds.postln; 1.01.wait; }) });

TempoClock.default.tempo = 2;

Tdef(\x, { "the end".postln });
Tdef(\x, { "one more".postln });
Tdef(\x, { 10.do({ "ten more".scramble.postln; 0.25.wait; }) });
Tdef(\x, { loop({ "lots more".scramble.postln; 0.25.wait; }) });

TempoClock.default.tempo = 1;

Tdef(\x).stop;
Tdef(\x).play;

Tdef(\x).clear;
::

code::
// sound example

(
// load a synthdef
s.boot;
SynthDef(\pdef_grainlet,
	{ arg out=0, freq=440, sustain=0.05;
		var env;
		env = EnvGen.kr(Env.perc(0.01, sustain, 0.3), doneAction:2);
		Out.ar(out, SinOsc.ar(freq, 0, env))
	}).add;
)
Tdef(\x).play;

(
Tdef(\x, {
	loop({
		s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, rrand(600, 640));
		0.1.wait;
	})
})
)

(
Tdef(\x, {
	var x;
	x = Pseries(300, 20, 100).loop.asStream;
	loop({
		s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
		0.05.wait;
	})
})
)

(
Tdef(\x, {
	var x;
	x = Plazy({ Pseries(300 + 300.rand, 10 + 30.rand, 10 + 30.rand) }).loop.asStream;
	loop({
		s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, x.next);
		0.05.wait;
	})
})
)

// metronome
Tdef(\y, { loop({ s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, 1500); 1.wait; }) }).play;

// play ending stream once
(
Tdef(\x, {
	var x, dt;
	dt = [0.1, 0.125, 0.05].choose;
	x = Plazy({ Pseries(1300 + 300.rand, 110 + 130.rand, 16) }).asStream;
	x.do({ arg item;
		s.sendMsg("/s_new", "pdef_grainlet", -1,0,0, \freq, item);
		dt.wait;
	})
})
)

// ... and so on ...

Tdef(\x).stop;
Tdef.removeAll;
::

subsection::Embed and fork: Tdef within other Tasks / Routines

code::
// embed plays tdefs in sequence within a task.
(
Tdef(\a, { "one".postln; 1.wait; "two".postln });
Tdef(\c, { var z; z = Synth(\default); 0.5.wait; z.release });
r = Task({
	"counting...".postln;
	2.wait;
	Tdef(\a).embed;
	1.wait;
	Tdef(\c).embed;
	"done.".postln;
});
)

r.play; // play a stream

Tdef(\c, { var z; z = Synth(\default, [\freq, 300]); 1.5.wait; z.release }); // change the def

r.reset;
r.play;

// of course Tdefs can be used in other Tdefs:
(
Tdef(\a, { 10.do { |i| (" a: " + i).postln; 0.3.wait; } });
Tdef(\b, { 15.do { |i| ("\t\t b: " + i).postln; 0.2.wait; } });
Tdef(\c, { 5.do { |i| ("\t\t\t\t c: " + i).postln; 0.5.wait; } });

Tdef(\d, {
	"embed - sequence.".postln;
	1.wait;
	Tdef(\a).embed;
	1.wait;
	Tdef(\b).embed;
	1.wait;
	Tdef(\c).embed;

	"done.".postln;
});
)
Tdef(\d).play;

// to start a tdef in its own separate thread, thus branching into parallel threads,
// one can use .fork, or .playOnce
(
Tdef(\a, { 10.do { |i| (" a: " + i).postln; 0.3.wait; } });
Tdef(\b, { 15.do { |i| ("\t\t b: " + i).postln; 0.2.wait; } });
Tdef(\c, { 5.do { |i| ("\t\t\t\t c: " + i).postln; 0.5.wait; } });

Tdef(\d, {
	"fork - parallel.".postln;
	1.wait;
	Tdef(\a).fork;
	1.wait;
	Tdef(\b).fork;
	1.wait;
	Tdef(\c).fork;

	"done.".postln;
});
)
::

subsection::Tdef as a time pattern

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.

code::
(
// load a synthdef
s.boot;
SynthDef("pdef_grainlet",
	{ arg out=0, freq=440, sustain=0.05;
		var env;
		env = EnvGen.kr(Env.perc(0.01, sustain, 0.3), doneAction:2);
		Out.ar(out, SinOsc.ar(freq, 0, env))
	}).add;
)



Tdef(\z, Pseq([1, 1, 1, 0.5, 0.5], inf));

(
Pset(\instrument, \pdef_grainlet,
	Ppar([
		Pbind(
			\dur, Tdef(\z),
			\note, Pseq([1, 3, 2, 1, 0], inf),
			\x, Pfunc { TempoClock.default.elapsedBeats.postln } // posts the onset times
		),
		Pbind(
			\dur, 4, // reference beat
			\sustain, 0.1,
			\note, 8
		)
	])
).play(quant:1);
)


Tdef(\z, Prand([1, 1, 0.23, 0.5, 0.5], inf)); // exchange time pattern
Tdef(\z, Pseq([1, 1, 1, 1], inf)); // pattern stays in sync.
Tdef(\z, Pseq([1, 1, 1, 0.5, 0.5], inf)); // but might be in different order.
					// to avoid this, set quant to an appropriate value.
::