24. TaskProxy

TaskProxy event stream reference

superclass: PatternProxy

TaskProxy는 task(time pattern)의 reference를 저장하는 공간이며, play되는 동안 다른 값으로 대체가 가능합니다.
하나의 stream이 끝나고 새로운 schedule의 beat이 변경될때(즉 count의 변화등) 유용하게 사용됩니다.



 *new(source)
  새로운 function을 가진 instance를 만듭니다. 그 소스는 routine function(Tdef참고) 또는 시간값을 가진 pattern이어야 합니다.
 
 
 *default
  아무것도 주어지지 않으면 default는 아무것도 하지않고 0.1의 wait time을 가진 loop입니다.
   
 source_(obj)
  source를 설정합니다. 만약 quantization이 주어지면 이 변화를 다음 beat으로 schedule합니다.
  object 는 routine function으로 안전한 방법으로 계산하는데 그렇기 때문에 만약 proxy가 멈출 경우 그것을 알려줍니다. object 는 time 값을 가진 pattern 이 주어져야 합니다.

 clear source를 nil로 설정.
 
 quant_(beats)
  quantization value로 설정. [quant, offset]의 pair로 설정 가능.
 
 quant
  quantization value를 받음
 
 *defaultQuant_(beats)
  default quantization value는 1.0, [quant, offset]의 pair로 설정 가능.
 
 condition_(func)
  새로운 pattern이 켜지면 새로운 condition을 제공합니다. stream 값과 count 가 그function에 적용됩니다. .
  methods count_(n)은 단순하게 n까지 count하고 그다음 pattern을 켜줍니다.
 
 reset  
  pattern을 reset시켜줍니다.
   
 envir_(event)
  proxy를 위해 default environment 를 제공합니다.
  주어진 다음 routine function을 위한 environment 로 사용됩니다. 
  맨 처음 주어졌을때는 routine pattern이 재 생성 됩니다.
 
 set(key, val, key2, val2, …)
  environment에 arguments를 설정.
  아무값이 주어지지 않으면 이것이 생성되고 routine pattern이 재 생성 됩니다.
 
 endless
  Proutine를 출력하고 그것이 이 proxy를 지속적으로 실행하도록 합니다. 이는 nil을 default(1 s. wait time)로 전환하기 때문입니다. 
  이것은 또한 stream을 만들어 새로운 pattern이 삽입될때까지 기다리도록 해 줍니다.
  

   

a) stream reference로 사용하기 
 
 source_ 
  routine function / pattern을 설정 (내부적으로 *new(key, obj)에 의해 만들어짐)
   
 
 embedInStream(inval)
  어느stream과 마찬가지로 그 자신을 stream상에 놓이도록 합니다. 
 
 
 
b) EventStreamPlayer로 사용하기

 play(clock, protoEvent, quant)
  TaskProxy를 만들어서 player를 생성합니다.
  만약 여러개의 instances를 play하고 싶다면 .playOnce(clock, protoEvent, quant)를 사용합니다.
  quant 는 array로 설정가능합니다.-> [quant, phase]
   
 stop
  stop
 
 player 
  현재 player (만약 TaskProxy가 단순히 다른 stream들에서 사용되면 이 값은 nil)

 pause / resume / reset / mute / unmute
  perform player method 
   
 isPlaying 
  만약 TaskProxy 가 진행되고 있으면 true값을 줍니다. 
  만약 TaskProxy 는 진행되고 그 stream이 끝나면 새로운 stream이 주어졌을때 바로 시작될 수 있도록 stream을 schedule해줍니다.
  
 




a) TaskProxy를 player로 사용하기


// 자. 앞에서 배운 Tdef와 비교하여 보세요.
x = TaskProxy.new;//이것은 없었던것이죠? x 에 새로운 TaskProxy설정해줍니다.
x.play; 


x.source = { loop { “ggggggggggggggggg9999ggg999ggg999gg”.scramble.postln; 0.5.wait; } };


x.source = { loop { “———////———————-“.scramble.postln; 0.25.wait; } };
x.source = { loop { thisThread.seconds.postln; 1.wait; } };
x.source = { loop { thisThread.seconds.postln; 1.01.wait; } };

TempoClock.default.tempo = 2;

x.source = { “the end”.postln };
x.source = { “one more”.postln };
x.source = { loop { “some more”.scramble.postln; 0.25.wait; } };

TempoClock.default.tempo = 1;

x.stop;
x.play;
x.stop;

//Tdef와 별반 다를것이 없죠. Tdef는 사실 이 TaskProxy의 편리한 사용을 위함이기 때문입니다. 


// 소리의 예제

(
// 앞장에서 쓰인 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))
 }).store;
)
x.play;//앞에서 쓰인 x값이 나오죠

(
x.source = { 
 loop {
  s.sendMsg(“/s_new”, “pdef_grainlet”, -1,0,0, freq, rrand(600, 640));
  0.1.wait;
 }
}
)
//자 여기서 x 가 변경되어 쓰입니다. freq가 변하고 있어요.source가 쓰였습니다. 

(
x.source = { 
 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, — 가 사용되었는데 여기서 다른점은 맨 앞에 x를 TaskProxy로 설정한 이후로 그저 x.source만 사용됩니다. 

(
x.source = { 
 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
(
y = TaskProxy { 
 loop { s.sendMsg(“/s_new”, “pdef_grainlet”, -1,0,0, freq, 1500); 1.wait; } 
};
y.play;
)

// play ending stream once
(
x.source = { 
 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 …

x.stop;
y.stop;
//앞장과 같아요~



b)다른 task나 Routine으로 TaskProxy를 embedding하기 

//이것은 앞에 것을 하나로 묶어준 것입니다.
(
#a, c = { TaskProxy.new } ! 2;//a 와 c 를 TaskProxy로 동시에 넣어줍니다. 그러기 위해 쓰인 #를 보세요. 이것을 지운후 실행해보면 에러가 나옵니다. !2도 잊지말아야겠죠.
a.source = { “one”.postln; 1.wait; “two”.postln };
c.source = { var z; z = Synth(default); 0.5.wait; z.release };
r = Task {
 “counting…”.postln;
 2.wait;
 a.embedInStream;
 1.wait;
 c.embedInStream;
 “done.”.postln;
};
)

r.play; // play 

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

r.reset;
r.play;

//TaskProxies는 또한 다른 Tdef에서도 사용할수 있습니다. 
(
b = TaskProxy.new;
b.source = {
 “counting…”.postln;
 2.wait;
 a.embedInStream;//다시 a를 부르고
 1.wait;
 c.embedInStream;//c 도 부르고
 “done.”.postln;
};
)
b.playOnce;

// 만약에 stream을 다른 분리된 곳으로 넣고 싶다면 asStream을 사용합니다.
(
Routine {
 c.asStream.play;
 0.1.wait;
 c.asStream.play;
 0.1.wait;
 a.asStream.play;

}.play;
)

Reference : SC3 메뉴얼


Leave a Comment.

This site uses Akismet to reduce spam. Learn how your comment data is processed.