///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// 2. Tasks
// Automate doing things with the Simple Sound
///////////////////////////////////////////////////////////////////////////
// Do something ten times with a one second wait between each time.
///////////////////////////////////////////////////////////////////////////
// First, here's the relevant SynthDef (but experiment using your own)

(
SynthDef( "simple", { arg freq = 400, dur = 1.0;
	var out, env;
	env = EnvGen.kr(Env.linen(dur*0.1, dur*0.1, dur*0.8, 0.6), 0.6, doneAction: 2);
	out = SinOsc.ar(freq, 0, env);
	Out.ar(0, out)
	}).send(s);
)

(
Task({
	10.do({
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 1.0 ]);
		1.wait;
	});
}).play;
)

///////////////////////////////////////////////////
// useful to know where we are?
///////////////////////////////////////////////////

(
Task({
	10.do({ arg count;
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 1.0 ]);
		count.postln;
		1.wait;
	});
}).play;
)

///////////////////////////////////////////////////
// now create a named instance
///////////////////////////////////////////////////
(
a = Task({
	10.do({ arg count;
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 1.0 ]);
		count.postln;
		1.wait;
	});
}).play; // you don't have to use .play, unless you want it to play when it is evaluated.
)

///////////////////////////////////////////////////
// now we can stop it and restart it, but notice the differences between the stop and reset:
///////////////////////////////////////////////////
a.stop;
a.play;
a.reset;

// note that if the task is completed (played ten times) you need to reset it before you can play it again, so this is useful
a.reset;a.play;

// now this is nice:
b = a;

// and try this:
b = a.copy;

b.stop;
b.play;
b.reset;

///////////////////////////////////////////////////
// you can make the task infinite
///////////////////////////////////////////////////
(
a = Task({
	inf.do({ arg count;
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 0.6 ]);
		count.postln;
		0.5.wait;
	});
}).play; // you don't have to use .play, unless you want it to play when it is evaluated.
)

///////////////////////////////////////////////////
// but then you have to start and stop things explicitly
///////////////////////////////////////////////////
a.stop;
a.play;
a.reset;

///////////////////////////////////////////////////
// but if you use an infinite loop, you must include a wait value or you will crash SC
// the following WILL crash, so if you want to try it, make sure you've saved anything you want to save.s
///////////////////////////////////////////////////
(
a = Task({
	inf.do({ arg count;
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 1.0 ]);
		count.postln;
		// 1.wait;
	});
}).play; // you don't have to use .play, unless you want it to play when it is evaluated.
)

///////////////////////////////////////////////////
// you can, of course, change the length of the delay:
///////////////////////////////////////////////////
(
a = Task({
	10.do({ arg count;
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, 1.0 ]);
		count.postln;
		0.1.wait;
	});
}).play;
)

a.stop;
a.play;
a.reset;

///////////////////////////////////////////////////
// also, be careful of infinite length tasks as,
// if you evaluate them twice without defining them
// separately, you will lose control of the first instance.
// the only option if this happens is command-.
///////////////////////////////////////////////////

///////////////////////////////////////////////////
// you might want to connect the duration and length
///////////////////////////////////////////////////
(
a = Task({
	10.do({ arg count;
		var length = 0.1;
		
		Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, length ]);
		count.postln;
		length.wait;
	});
}).play;
)

a.stop;
a.play;
a.reset; a.play;