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