// jedem Würfel ist eine Geraeuschfamilie zugeordnet

(
Server.default = s = Server.internal;

s.waitForBoot{
q = ();

// joseph
// q.directory = "/Network/Servers/stitch/srv/nfs/volume1/home/till/samples/";

// till
// q.directory = "/localvol/sound/share/audiosamples/koelnKalk/sequencer/";

// hubert
q.directory = "/Users/till/Documents/koelnKalk/sequencer/";

/* open directory
"open %".format(q.directory).unixCmd; // */

// For each name given below, q.directory should have a directory containing files named 1-*.aiff, 2-*.aiff, etc. 
// If the files are n-channel, currently only the first channel is used.
// be sure to have only .aiff files here. Neither wav, nor mp3 are supported yet. If you need to convert files easily, use e.g. Max (http://sbooth.org/Max/), or sndfile-convert.

// Link directory names to colors. Only given colores will be recognized, all other blocks are ignored.
q.colorToName = (
	lightGreen: \sn,
	red: \bass, 
	blue: \chords, 
	yellow: \hh,
	orange: \synth,
	green: \bd
);

// the audiochannels to which the block speakers are attached to
q.blockChannels = (
	yellow:		0,
	lightGreen:	1,
	blue:		2,
	orange:		3,
	red:			4,
	green:		5
);

/*q.blockChannels = (
	yellow:		7,
	lightGreen:	7,
	blue:		7,
	orange:		7,
	red:			7,
	green:		7
);
*/

q.visualsAddr = NetAddr("localhost", 12000);

q.filenames = ();
q.colorToName.keysValuesDo{|color, subdirname|
	q.filenames[color] = 6.collect{|i|
		"%/%.aif".format(subdirname, i+1);
	}
};

/*
q.filenames.printAll // */

q.buffers = q.filenames.collect{|blockfiles|
	blockfiles.collect{|name|
		Buffer.readChannel(s, q.directory ++ name, channels: [0], action:{"file % read.\n".postf(name) })
//		Buffer.read(s, q.directory ++ name, action:{"file % read.\n".postf(name) })
	}
};

// only first channel of the file is read 

/* test
q.buffers.choose.choose.play 

q.sfile = SoundFile.openRead(q.directory ++ q.filenames[\green][6]);

q.sfile.numChannels
q.sfile.close;

// */

}
)

(
q.blocks = q.colorToName.collect{|v, color| BufferBlock(color, 0, q.visualsAddr, q.buffers[color], q.blockChannels[color])};
BufferBlock.sendSynth;
SynthDef(\masterAmper, {|out = 0|
	var amps = [
		\amp0.kr(1, 0.1),
		\amp1.kr(1, 0.1),
		\amp2.kr(1, 0.1),
		\amp3.kr(1, 0.1),
		\amp4.kr(1, 0.1),
		\amp5.kr(1, 0.1),
		\amp6.kr(1, 0.1)
	];
	
	ReplaceOut.ar(out, In.ar(out, 7) * amps);
}).memStore;

q.buffers.asArray.flatten.do{_.normalize};
)

(
s.bind{
	BufferBlock.startClock;
	q.blockAmper = Synth(\masterAmper, target: 1, addAction: \addAfter);
	q.blocks.do(_.play);
}
)

//////////////////////
// Start SETO

(
q.seto = SETO_OSCTUIOServer("2Dobj", nil, JITseto, SETOIDistance); 
q.seto.start;

/*
Tdef(\player, {loop{
	0.03.wait;
	// bd
//	q.blocks.green.setFace(126, \amps, 1);q.blocks.green.setFace(126, \filterFreqs, 260000);

//	q.blocks.blue.setFace(180, \amps, 1);q.blocks.blue.setFace(180, \filterFreqs, 260000);
//	q.blocks.red.setFace(108, \amps, 1);q.blocks.red.setFace(108, \filterFreqs, 260000);
//	q.blocks.lightGreen.setFace(144, \amps, 1);q.blocks.lightGreen.setFace(144, \filterFreqs, 260000);
//	q.blocks.orange.setFace(162, \amps, 1);q.blocks.orange.setFace(162, \filterFreqs, 260000);
//	q.blocks.yellow.setFace(198, \amps, 1);q.blocks.yellow.setFace(198, \filterFreqs, 260000);
}}).play;
*/

JITseto.action = {|me|
	var block = q.blocks.detect{|block| block.ids.includes(me.id)};
	block.notNil.if{
		//block.color.postln;
		//block.setFace(me.id, \amps, ((sin(me.rotEuler.first) * 0.95).abs + 0.05));
		block.faceSeenAs(me);
		block.setFace(me.id, \amps, me.pos.first.linlin(0, 1, 1, 1));
		block.setFace(me.id, \filterFreqs, sin(me.rotEuler.first*0.5).abs.linexp(0, 1, 1500, 260000));
		//block.setFace(me.id, \amps, 0.9)
	}
};

/*
JITseto.action = nil; // */
//JITseto.action = {|me| me.postln}; // */
)

(
s.bind{
q.blocks.do(_.stop);
}
)

q.blocks.do{|block|
	block.set(\amp, 1);
	//block.out = 0
};

///////////////////////
// Midi Mixer

MIDIClient.init;
MIDIIn.connect;

(
MIDIIn.control = {|port, chan, ctlNum, val| 
	[chan, ctlNum, val].postln;
	
	(ctlNum == 7).if{ // fader
		(chan == 8).if{ // master (right-most)
			q.blocks.do{|block|
				block.set(\masterAmp, val.linlin(0, 127, 0, 1))	
			}
		};

		(chan < 8).if{ // red (left-most)
			[chan, val].postln;
			q.blocks[q.blockChannels.findKeyForValue(chan)].set(\amp, val.linlin(0, 127, 0, 1))	
		};
	};
	
	(ctlNum == 17).if{ // lower button -> mute
		(chan == 8).if{ // master (right-most)
			q.blocks.do{|block|
				block.set(\masterMute, val.linlin(0, 127, 0, 1))	
			}
		};

		(chan < 8).if{ // red (1- rightmost)
			q.blocks[q.blockChannels.findKeyForValue(chan)].set(\mute, val.linlin(0, 127, 0, 1))	
		};
	};
	
	(ctlNum == 10).if{ // knob
		(chan == 8).if{ // global rate -> master (right-most)
			BufferBlock.phase.set(\rate, val.linlin(0, 127, 0.5, 2).round(0.01).postln)
		};
		(chan < 8).if{ // amps
			q.blockAmper.set("amp%".format(chan), val.linlin(0, 127, 0, 1));
		};

	};
}
)

q.blocks.do{|block|
	block.synthParams.add(\masterMute -> [0]);
	block.synthParams.add(\mute -> [0]);
}

q.blocks[3].play
q.blocks[3].out = 0

q.blocks[3].stop

q.blocks.do{|block|
	block.set(\amps, 3);
}

q.blocks.do{|block|
	block.stop;
}

q.blocks[3].play
q.blocks[3].out = 0
q.blocks[3].stop

q.blocks[1].set(side: 2, what: \rates, val: 0.5);

6.do{|i|
	q.blocks[1].set(side: i, what: \amps, val: 0.5);
}

6.do{|i|
	q.blocks[1].set(side: i, what: \rates, val: rrand(0.5, 2.0));
}

6.do{|i|
	q.blocks[0].set(side: i, what: \rates, val: rrand(1, 4.0));
}

x.setn(\amps, [1, 0, 0, 0, 0, 0])
x.setn(\amps, [0, 0, 1, 0, 0, 0])
x.setn(\amps, 1!6)

x.setn(\amps, [10, 0, 0, 0, 0, 0, 0])

x.setn(\amps, [1, 1, 1, 1, 1, 1, 1])