// Schrittwechsel Controller


(

q = ();


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

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

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


// the audiochannels to which the block speakers are attached to

q.blockChannels = (

// lightGreen: 1,

// orange: 3,

// red: 4,

yellow: 0,

blue: 2,

green: 5

);

q.personNames = [

\fred, 

// \wilma,

// \barney

];


Server.default = s = Server.internal;

s.boot;



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

q.visualAddr.sendMsg("/test");

//q.visualAddr = NetAddr("192.168.84.14", 12000);

//q.visualAddr = NetAddr("localhost", 57120);


/*

q.visualAddr.sendMsg(\test) // */



// read buffers and send Synths

s.waitForBoot{

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); 

// do not normalize activities

//(dirName != \activity).if{b.normalize}

}

);

}

};


HomeBlock.sendSynth;

BlockPerson.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

}


)


(

// helper vars

var openBufIndices, activityBufIndices;


q.blocks = q.blockChannels.collect{|outChan, color|

openBufIndices = 

((0..5) + (6*HomeBlock.idCounter)).wrap(0, q.buffers.doorOpen.size-1);

activityBufIndices =

((0..5) + (6*HomeBlock.idCounter)).wrap(0, q.buffers.activity.size-1);

HomeBlock(color, 0, q.visualAddr, s,

q.buffers.activity[activityBufIndices], 

q.buffers.doorOpen[openBufIndices], 

q.buffers.doorClose, outChan

);

};



// create persons

q.persons = ();

q.personNames.do{|name, i|

q.persons[name] = BlockPerson(s, q.buffers.footsteps[[0, 2, 4] + (i%2)], q.blocks.asArray[i], q.blocks.asArray[i], q.visualAddr)

};



q.blocks.do{|q| q.activitySynthParams.masterAmp = 1};

//q.blocks.do{|q| q.activitySynthParams.amp = 0.1};

q.persons.do{|p| p.synthParams.masterAmp = 1};



/*

q.blocks.red.getActive


q.blocks.red.getInactive(1)

q.blocks.red.getInactiveImmediatly // force inactivity

*/




(

q.blocks.do{|block|

block.fittingAction = {|block, numPersons|

"active".postln;

};


// choose a person and send it to another block. 

// FIXME: search for a strategy to choose the block 

// FIXME: set duration according to distance 

block.overfullAction = {|block, numPersons, supernumerousPersons|

{

block.getInactive;

1.0.rand.wait;

supernumerousPersons.postln;

supernumerousPersons.do{

//rrand(1, 2.0).wait;

block.persons.choose.transite(block.others.choose, dur: 5, dt: 1);

};

6.wait;

block.getActive;


}.fork

};

block.invisibleAction = {|block|

"% invisible".format(block.color).postln;

};

block.faceChangeAction = {|block, face|

[block.color, face].postln;

block.transitePersonsToNext;

};

block.setActivityParam(\masterAmp, 1)

.setActivityParam(\dampFreq, 600)

.setActivityParam(\amp, 1);


/* block.blockUpdateAction = {|block|

};

*/

block.fUpThresh = 0.11;

}

);


q.god = BlockGod(s, q.blocks, q.persons);

q.god.activityDt = 5;

q.blockAmper = Synth(\masterAmper, target: 1, addAction: \addAfter);

)




/*

q.blocks.orange.upFace 

q.blocks.orange.faceStates.selectIndex{|v| v > q.blocks.orange.fUpThresh}



*/

/*

q.persons.wilma.transite(q.blocks.lightGreen, 5);

q.persons.barney.transite(q.blocks.lightGreen, 5);

q.persons.fred.transite(q.blocks.lightGreen, 5) // */


//////////////////////

// Start SETO


(

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

q.seto.start;


JITseto.action = {|me|

var block = q.blocks.detect{|block| block.ids.includes(me.id)};

block.notNil.if{

block.faceSeenAs(me);

}

};


(q.blocks.size > 1).if{

q.god.start;

}

/*

JITseto.action = nil; // */

)




///////////////////////

// Midi Mixer


MIDIClient.init;

MIDIIn.connect;


(

MIDIIn.control = {|port, chan, ctlNum, val| 

[chan, ctlNum, val].postln;

(ctlNum == 7).if{ 

(chan == 8).if{ // master fader (right-most) -> master volume

q.blocks.do{|block|

q.god.ampAll(val.linlin(0, 127, 0, 1.5));

}

};


(chan < 8).if{

//q.blocks[q.blockChannels.findKeyForValue(chan)].setActivityParam(\amp, val.linlin(0, 127, -85, 0).dbamp);

q.blockAmper.set("amp%".format(chan), val.linlin(0, 127, 0, 1));

};

};


(ctlNum == 10).if{ // knobs == dampFreq

(chan < 7).if{ 

q.persons.asArray[chan].setParam(\amp, val.linlin(0, 127, 0, 1));

};

(chan == 7).if{ 

q.blocks.do{|b| 

b.setActivityParam(\dampFreq, val.linexp(0, 127, 500, 2000));

};

};

(chan == 8).if{ 

q.persons.do{|p| 

p.setParam(\amp, val.linlin(0, 127, 0, 1));

};

};

};


(ctlNum == 17).if{ // lower button -> mute

(chan == 8).if{ // master (right-most)

q.blocks.do{|block|

q.god.muteAll(val.linlin(0, 127, 0, 1));

}

};


(chan < 8).if{ 

q.blocks[q.blockChannels.findKeyForValue(chan)].setActivityParam(\mute, val.linlin(0, 127, 0, 1));

};

};

}

)