(
//synthdefs
~stringModelBusArray = 4.collect({Bus.audio(s, 1)});
~sineBusArray = 4.collect({Bus.audio(s, 1)});
/*
~bassBusArray = 1.collect({Bus.audio(s, 1)});
~hdustBusArray = 1.collect({Bus.audio(s, 1)});
~samplerBusArray = 2.collect({Bus.audio(s, 1)});
*/
~sBuf = Buffer.alloc(s, 10, 2);
SynthDef(\string_model, {arg freq, gate = 1, sustain, amp, dur, attack, release = 1, busIndex = 0;
	var trig, exc, sig1, sig2, noHarms;
	noHarms = rrand(20, 40);
	exc = Saw.ar(freq, TRand.ar(0.5, 1, Impulse.ar(freq))) * 0.001 + Dust.ar(10000, 0.01);
	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq),
		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}),
		Array.fill(noHarms, {rrand(1, 2)}) ], exc) * 0.8).softclip;
	//sig1 = HPF.ar(sig1, 300);
	Out.ar(Select.kr(busIndex, ~stringModelBusArray), sig1 * amp * EnvGen.kr(Env.adsr(attack, 0.3, 0.9, release, 0.9, -3), gate, doneAction: 2));
	//Out.ar([0, 1], sig1 * EnvGen.kr(Env.asr(dur, 0.3, 1), gate, doneAction: 2));
}).add;

SynthDef(\sine, {arg freq, gate = 1, sustain, amp, dur, busIndex = 0;
	var sig;
	sig = SinOsc.ar(freq);
	Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.asr(0.3, 0.4, 0.3), gate, timeScale: dur, doneAction: 2));
	//Out.ar(Select.kr(busIndex, ~sineBusArray), sig * EnvGen.kr(Env.sine(dur), gate, doneAction: 2));
}).add;

SynthDef(\mixer, {arg freq, gate = 1, sustain, amp, dur, out;
	var nameSpaces, sigs;

	sigs = [~stringModelBusArray, ~sineBusArray/*, ~bassBusArray, ~hdustBusArray, ~samplerBusArray*/].collect({arg busArray, i;
		var nameSpace, sig;
		nameSpace = ['string', 'sine', 'bass', 'hdust', 'sampler'][i];
		sig = busArray.collect({arg bus, c; In.ar(bus, 1) * NamedControl.kr(\ ++ nameSpace ++ '_volume_' ++ c, 1, 0.1)});
		sig = sig.collect({arg channel, c; Pan2.ar(channel, NamedControl.kr(\ ++ nameSpace ++ '_pan_' ++ c, i / (busArray.size - 1), 0.1) * 2 - 1)});
		sig = sig.collect({arg channel, c; channel * NamedControl.kr(\ ++ nameSpace ++ '_mute_' ++ c, 1, 0.1)});
		sig = Mix.ar(sig) * pow(NamedControl.kr(\ ++ nameSpace ++ '_volume_master', 1, 0.1), 2);
	});

	sigs = Mix.ar(sigs);
	Out.ar(0, sigs)
}).add;

/*
SynthDef(\bass, {
	var switches, drone;
	switches = {|i| Dust.kr(0.1)} ! 9;
	drone = {|i| var harm = pow(2, 2 - (i / 3).trunc), amp = (1 / pow(harm, 2));
		SinOsc.ar(60 * harm + TRand.kr(-3, 3, switches[i]), 0, amp)} ! 9;
	Out.ar(~bassBusArray[0], Mix.new(drone) * 0.2);
}).add;

SynthDef(\sampler, {
	Out.ar(~samplerBusArray, PlayBuf.ar(2, ~sBuf, BufRateScale.kr(~sBuf), doneAction: 2))
}).add;


SynthDef(\hdust, {
	arg gate = 0;
	var hierarchical_dust, low_sine, high_sine, brown_noise, white_noise;
	// this triggers the combinations of sources
	// it is similar to the Supercollider UGen called dust but with a hierarchical structure
	hierarchical_dust = (
		TIRand.kr(0, 1, Impulse.kr(100)) *
		TIRand.kr(0, 1, Impulse.kr(10)) *
		TIRand.kr(0, 1, Impulse.kr(1)) *
		TIRand.kr(0, 1, Impulse.kr(0.1))
	);
	// adjust the multiplier at the end of each line for adjusting levels
	// note with each trigger, each source has a 1 in 3 chance of sounding
	low_sine = SinOsc.ar(76.midicps / 16) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.1;
	high_sine = SinOsc.ar(76.midicps * 8) * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.01;
	brown_noise = BrownNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.025;
	white_noise = WhiteNoise.ar() * (TIRand.kr(0, 2, hierarchical_dust) < 1) * 0.02;
	Out.ar(~hdustBusArray[0],
		((low_sine + high_sine + brown_noise + white_noise) )
	);
}).add;
*/
)


/* old something
(
SynthDef(\test, {arg freq, gate = 1, sustain, amp, dur;
	var trig, exc, sig1, sig2, noHarms, freqFinal, start, end;
	noHarms = 30;
	freq = WhiteNoise.ar * 3 + freq;
	freqFinal = Duty.ar((1/freq), 0, freq);
	trig = Changed.ar(freqFinal);
	start = Demand.ar(trig, 0, Dwhite(-1, -0.75));
	end = Demand.ar(trig, 0, Dwhite(0.75, 1));
	exc = Phasor.ar(trig, (end - start) * freqFinal / SampleRate.ir, start, end, 0) * 0.001 + Dust.ar(10000, 0.01);

	sig1 = (Klank.ar(`[ Array.series(noHarms, freq, freq),
		Array.geom(noHarms, 1, 0.2) + Array.fill(noHarms, {rrand(0.01, 0.03)}),
		Array.fill(noHarms, {rrand(2, 3)}) ], exc) * 0.5).softclip;
	sig1 = HPF.ar(sig1, 300);
	Out.ar([0, 1], sig1 * EnvGen.kr(Env.adsr(0.3, 0.3, 0.9, 0.5, 0.9), gate, doneAction: 2));
}).add;
)
*/