/* A recommended setup for the WFS system at TU Berlin:


* Use a SharedServer with 42 channels I/O;

* split for e.g. 8 users, such that each user gets 5 private chans

* these chans can be panned freely with Wonder via OSC, 

* or thru Florian's SWonder SC class.

*/

(

q = q ? ();


q.myClientID = 0; // CHANGE FOR YOURS!!

q.numPlayers = 8; // agree on a maximum number

// prepare a shared server: 

q.options = SharedServerOptions.new

.numAudioBusChannels_(1024)

.numInputBusChannels_(8)

.numOutputBusChannels_(42);


q.numChans = q.options.numOutputBusChannels;

q.wfs = SharedServer(\wfs, NetAddr("192.168.3.111", 57110), q.options, q.myClientID);

Server.default = s = q.wfs;


CmdPeriod.add({ q.wfs.freeAll }); // frees only my own nodes, not all of them

q.wfs.initTree;

q.wfs.numClients_(q.numPlayers);

"I can play on chans: %\n".postf(q.wfs.myOuts);



// the panning software address at TU is: 

q.wfsCtl = NetAddr("192.168.3.254", 58100);

w = q.wfsCtl;


// try { q.wfsWin.close };

q.wfsWin = Window("WFS server", Rect(0,800,305, 130)).userCanClose_(false).front;

q.wfsWin.addFlowLayout;


Button(q.wfsWin, Rect(0,0, 145, 50))

.states_([["EMERGENCY ONLY \n    - FREE ALL!", Color.white, Color.red]])

.action_({ q.wfs.freeAll(true); });


Button(q.wfsWin, Rect(0,150, 145, 50))

.states_([["Free All \nMy Sounds.", Color.white, Color.green]])

.action_({ q.wfs.freeAll });


q.wfs.makeGui(q.wfsWin);

)



// a simple test sound, playing to s.myOuts, channel 0

x.free; x = { Ringz.ar(Dust.ar([30, 20, 10]), [600, 1800, 7200], 0.04).sum * 0.5 }.play(s, s.myOuts[0]);


//

x.free; x = { Ringz.ar(Dust.ar([30, 20, 10]), [600, 1800, 7200], 0.04).sum * 0.1 }.play(s, s.myOuts[1]);



// ch, x, y, fadeDur

//     0, 0 is center;

w.sendMsg("/WONDER/source/position", s.myOuts[0], 0, -0.2);

w.sendMsg("/WONDER/source/position", s.myOuts[0], 7, -0.2);

w.sendMsg("/WONDER/source/position", s.myOuts[0], -7, -0.2);


w.sendMsg("/WONDER/source/position", s.myOuts[0], 7, -0.2, 5);

w.sendMsg("/WONDER/source/position", s.myOuts[0], -7, -0.2, 5);




// Florians Wonderful SWonder class: 

a = SWonder( NetAddr("192.168.3.254", 58100)); // creating an instance of SWonder

a.connect // connect it to cwonder

a.drawGUI_(true)

a.sourcePosition(s.myOuts[1], 0.8@0.5) // put source 0 in the center of the room

a.sourcePosition(0, 0@0.5) // move it half way to the front

a.addSource(1, 0.5@0.2) // add a source directly to a specified position

a.sourcePlane(1, true) // add a plane wave source

a.sourceAngle(1, 360.rand) // set it's angle

a.sourceName(1, "new name") // rename it

a.sourceColor(1, Color.rand) // different color

a.removeSource(1) // remove it

a.addNextSource

a.sources.collect(_.position)

a.addNextSource(0.1 @ 0.7)

a.free;


// randomly move evrything:

a.sources.do { |src, i| a.sourcePosition(i, 1.0.rand2 @ 1.0.rand2, exprand(0.3, 3)) };





// jumping to a new position produces bad glitches

(

Tdef(\randPan, {

inf.do { 

var dur = exprand(1.0, 10.0);

var x = 30.0.bilinrand;

var y = 50.0.bilinrand;

w.sendMsg("/WONDER/source/position", s.myOuts[1], *[x, y]);

dur.wait;

}

}).play;

)


// can also smoothly move there

(

Tdef(\randPan1, {

inf.do { 

var dur = exprand(1.0, 10.0);

var x = 30.0.bilinrand;

var y = 50.0.bilinrand;

w.sendMsg("/WONDER/source/position", s.myOuts[2], *[x, y, dur]);

dur.wait;

}

}).play;

)



Tdef(\randPan).stop;

Tdef(\randPan1).stop;



x.free; x = { SinOsc.ar(100) * 0.1 }.play(s, s.myOuts[2]);


// xy pendulum - lissajou figures

(

Tdef(\pendulum, { 

inf.do { |i| 

var xpos = (i * 0.02).sin * 7;

var ypos = (i * 0.022).sin * 12 + 12;

w.sendMsg("/WONDER/source/position", s.myOuts[2], *[xpos, ypos, 0.02]);

0.02.wait;

};

}).play;

)


(

Tdef(\pendulum2, { 

inf.do { |i| 

var xpos = (i * 0.024).sin * 7;

var ypos = (i * 0.028).sin * 12 + 12;

w.sendMsg("/WONDER/source/position", s.myOuts[2], *[xpos, ypos, 0.02]);

0.02.wait;

};

}).play;

)


(

Tdef(\pendulum3, { 

inf.do { |i| 

var xpos = (i * 0.027).sin * 7;

var ypos = (i * 0.029).sin * 12 + 12;

w.sendMsg("/WONDER/source/position", s.myOuts[3], *[xpos, ypos, 0.02]);

0.02.wait;

};

}).play;

)


// x, y, 0/0 is center front;

// x, y, 0/0 is center;

w.sendMsg("/WONDER/source/position", s.myOuts[0], 0, 0);

w.sendMsg("/WONDER/source/position", s.myOuts[0], 7, 0);   // right

w.sendMsg("/WONDER/source/position", s.myOuts[0], -7, 0);  // left


w.sendMsg("/WONDER/source/position", s.myOuts[0], 0, 0);   // center front

w.sendMsg("/WONDER/source/position", s.myOuts[0], 7, 25);  // right back

w.sendMsg("/WONDER/source/position", s.myOuts[0], -7, 25); // left back


// EMERGENCY:

q.wfs.freeAll; // kill your own sounds

q.wfs.freeAll(true); // kill everything on the server.