[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-users] little class for plotting multiple envelopes



You can get editing aswell with stacked views with a envelopeview ontop
This is a 1st draft, thought you might be interested though.

(
	var w,ev,bounds;
	var envelopes,views;
	var randomEnv,plotEnv;
	var n = 10,indexInfo;
	var getEnvIndexAndBreakpoint;
	
	w = SCWindow("",Rect(100,100,620,400)).front;
	
	bounds = Rect(10,10,600,150);
	
	randomEnv = { |n=8,lo=0,hi=1|
		Env(
			{ rrand(lo.asFloat,hi.asFloat) }!n,
			normalizeSum({ 1.0.rand }!(n - 1)),
			{ [ \lin,\sin,\welch,6.0.rand2].choose }!(n - 1)
		)
	};
	
	plotEnv =  { |env,ms|
		var n = 300, t = env.times.sum, step = t / n;
		var array = env.prAsArray;
		ms.value = { |i| array.envAt(step*i) }!n
	};
	
	envelopes = { randomEnv.(10.rand+2) }!n;
	
	views = { SCMultiSliderView(w,bounds).thumbSize_(1).valueThumbSize_(0)
		.drawLines_(true).drawRects_(false).strokeColor_(Color.blue) }!n;
	
	
	ev = SCEnvelopeView(w,bounds).thumbSize_(4);
	ev.backColor = Color.white;
	
	getEnvIndexAndBreakpoint = { |index|
		var counter = 0, i =0, next = indexInfo.first;
		while ( { counter + next <= index},{
			counter = counter + next;
			next = indexInfo[i = i + 1];
		});
		[i.asInt,asInt(index-counter),counter,next] // index,breakpoint,offset,length
	};
	
	indexInfo = Array.new;
	ev.value = [
		envelopes.collect({ |env,i|
			indexInfo = indexInfo.grow(1).add(env.levels.size);
			integrate([0.0]++env.times).asFloat
		}).flat,
		envelopes.collect({ |env| env.levels.asFloat }).flat,
	];
	
	ev.action = { |v|
		var index,break,os,len,env,times;
		
		#index,break,os,len = getEnvIndexAndBreakpoint.(v.index);
		
		env = envelopes[index];
		
		times = v.value[0][os..os+len-1];
		times[0] =0.0;
		times[len-1] =1.0;
		times = sort(times);
		
		env.times = times[1..].differentiate;
		env.levels[break] = v.value[1][os+break];
		envelopes[index] = env;
		plotEnv.(env,views[index]);
		
		
		if(os != 0,{
			times = v.value[0][0..os-1] ++ times
		});
		times = times ++ v.value[0][os+len..];
		
		v.value = [
			times,
			v.value[1]
		];
		
	};
		
	views.do({ |v,i|
		plotEnv.(envelopes[i],v)
	})

)