(
SynthDef(\pad, {
	arg amp = 0.3, freq = 440, octave = 0, gate = 0;
	var sig, osc1, osc2, env, lfo, noise;

	freq = freq * (2 ** octave);

	osc1 = LFSaw.ar(freq + 1.01) * 2;
	osc2 = SawDPW.ar(freq + 0.99) * 3;
	noise = WhiteNoise.ar(2);

	lfo = SinOsc.kr(3.1).range(0.5, 1.5);

	sig = osc1 + osc2;
	sig = RLPF.ar(sig, 800 * lfo);
	// sig = BPF.ar(sig, 40 * lfo, 0.8);

	env = EnvGen.ar(Env.adsr(attackTime: 0.3, decayTime: 0.5, sustainLevel: 0.2, releaseTime: 0.05), gate, doneAction: 2);
	// env = EnvGen.kr(Env.adsr(0.2, 3, 1, 1), gate, doneAction: 2);

	// sig = CombL.ar(sig, 0.2, 0.2, 1.0);
	// sig = DiodeRingMod.ar(sig);

	// sig = sig.blend(GVerb.ar(sig, 299, 4), 0.15);
	// sig = sig.blend(GVerb.ar(sig.sum, 299, 4), 0.15);

	sig = CombL.ar(sig, 0.5, 1/[36.7, 37.3], 1, 0.2);

	// sig = sig.blend(PF.ar(sig, 1500, 0.5), 0.9);

	// Ideas
	// chorusing (through J Concepts arrays), reverb, spatialization, distortion. See: Presence by Basic Channel
	// dub echo
	// band pan -- what was that AFX demo rack effect?
	// multi-band strum

	sig = sig!2 * amp * env;

	Out.ar(0, sig);
}).add;
)

x = Synth(\pad, [\freq, 60.midicps]);


MIDIClient.init;
MIDIIn.connectAll;


(

~notes = Array.newClear(128);

// MIDI

MIDIdef.noteOn(\noteOnTest, {
	arg vel, nn, chan, src;
	// [vel, nn].postln;
	~notes[nn] = Synth.new(
		\pad,
		[
			\freq, nn.midicps,
			\amp, vel.linexp(1,127,0.01,0.3),
			\gate, 1,
			\octave, 0
		]
	);
});

MIDIdef.noteOff(\noteOffTest, {
	arg vel, nn;
	// [vel, nn].postln;
	~notes[nn].set(\gate, 0);
	~notes[nn] = nil;
});
)
