// a simple example, playing sine grains
//to play: double click to the right of the ( and press enter

(

		GrainPicScribble.new;
		
)

// an example with a varying loudness of grains
// we change the default settings object for newly created clouds

(

	var scribble;

		SynthDef( "sinedbGrains", { arg out = 0, pan = 0, highfreq = 2000, lowfreq = 200, 
			grainDur = 0.04, gate = 1, density = 5, hidb = -20, lowdb;

			var dust, env, wfreq, freq, mainEnv, sine, panner, amp, wamp;

			//amp = db.dbamp;
			dust = Dust.kr(density);
			wfreq = Dwhite(lowfreq, highfreq, inf);
			wamp = Dwhite(lowdb.dbamp, hidb.dbamp, inf);
			freq = Demand.kr(dust, 0, wfreq);
			amp = Demand.kr(dust, 0, wamp);
			env = EnvGen.kr(Env.sine(grainDur, amp), dust > 0, doneAction: 0); 
			mainEnv = EnvGen.kr(Env.asr(0.01, 1, 0.01, 1), gate.if(gate, env) , doneAction:2);
			
			sine = SinOsc.ar(freq, 0, env);
			
			panner = Pan2.ar(sine, pan, mainEnv);
			
			Out.ar(out, panner);
			
		}).store;

		scribble = GrainPicScribble.new;
		
	// set the default settings for newly created clouds
	// the settings should be a function which returns an instance of the Conductor class
	// the Conductor object must contain a Pbind
	// the parent cloud is an argument to the function

		scribble.defaultSettings_({arg cloud;
		Conductor.make({ arg cond, pan, density, grainDur;
	  	
		  		var div, frameDur, lowFreq, highFreq, dur, hidb, lowdb, dbslider;
		  	
		  		hidb = CV.new;
		  		lowdb = CV.new;
		  	
			  	hidb.spec_(\db, -20);
			  	lowdb.spec_(\db);
			  	pan.spec_(\pan);
			  	density.sp(10, 0.001, 100);
		  		grainDur.sp(0.01509, 0.001, 1);
	  		
	  			lowFreq = \rest;

	  			// we can add different gui object besides just sliders.
	  			// here is a range slider tied to 2 number boxes
	  			
	  			cond.gui.guis = (
				
					dbRange: [\vrslider, [lowdb, hidb]],
					hiNlow:		[\numerical, lowdb, hidb]

	  			);
	  			
	  			// we'll put the slider and the number boxes together in the last 
	  			// row of the control window
	  			
	  			cond.gui.keys = #[pan, density, grainDur, [dbRange, hiNlow]];
	  		
	  			cond.pattern_(

	  				Pbind(
	  			
	  					\dur, Prout({
	  						cloud.inside.size.do({
	  							dur = cloud.getPixelDur;
	  							dur = dur + dur.sum3rand;
	  							dur.yield;
	  						});
	  					}), 

	  					[\highfreq, \lowfreq, \div], Prout({

	  						var arr, freqRange, loopArr, popped, left;
	  							
							div =1;

	  						left = cloud.boundingRect.left;
	  							
	  						cloud.inside.do({ arg boundArr, count;
	  							arr = cloud.getFreqs(left + count);
	  							highFreq = arr.first;
	  							lowFreq = arr.last;
	  							div = lowFreq.size;
	  							[highFreq, lowFreq, div].yield;
	  						});
	  					}),

	  					\grainDur, grainDur,
	  					\density, Pfunc({arg evt; density.value / evt[\div]}),
	  					\hidb,  hidb,
	  					\lowdb, lowdb,
	  					\pan, pan,
	  					\legato, 2, //1.1,

	  					\instrument, \sinedbGrains
	  				
	  				)
	  			)
	  		});
		});
)

// a more complicated example, using clouds to control filters
//to play: double click to the right of the ( and press enter

(
	var scribble;

		SynthDef( "filts", { arg out = 0, pan = 0, highfreq = 2000, lowfreq = 200, 
			gate = 1, q=0.2, db = -20, dur;

			var noise, env, panner, amp;

			amp = db.dbamp;
			
			noise = WhiteNoise.ar;
			noise = RHPF.ar(noise, lowfreq,q);
			noise = RLPF.ar(noise, highfreq, q);
			
			env = EnvGen.kr(Env.asr(0.01, 1, 0.01, amp, 'sine'), gate, doneAction:2);
			//env = EnvGen.kr(Env.sine(dur, amp), doneAction:2);
			panner = Pan2.ar(noise, pan, env);
			
			Out.ar(out, panner);
			
		}).store;

	scribble = GrainPicScribble.new;

	// set the default settings for newly created clouds
	// the settings should be a function which returns an instance of the Conductor class
	// the Conductor object must contain a Pbind
	// the parent cloud is an argument to the function
	
	scribble.defaultSettings_({arg cloud;
		Conductor.make({ arg cond, db, pan, q;
	  	
		  		var lowFreq, highFreq, dur;
		  	
			  	db.sp(-20, -100, 20);
			  	pan.spec_(\pan);
	  			q.spec_(\rq);
	  		
	  			lowFreq = \rest;

	  			cond.pattern_(

	  				Pbind(

	  					
	  					\dur, Prout({
	  						cloud.inside.size.do({
	  							dur = cloud.getPixelDur;
	  							dur = dur + (dur).sum3rand;
	  							dur.yield;
	  						});
	  					}), 

	  					[\highfreq, \lowfreq], Prout({

	  						var arr, left; 

	  						left = cloud.boundingRect.left;
	  							
	  						cloud.inside.do({ arg boundArr, count;
	  							arr = cloud.getFreqs(left + count);
	  							highFreq = arr.first;
	  							lowFreq = arr.last;
	  							[highFreq, lowFreq].yield;
	  						});
	  					}),

	  					\db,  db,
	  					\pan, pan,
	  					\q, q,
	  				
	  					\legato, 2, 
	  					\in, 2,
	  					
	  					\instrument, \filts

	  				)
	  			);
			});
		});
)