ClusterBasic libray for parallel multicomputer/multiserver usage


Inherits from: Object


The Cluster library is useful to use a synth or family of related synths playing symmetrically in multiple servers/computers.

Usefull for multicomputer spatialization systems.


When returning values the classes give out a ClusterArg, which is then recognized by the other classes as a valid argument to expand. 


The classes implement automatically all methods of Bus, Buffer, Server, Synth, SynthDef, OSCBundle and Group. The arguments supplied can be of two kinds: Either the same arguments one would pass to this classes, or a ClusterArg.


A ClusterArg should be used when one wants to send different values to each item of the Cluster class. To do so, one must convert an array into a ClusterArg using .asCluster . E.g. [\freq, [200,400].asCluster]


Other than this everything should work exactly the same as with the original classes. 


Attention: for sample accurate playback this classes use SyncCenter for scheduling, since otherwise the synths would not start at the exact same time on both computers/servers.


//vanilla version (this will work if SyncCenter class is not installed)

//Startup 

(

~server = ClusterServer([

Server("slave1",NetAddr("127.0.0.1", 53177),~options).boot.makeWindow,

Server("slave2",NetAddr("127.0.0.1", 53178),~options).boot.makeWindow]);

~server.boot;

)

SynthDef(\test,{ |out = 0, freq = 400, amp = 0.2| OffsetOut.ar(out,SinOsc.ar(freq)*amp) }).sendCluster(~server);


//basic synth stuff

(

~group = ClusterGroup(~server);

~synth = ClusterSynth(\test,target: ~group)

)


~synth.run(true);

~synth.run(false);

~synth.free


~bus = ClusterBus.audio(~server,1)


~synth.set(\freq,3600)

~synth.set(\freq,[300,2200].asClusterArg,\amp,[0.05,0.1].asClusterArg)

~synth.set(\amp,1)

~synth.setn(\freq,[[600,300].asClusterArg,[0.2,0.1].asClusterArg])

~synth.set(\out,~bus.index) 

~synth.set(\out,0) 

~synth.get(\freq,{ |v| v.value.postln })



//Sample accurate usage. Run this if instead of above if you have SyncCenter installed.

//Startup - 

(

SyncCenter.initClass;

SyncCenter.master = Server("master",NetAddr("127.0.0.1", 53428)).boot.makeWindow;

)

(

~options = ServerOptions.new.numInputBusChannels_(10);

~server = ClusterServer([

Server("slave1",NetAddr("127.0.0.1", 53177),~options).boot.makeWindow,

Server("slave2",NetAddr("127.0.0.1", 53178),~options).boot.makeWindow]);

~server.boot;

~server.addToSyncCenter;

SyncCenter.inBus = 9;

SyncCenter.outBus = 0;

//use jack audio or an adat connection for this.


)


SyncCenter.remoteSync; //run this

SyncCenter.remoteCounts //check values


// USAGE

//send synthdef

SynthDef(\test,{ |out = 0, freq = 400, amp = 0.2| OffsetOut.ar(out,SinOsc.ar(freq)*amp) }).sendCluster(~server);


//basic synth stuff

(

~group = ClusterGroup(~server);

~synth = ClusterSynth(\test,target: ~group)

)


~synth.run(true);

~synth.run(false);

~synth.free


~bus = ClusterBus.audio(~server,1)


~synth.set(\freq,3600)

~synth.set(\freq,[300,2200].asClusterArg,\amp,[0.05,0.1].asClusterArg)

~synth.set(\amp,1)

~synth.setn(\freq,[[600,300].asClusterArg,[0.2,0.1].asClusterArg])

~synth.set(\out,~bus.index) 

~synth.set(\out,0) 

~synth.get(\freq,{ |v| v.value.postln })


//bundling

(

fork{

SynthDef(\test,{ |out = 0, freq = 400, amp = 0.2| OffsetOut.ar(out,SinOsc.ar(freq)*amp) }).sendCluster(~server);

~server.sync;

~group = ClusterGroup.basicNew(~server);

~synth = ClusterSynth.basicNew(\test,~server);

~bundle = ClusterOSCBundle.new(~server);

~bundle.add(~group.newMsg(~server));

~bundle.add(~synth.newMsg(~group));

~bundle.dopost;

if('SyncCenter'.asClass.notNil){

'SyncCenter'.asClass.sendPosClusterBundle(1,~bundle,~server);

}{

~bundle.send(~server)

}

}

)


//sample accurate -> phase cancelation

(

fork{

~synthDef = ClusterSynthDef([\test1,\test2].asClusterArg,2.collect{ |i|

{ |out = 0, bufnum=0, amp = 0.2| OffsetOut.ar(out,PlayBuf.ar(1,bufnum)*if(i==0){amp}{amp.neg} )} }.asClusterArg);

~synthDef.send(~server); 

~buffer = ClusterBuffer.read(~server, "sounds/a11wlk01.wav");

~server.sync;

~synth = ClusterSynth(~synthDef.name,[\bufnum,~buffer,\amp,0.2],~server)

}

)

// you should hear absolute silence if synced !!!!



//clusterfy objects

s.clusterfy

Bus.audio(s,1).clusterfy