//  Dynamic Interface Test with Control & SuperCollider
//  Charlie Roberts - Nov. 2011
//  
//  This script creates a variable number of sine oscillators. The frequency of each osc is controlled by a slider on
//  an iOS device generated by an OSC message coming from SuperCollider. The sliders output addresses are
//  s1 ... sn where n is the max number of synths being controlled (and thus the number of sliders). You can
//  change this by changing the ~numberOfSynths global parameter in the first block.
//
//  To use this patch, startup Control on your remote device. Enter your devices ip address into the variable
//  yourIOSDeviceIPAddress and change the port if needed (8080 is the default and should be fine. Set the number of synths you 
//  want by changing the ~numberOfSynths variable.
//  Then:
//  - Start the SC servers
//  - Run the first code block
//  - Run the line that creates the blank interface on the device
//  - Run the second code block
//
//  And at this point you should be up and running with oscillators and sliders controlling their frequency

s.boot;

(
	var yourIOSDeviceIPAddress, yourIOSDeviceOSCReceivePort;
	
	// define number of synths to be created / controlled
	~numberOfSynths = 20;

	// setup OSC Addresses
	yourIOSDeviceIPAddress = "127.0.0.1";
	yourIOSDeviceOSCReceivePort = 8080; // 8080 is the default for Control
		
	n = NetAddr(yourIOSDeviceIPAddress, yourIOSDeviceOSCReceivePort);

	// add a synthdef
	SynthDef(\SineSynth, { arg freq = 110, amp = 0.5;
		var a, z;
		a = SinOsc.ar(freq, mul: amp);
		z = Mix.ar(a);
		Out.ar(0, z) + Out.ar(1, z)
	}).add
)

// create a blank interface on your iOS Device
n.sendMsg("/control/createBlankInterface", "testing", "portrait");
n.sendMsg("/control/pushDestination", "127.0.0.1:57120");

(
	//create synths with associated osc responders and create sliders on remote device
	var sliderSize;
	
	~synthArray = Array.new(~numberOfSynths); // holds our oscillators
	~oscArray   = Array.new(~numberOfSynths); // holds our OSCResponderNodes
	
	sliderSize = 1 / ~numberOfSynths;
	
	for (1, ~numberOfSynths, { 
		arg i;
		~synthArray.add(Synth(\SineSynth));
		~synthArray[i-1].set(\freq, 110 * i, \amp, sliderSize); 
		
		// create and send nasty JSON string populated with variables
		n.sendMsg("/control/addWidget", "{'name':'s" ++ i ++ "', 'type':'Slider', 'bounds':[.0,"++ ((i-1) * sliderSize) ++",.75, " ++ sliderSize ++ "], }");	
			
		~oscArray.add(
			OSCresponderNode(nil, '/s'++i, { arg time, responder, msg;
				~synthArray[i-1].set(\freq, 200 + (msg[1] * 880));
			}).add;
		);
	});
)

s.quit;