(
Server.default = s = Server.internal;
s.boot;

q = ();

q.directory = "/localvol/sound/share/audiosamples/koelnKalk";
q.subDirs = [\footsteps, \doorClose, \doorOpen];

q.subDirs = (footsteps: 6, doorClose: 4, doorOpen: 4);
)

(
q.buffers = q.subDirs.collect{|num, dirName|
	num.collect{|i|
		Buffer.readChannel(s, "%/%/%.aiff".format(q.directory, dirName, i+1), channels: [0], action:{|b| "file %/%.aiff read.\n".postf(dirName, i+1);  b.normalize});
	}
};
)

q.channels = (0..5);

(
SynthDef(\wanderer, {arg 
		stepBufnum = 0, openBufnum, closeBufnum,
		startChan = 0, finishChan = 1, dur = 5, rate=1, inter=4;
	var steps, pannedSteps, open, close;
	var openLength, closeLength, minDur;

	
	openLength = BufSampleRate.kr(openBufnum).reciprocal * BufFrames.ir(openBufnum);
	closeLength = BufSampleRate.kr(closeBufnum).reciprocal * BufFrames.ir(closeBufnum);

	// minimal operation time (open and close doors)
	minDur = openLength + closeLength + dur;
	//minDur.poll;
	open = BufRd.ar(
		1,
		openBufnum, 
		EnvGen.ar(Env([0, BufFrames.ir(openBufnum), 0], [openLength, 0]), gate: Impulse.ar(0)), 
		0, // no loop 
		inter
	);
	
	steps = BufRd.ar(
		1,
		stepBufnum, 
		EnvGen.ar(Env([0, 0, BufFrames.ir(stepBufnum), 0], [openLength * 0.9, BufSampleRate.kr(stepBufnum).reciprocal * BufFrames.ir(stepBufnum), 0]), gate: Impulse.ar(0)), 
		0, // no loop 
		inter
	) * EnvGen.ar(Env.linen(0, minDur - closeLength, 0));
	
	pannedSteps = Pan2.ar(steps, 
		EnvGen.ar(Env([-1, -1, 1], [openLength * 0.9, minDur - closeLength]))
	);

	close = BufRd.ar(
		1,
		closeBufnum, 
		EnvGen.ar(Env([0, 0, BufFrames.ir(closeBufnum), 0], [minDur - closeLength, closeLength, 0]), gate: Impulse.ar(0), doneAction: 2), 
		0, // no loop 
		inter
	);

	Out.ar(startChan, open + pannedSteps[0]);
	Out.ar(finishChan, close + pannedSteps[1]);
	
}).memStore;
)

(
Synth.grain(\wanderer, [
	\openBufnum, q.buffers[\doorOpen].choose.bufnum, 
	\closeBufnum, q.buffers[\doorClose].choose.bufnum, 
	\stepBufnum, q.buffers[\footsteps].choose.bufnum, 
	\dur, 10
])
)