///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// 3. Functions
// Control your tasks easily
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// It would be nice to determine the above value from outside the task
// for this we need to make our own function
// it's exactly the same, but the task is wrapped up in the function
// and we utilise the function by asking for its value:
// ~myFunction.value;
// note the task (a) is still operating and if we want to stop the task we still need to refer to it as 'a'.
///////////////////////////////////////////////////

// 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);
)

(
~myFunction = ({
	a = Task({
		10.do({ arg count;
			var length = 0.1;
			
			Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, length ]);
			count.postln;
			length.wait;
		});
	}).play;
});
)

~myFunction.value;

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

///////////////////////////////////////////////////
// now we can make our own arguments
///////////////////////////////////////////////////

(
~myFunction = ({ arg length=0.1; // here's the argument, with a default value
	a = Task({
		inf.do({ arg count;
			// we don't need a var anymore as we have an arg
			Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, length ]);
			count.postln;
			length.wait;
		});
	}).play;
});
)

~myFunction.value(0.3);

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

///////////////////////////////////////////////////
// note that setting the argument length to zero will crash SC
// now you can use a combined command to alter value as we're going
///////////////////////////////////////////////////

(
~myFunction = ({ arg length=0.1; // here's the argument, with a default value
	a = Task({
		inf.do({ arg count;
			// we don't need a var anymore as we have an arg
			Synth( "simple", [ \freq, ( 800.rand + 400 ), \dur, length ]);
			count.postln;
			length.wait;
		});
	}).play;
});
)

~myFunction.value(0.3);

(
a.stop;
~myFunction.value(0.2);
)

// or

a.stop; ~myFunction.value(0.2.rand);

///////////////////////////////////////////////////
// now the function has a life of it's own, and we can use it in another task!
///////////////////////////////////////////////////

(
	b = Task({
		10.do({ arg count;
			a.stop; ~myFunction.value(0.2.rand);
			[ "b = " ++ count ].postln; // so we know where we are with the second loop
			2.wait;
		});
		a.stop; // without this the last 'a' won't stop
	}).play;
);

// remember stopping b won't stop as well, so
b.stop; 
b.stop; a.stop;
b.reset; b.play;

// now make a function to control b?