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