[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)
})
)