A Tiny Little White One
2006-10-13 15:19
supercollider
This chunk of SuperCollider code will create a tiny but not so well behaved audiovisual creature.
(I must admit I stole the title from a.berthling's album on mitek)

/*a tiny little white one /redFrik 061009*/
/*
GUI.cocoa;
GUI.swing;
*/
(
s.waitForBoot{
n= 25; /*number of arms*/
b= {Buffer.alloc(s, 32, 1)}.dup(n); /*length must be power of 2*/
SynthDef(\wormsnd, {|out= 0, bufnum, freq= 60, amp= 0.01, pan= 0|
Out.ar(out, Pan2.ar(OscN.ar(bufnum, freq, 0, amp), pan));
}).send(s);
})
(
var width= 300, height= 300, freqSpread= 100.rrand(1000).postln, muckProb= 0.0008,
muck= 0, i= 0, j= 0, shapes, synths, pnt, w, u, freq,
centerX= width/2, centerY= height/2, o= 0.1, frict= 1, lfo= 1, lfoSpeed= 0;
w= Window("a tiny little white one", Rect(128, 64, width, height), false);
u= UserView(w, Rect(0, 0, width, height));
u.background= Color.black;
w.onClose_({synths.do{|x| x.free}});
CmdPeriod.doOnce({w.close});
w.front;
shapes= {|x| {1.0.rand}.dup(b[x].numFrames)}.dup(n); /*init shapes*/
synths= {|x| Synth(\wormsnd, [\bufnum, b[x].bufnum, \pan, x/(n-1)*2-1])}.dup(n);
u.drawFunc= {
shapes.do{|shape, x| /*iterate shapes, x is index*/
var dist;
if((muckProb*0.1).coin, {muck= 4.rand});
if(muck>0, {
([
{pnt= Point(x/n*10, x/n*10)},
{pnt= Point(x/n* -10, x/n*10); if(muckProb.coin {muck= 0})},
{pnt= Point(x.rand2, x.rand2); if(muckProb.coin {muck= 0})}
][muck-1]).value;
if(i%2000==0, {muck= 0});
}, {
pnt= Point(0, 0)
});
lfo= (lfo+lfoSpeed).fold(0.05, 1);
i= i+1;
j= (j+10.rand2).fold(0, shape.size-1);
shape.put(j, (shape[j]+o).fold(0.01, 1));
if(muckProb.coin, {
o= [0.15.rand2, -1, 1].wchoose(#[0.95, 0.025, 0.025]);
frict= [0.997.rrand(1), 0.95.rrand(1.5)].wchoose(#[0.95, 0.05]);
lfoSpeed= 0.0001.rand2;
[
#[\o, \frict, \lfo, \lfoSpeed],
[o, frict, lfo, lfoSpeed].round(0.0001)
].lace(8).postln;
});
o= o*frict;
b[x].sine1(shape.clip(0.01, 1));
Pen.strokeColor= Color.grey(x+1/n);
Pen.moveTo(Point(centerX, centerY));
shape.clump(2).do{|ll, k|
var distance, angle, temp;
#distance, angle= ll;
pnt= Point(distance, distance).rotate(angle*2pi*lfo)+pnt;
Pen.lineTo(
Point(
(pnt.x*10+centerX).clip(0, width),
(pnt.y*10+centerY).clip(0, height)
)
);
};
Pen.stroke;
dist= pnt.dist(0).clip(0.1, 20); /*distance from 0, 0*/
freq= dist/20+lfoSpeed+muck+(lfo*0.01.rand)*freqSpread+60;
synths[x].set(\freq, freq, \amp, (1/n)*dist/20);
}
};
{while{w.isClosed.not} {u.refresh; (1/30).wait}}.fork(AppClock);
)
b.do{|x| x.free};