Tdef task reference definition

superclass: TaskProxy

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.

Tdef(key) returns the instance, Tdef(key, pat) defines the pattern and returns the instance, like Pdef and Ndef.

it is very similar to TaskProxy

*new(key, obj)

store the task in a global dictionary under key.

if there is already a Tdef there, replace its task

with the new one.

obj is a function or a pattern of time values.

*new(key)

acess the task at that key (if none is there, a default task is created)

*default

a default source, if none is given. the default is a loop that does nothing with a 1.0 beat wait time

*removeAll remove all proxies

*clear clear all proxies

*all

dict that stores all Tdefs

*all_(envir)

set the global environment

quant_(beats)

set the quantisation time for beat accurate scheduling

can be a pair [timingOffset, quant]

clear set the source to nil

*defaultQuant_(beats)

set the default quantisation for new instances (default: 1.0)

can be a pair [timingOffset, quant]

condition_(func)

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 count_(n) simply counts up to n and switches the pattern then

reset

switch the pattern immediately. (stuck conditions can be subverted by this)

envir_(event)

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.

set(key, val, key2, val2, ...)

set arguments in the environment.

If there is none, it is created and the routine pattern is rebuilt.

endless

returns a Proutine that plays the proxy endlessly, replacing nil with a default

value (1 s. wait time). This allows to create streams that idle on until a new pattern is inserted.

a) using it as stream reference

embed short for embedInStream

embedInStream(inval)

just like any stream, embeds itself in stream.

see example for usage.

b) using it as Task

play(clock, doReset, quant)

starts the Pdef and creates a player.

if you want to play multiple instances, use .playOnce(clock, doReset, quant) quant can be an array of [quant, phase]

stop

stops the task

player

the current task (if the Tdef is simply used in other streams this is nil)

pause / resume / reset / mute / unmute

perform player method

isPlaying

returns true if Tdef is running.

if a Tdef is playing and its stream ends, it will schedule a task for playing

as soon as a new function is assigned to it.

a) using Tdef as a task player

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, { loop({ "some more".scramble.postln; 0.25.wait; }) });

TempoClock.default.tempo = 1;

Tdef(\x).stop;

Tdef(\x).play;

Tdef(\x).clear;

// sound example

(

// load a synthdef

s.boot;

SynthDef("pdef_grainlet",

{ arg out=0, freq=440, dur=0.05;

var env;

env = EnvGen.kr(Env.perc(0.01, dur, 0.3), doneAction:2);

Out.ar(out, SinOsc.ar(freq, 0, env))

}).store;

)

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;

b) embed and fork: Tdef within other Tasks / Routines

(

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(\b, {

"counting...".postln;

2.wait;

Tdef(\a).embed;

1.wait;

Tdef(\c).embed;

"done.".postln;

});

)

Tdef(\b).fork;

// if one wants to branch off a stream in a separate thread, asStream is used.

// also the method playOnce can be used

(

Routine({

Tdef(\c).fork;

0.1.wait;

Tdef(\c).fork;

0.1.wait;

Tdef(\a).fork;

}).play;

)

Tdef as a time pattern

Instead of using a 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.

(

// load a synthdef

s.boot;

SynthDef("pdef_grainlet",

{ arg out=0, freq=440, dur=0.05;

var env;

env = EnvGen.kr(Env.perc(0.01, dur, 0.3), doneAction:2);

Out.ar(out, SinOsc.ar(freq, 0, env))

}).store;

)

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 the quant to a appropriate value.