// groups, busses and the order of execution

// 2 sound source synthdefs and 2 effects synthdefs:
(
SynthDef("saw", { arg out=0, freq=100, amp=0.3;
	var sig;
	sig = Saw.ar(freq, amp);
	// Out adds (mixes) signals to previous contents on a bus:
	Out.ar(out, sig);
}).store;

SynthDef("noise", { arg out=0, amp=0.3;
	var sig;
	sig = Crackle.ar(1.99, mul: amp);
	Out.ar(out, sig);
}).store;

SynthDef("reson", { arg in=0, out=0;
	var sig;
	// In.ar reads a signal from an audio bus:
	sig = In.ar(in);
	sig = Resonz.ar(sig, LFNoise2.kr(2.6).range(100, 1000), 0.2, 5);
	// ReplaceOut overwrites previous contents on a bus:
	ReplaceOut.ar(out, sig);	
}).store;

SynthDef("chop", { arg in=0, out=0;
	var sig;
	sig = In.ar(in);
	sig = LFPulse.ar(5, mul: sig);
	ReplaceOut.ar(out, sig);	
}).store;
)

~saw = Synth("saw");

// new nodes get placed before the others (by default):
~res = Synth("reson")

// but a node can be moved somewhere else:
~res.moveAfter(~saw)

// nodes can be un/muted:
~res.run(false)
~res.run(true)

~saw.free;  ~res.free;

// this node reads from bus 1 and (over)writes to bus 0:
~chop = Synth("chop", [\in, 1, \out, 0])

// this writes to bus 1:
~noise = Synth("noise", [\out, 1])

// create this node in the right position:
~res = Synth.after(~chop, "reson")
// and set its busses:
~res.set(\in, 1, \out, 1)

// free them all
~chop.free;  ~res.free; ~noise.free;

// two groups to contain synth nodes:
~src = Group(s);
~fx = Group.after(~src);

// these go into the source group:
~saw = Synth("saw", [\out, 1], ~src);
~noise = Synth("noise", target: ~src);

// these are the fx nodes:
~chop = Synth("chop", [\in, 1, \out, 1], ~fx)
~res = Synth("reson", target: ~fx)

// control everything in a group as one:
~fx.run(\false)
~fx.run(\true)

~fx.moveBefore(~src)
~src.moveBefore(~fx)

// remove everything from the server:
s.freeAll