//audiovisual programming / mapping and visualization

//organized by lullcec, barcelona 18-20 may 2012



//----------------------------

//session #02.0

//animation




//--simple examples


(

var width= 640;

var height= 480;

var win= Window("animation", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.white;

Pen.fillRect(Rect(usr.frame%width, height*0.5, 10, 20));

};

usr.animate= true;

)


(

var width= 640;

var height= 480;

var win= Window("animation2", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 0.5;

Pen.strokeColor= Color.white;

100.do{|i|

Pen.line(Point(width*0.5, height*0.5), Point(width.rand, height.rand));

Pen.stroke;

};

};

usr.animate= true;

)





//--changing parameters while it is running


(

var width= 640;

var height= 480;

var win= Window("animation live control", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~num= 4;

~col= Color.white;

~size= 40;

~spread= 100;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.strokeColor= ~col;

~num.do{|i|

Pen.strokeRect(Rect(usr.frame+(i*~spread)%width, height*0.5, ~size, ~size));

};

};

usr.animate= true;

)


~num= 8

~spread= 3

~spread= 13

~num= 20

~size= 10

~num= 200

~spread= 4

~size= 100


(

var width= 640;

var height= 480;

var win= Window("redlines", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~speed= 0.1;

~width= 4;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= ~width;

70.do{|i|

Pen.strokeColor= Color.red(i/69);

Pen.line(Point(width*0.5, height*0.5), Point(width*0.33, height*0.33).rotate(i/69*2pi+(usr.frame*~speed))+Point(width*0.5, height*0.5));

Pen.stroke;

};

};

usr.animate= true;

)


~speed= 0.2

~speed= -0.2

~speed= 0.002

~speed= 2.2

~speed= 2.5

~speed= 3

~width= 1

~width= 10






//--strings


~font= Font("Geneva", 40);

(

var width= 640;

var height= 480;

var win= Window("text animation", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.white;

Pen.font= ~font;

Pen.stringAtPoint("123456789".rotate(((usr.frame*0.03).asInteger%5)), Point(usr.frame*0.7%width, height*0.5));

};

usr.animate= true;

)


~font= Font("Helvetica", 8);

(

var width= 640;

var height= 480;

var win= Window("text animation2", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

~rows= 50;

~cols= 30;

usr.drawFunc= {

Pen.smoothing= false;

Pen.fillColor= Color.white;

Pen.font= ~font;

~rows.do{|x|

~cols.do{|y|

Pen.stringAtPoint(10.rand.asString, Point(x/~rows*width+(0.5/~rows*width), y/~cols*height+(0.5/~cols*height)));

};

};

};

usr.animate= true;

)


~rows= 1

~cols= 1

~rows= 10

~cols= 10

~font= Font("Helvetica", 24)

~font= Font("Helvetica", 14)

(

Routine({

50.do{

~rows= ~rows+1;

~cols= ~cols+1;

0.1.wait;

};

}).play

)





//--animation with simple sound


s.boot


(

var width= 640;

var height= 480;

var win= Window("white oval", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

var syn= {|freq= 400, pan= 0| Pan2.ar(SinOsc.ar(freq, 0, 0.2), pan)}.play;

usr.background= Color.black;

win.front;

~speed= 5;

~updown= 0.5;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

var x= usr.frame*~speed%width;

var y= height*~updown.value(usr.frame);

syn.set(\freq, y.linexp(0, height, 800, 400), \pan, x.linlin(0, width, -1, 1));

Pen.width= 30;

Pen.strokeColor= Color.white;

Pen.strokeOval(Rect(x, y, 50, 50));

};

usr.animate= true;

)


~speed= -3

~speed= 40

~speed= 400

~speed= 0.1

~speed= 1

~updown= 0.25

~updown= 0.9


~updown= {1.0.rand}

~updown= {|i| sin(i*0.01)*0.5+0.5}

~updown= {|i| sin(i*0.01+sin(i*0.11))*0.5+0.5}


//more about mapping audio and sound in session #03





//----------------------------

//session #02.1

//colour-modes, trailing effects, rotation, scaling, translation


Color.white

Color(0.1, 0.2, 0.3, 1) //red, green, blue, alpha

Color.red(1, 0.4) //amount, alpha

Color.green(0.5, 0.9)


Color.hsv(1, 0.5, 0.25, 1) //hue, sat, val, alpha


//see Color helpfile





//--using hsv color mode


(

var width= 640;

var height= 480;

var win= Window("hsvlines", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~speed= 0.1;

~width= 1;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= ~width;

70.do{|i|

Pen.strokeColor= Color.hsv(i/70, 0.5, 0.8);

Pen.strokeOval(Rect.aboutPoint(Point(width*0.5, height*0.5).rotate(i/69*2pi+(usr.frame*~speed))+Point(width*0.5, height*0.5), width*0.9, height*0.9));

Pen.stroke;

};

};

usr.animate= true;

)


~speed= 0.2

~speed= -0.2

~speed= 0.002

~speed= 2.2

~speed= 2.5

~speed= 3

~speed= 3.1

~speed= 3.14

~speed= 3.1415

~speed= 2pi

~width= 2

~speed= 0.1

~width= 20




//--trail effect


//set clearOnRefresh to false and manually draw a big rect with some alpha every frame


(

var width= 640;

var height= 480;

var win= Window("trail effect", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~speed= 0.1;

~alpha= 0.1;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.grey(0.1, ~alpha); //here trail amount

Pen.fillRect(Rect(0, 0, width, height));

Pen.width= 5;

70.do{|i|

Pen.strokeColor= Color.hsv(i/70, 0.5, i/70);

Pen.line(Point(width*0.5, height*0.5), Point(width*0.33, height*0.33).rotate(i/69*2pi+(usr.frame*~speed))+Point(width*0.5, height*0.5));

Pen.stroke;

};

};

usr.animate= true;

usr.clearOnRefresh= false; //important

)


~alpha= 0.9

~alpha= 0.01

~speed= 0.2

~alpha= 0.5

~alpha= 0.01




(

var width= 640;

var height= 480;

var win= Window("white oval with trail", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~speed= 5;

~updown= 0.5;

~alpha= 0.1;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.grey(0.1, ~alpha);

Pen.fillRect(Rect(0, 0, width, height));

Pen.width= 30;

Pen.strokeColor= Color.white;

Pen.strokeOval(Rect(usr.frame*~speed%width, height*~updown.value(usr.frame), 50, 50));

};

usr.animate= true;

usr.clearOnRefresh= false;

)


~updown= {|i| sin(i*0.11)*0.5+0.5}

~speed= 20

~alpha= 0.25

~alpha= 0

~alpha= 0.01

~updown= {|i| sin(i*0.11)*sin(i*0.2)*0.3+0.5}

~speed= 200

~speed= -300

~speed= 80

~speed= 160.1

~updown= {|i| sin(i*0.11)%cos(i*0.2)*0.3+0.5}

~speed= 5




//--rotate


(

var width= 640;

var height= 480;

var win= Window("rotated squares", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

var theta= 0;

usr.background= Color.black;

win.front;

~alpha= 0.1;

~speed= 0;

~width= 1;

~size= 10;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.grey(0.1, ~alpha);

Pen.fillRect(Rect(0, 0, width, height));

Pen.width= ~width;

Pen.rotate(theta, width*0.5, height*0.5);

theta= theta+~speed;

Pen.strokeColor= Color.white;

10.do{|i|

6.do{|j|

Pen.strokeRect(Rect.aboutPoint(Point(i/9*width, j/5*height), ~size, ~size));

};

};

};

usr.animate= true;

usr.clearOnRefresh= false;

)


~speed= 0.01

~speed= -0.01

~speed= -0.05

~speed= 2

~size= 4;

~size= 30;

~width= 4

~width= 0.2

~size= 1

~width= 1

~speed= pi*0.999




//--scale


(

var width= 640;

var height= 480;

var win= Window("scaled squares", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~alpha= 0.1;

~sx= 1;

~sy= 1;

~width= 1;

~size= 10;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.grey(0.1, ~alpha);

Pen.fillRect(Rect(0, 0, width, height));

Pen.width= ~width;

Pen.scale(~sx.value(usr.frame), ~sy.value(usr.frame));

Pen.strokeColor= Color.white;

10.do{|i|

6.do{|j|

Pen.strokeRect(Rect.aboutPoint(Point(i/9*width, j/5*height), ~size, ~size));

};

};

};

usr.animate= true;

usr.clearOnRefresh= false;

)


~sx= 0.5

~sy= 0.2

~sy= {|i| sin(i*0.01)*0.5+0.5}

~sx= 1

~width= 40

~sy= {|i| sin(i*0.01+sin(i*0.1))*0.5+0.5}

~size= 1

~width= 4

~size= 200

~sx= {|i| sin(i*0.007+sin(i*0.08))*0.5+0.5}

~size= 20



//--translate


(

var width= 640;

var height= 480;

var win= Window("translated squares", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~alpha= 0.1;

~tx= 0;

~ty= 0;

~width= 1;

~size= 10;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.fillColor= Color.grey(0.1, ~alpha);

Pen.fillRect(Rect(0, 0, width, height));

Pen.width= ~width;

Pen.translate(~tx.value(usr.frame), ~ty.value(usr.frame));

Pen.strokeColor= Color.white;

10.do{|i|

6.do{|j|

Pen.strokeRect(Rect.aboutPoint(Point(i/9*width, j/5*height), ~size, ~size));

};

};

};

usr.animate= true;

usr.clearOnRefresh= false;

)


~tx= 10

~tx= 40

~tx= {|i| i%(640/9)}

~ty= {|i| sin(i*0.01)*100}

~tx= {|i| cos(i*0.01)*100}

~size= 60

~alpha= 0.01





//everything at once - push and pop


(

var width= 640;

var height= 480;

var win= Window("rotate scale translate", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~rotate= 1;

~translate= 50;

~scale= 0.99;

~num= 50;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 1;

Pen.translate(width*0.5, height*0.5); //offset drawing to the middle

Pen.push; //see also Pen.use

Pen.strokeColor= Color.white;

~num.do{

Pen.rotate(~rotate);

Pen.translate(0, ~translate);

Pen.scale(~scale, ~scale);

Pen.strokeOval(Rect(0, 0, 10, 10));

};

Pen.pop;

Pen.push;

Pen.fillColor= Color.red;

10.do{|i|

Pen.fillRect(Rect(i*10, i*10, 10, 10));

};

Pen.pop;

};

usr.animate= true;

)


~rotate= 2

~rotate= 0.2

~rotate= -4

~rotate= 0.4

~translate= 10;

~translate= 100;

~scale= 0.9

~translate= 50;

~scale= 1.06

~rotate= 4

~num= 3

~num= 300

~scale= 0.995

~scale= 0.999

~translate= 200





//----------------------------

//session #02.2

//custom shapes, styles and clipping


(

var width= 640;

var height= 480;

var win= Window("smoothing", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

var theta= 0;

usr.background= Color.black;

win.front;

~speed= 0.001;

~smooth= false;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.smoothing= ~smooth; //important

Pen.strokeColor= Color.white;

Pen.rotate(theta, width*0.5, height*0.5);

theta= theta+~speed;

100.do{|i|

Pen.strokeOval(Rect(100+(i*2), 100+i, width-200, height-200));

};

};

usr.animate= true;

)


~speed= -0.01

~speed= pi*0.5005

~speed= 2pi*0.5005

~speed= pi*0.6667

~smooth= true

~speed= 0.01

~smooth= false

~smooth= true

~smooth= false


(

var width= 640;

var height= 480;

var win= Window("join styles", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~join= 0;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 50;

Pen.joinStyle= ~join;

Pen.strokeColor= Color.blue;

Pen.strokeRect(Rect(100, 100, width-200, height-200));

};

usr.animate= true;

)


~join= 1 //round

~join= 2 //bevel

~join= 0 //miter


(

var width= 640;

var height= 480;

var win= Window("cap styles", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

~cap= 0;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 50;

Pen.capStyle= ~cap;

Pen.strokeColor= Color.blue;

Pen.line(Point(40, 40), Point(width*0.5, height*0.5));

Pen.line(Point(width*0.5, height*0.5), Point(width*0.8, height*0.1));

Pen.stroke;

};

usr.animate= true;

)


~cap= 1 //round

~cap= 2 //bevel

~cap= 0 //miter




//--custom shapes


(

var width= 640;

var height= 480;

var win= Window("custom", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 1;

Pen.strokeColor= Color.white;

Pen.moveTo(Point(40, 40));

Pen.lineTo(Point(width*0.5, height*0.5));

Pen.lineTo(Point(width*0.8, height*0.1));

Pen.lineTo(Point(20, height*0.65));

Pen.lineTo(Point(40, 40));

Pen.stroke;

};

usr.animate= true;

)




//--clipping


//useful for masking and only draw in one area


(

var width= 640;

var height= 480;

var win= Window("clip", Rect(10, 10, width, height), false);

var usr= UserView(win, Rect(0, 0, width, height));

usr.background= Color.black;

win.front;

CmdPeriod.doOnce({win.close});

usr.drawFunc= {

Pen.width= 1;

Pen.strokeColor= Color.white;

Pen.addOval(Rect.aboutPoint(Point(width*0.5, height*0.5), width*0.25, height*0.25));

Pen.clip;

50.do{ //draw 50 random lines, but clip will mask out

Pen.line(Point(width.rand, height.rand), Point(width.rand, height.rand));

};

Pen.stroke;

};

usr.animate= true;

)




//----------------------------

//session #02.3

//drawing waveforms (time domain)


(

s.latency= 0.05;

s.waitForBoot{

//--variables

var l= 750; //global window size

var theta= 0;

var fps= 60;

var arr= Array.fill(l, 0); //same as half windowsize above

var o= OSCresponder(s.addr, '/tr', {|t, r, m|

if(m[2]==0, { //redraw once for each cycle of amps

b.getn(0, l-1, {|data| {arr= data; u.refresh}.defer});

});

}).add;

var trk, cnt= 0;

//--window setup

var width= l, height= l;

var w= Window("waveform", Rect(99, 99, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

var w2= width*0.5;

var h2= height*0.5;

//--interface

~trails= 1;

~speed= 0;

~sample= 1;

~amp= 0.5;

~version= 0;

//--synths

b= Buffer.alloc(s, l, 1);

SynthDef(\avTrk, {|in= 0, bufnum, rate= 40, sample= 1|

var z= In.ar(in, 1);

var trig= Impulse.kr(rate);

var index= Phasor.ar(trig, sample, 0, BufFrames.ir(bufnum)-1);

BufWr.ar(z, bufnum, index, 0);

SendTrig.kr(trig, 0, bufnum);

}).send(s);

s.sync;

trk= Synth(\avTrk, [\in, 0, \bufnum, b, \rate, fps], RootNode(s), \addToTail);

s.sync;

//--main loop

u.drawFunc= {

if(cnt==0, {

Pen.fillColor= Color.black; //erase first time

Pen.fillRect(Rect(0, 0, width, height));

});

trk.set(\sample, ~sample);

Pen.fillColor= Color.grey(0, ~trails);

Pen.fillRect(u.bounds); //manually clear

Pen.strokeColor= Color.green;

switch(~version,

0, { //line

Pen.rotate(theta, w2, h2);

Pen.translate(0, h2);

arr.do{|y, x|

var p= Point(x, y*(height*~amp));

if(x==0, {Pen.moveTo(p)}, {Pen.lineTo(p)});

};

Pen.stroke;

},

1, { //warp

Pen.rotate(theta, w2, h2);

Pen.translate(w2, h2);

arr.do{|y, x|

var p= Point(x*~amp, y*~amp).rotate(y*2pi);

if(x==0, {Pen.moveTo(p)}, {Pen.lineTo(p)});

};

Pen.stroke;

},

2, { //flower

Pen.translate(w2, h2);

Pen.moveTo(Point(arr[0], 0)*arr[0]);

arr.do{|y, x|

var p= Point(y, x)*y;

var a= x%width/width*2pi+theta;

Pen.lineTo(p.rotate(a));

};

Pen.stroke;

}

);

theta= theta+~speed;

cnt= cnt+1;

};

//--window management

u.clearOnRefresh= false; //do not erase - just draw on top of

w.onClose= {

trk.free;

o.remove;

b.free;

};

w.front;

CmdPeriod.doOnce({if(w.isClosed.not, {w.close})});

//note no routine here. the responder is driving the animation

};

)


//play your own sound or test with this...

//--tweet0038

a= play{PingPong.ar(LocalBuf(3e4,2).clear,Ringz.ar(CuspN.ar*Impulse.kr([9,8]/12)/9,LFPar.kr(1/[3,2]).range(51,[99,17])*9),0.5)}//#SuperCollider


//change these while the program is running

~sample= 2;

~sample= 10;

~sample= 1;

~trails= 0.2;

~speed= 0.1;

~speed= -0.05;

~trails= 0.01;

~amp= 0.02;

~speed= pi*0.25;

~amp= 0.2;

~sample= 2;

~version= 1;

~trails= 0.2;

~version= 2;

~sample= 1;

~version= 1;

~speed= 2pi*1.001;

~amp= 0.5;

a.release




//ADVANCED: bufferdisplay (waveform variant)

(

l= 1024; //global window/buffer size in pixels/samples

s.latency= 0.05;

s.waitForBoot{

//--variables

var theta= 0;

var fps= 60;

var arr= Array.fill(l, 0);

var cnt= 0;

//--window setup

var width= l, height= l;

var w= Window("bufferdisplay", Rect(99, 99, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

var w2= width*0.5;

var h2= height*0.5;

//--buffer

b= Buffer.alloc(s, l, 1);

s.sync;

//--interface

~trails= 1;

~speed= 0;

~amp= 0.5;

~version= 0;

//--main loop

u.drawFunc= {

//uncomment framerate display in the two lines below to gain some speed

Pen.color= Color.white;

Pen.stringAtPoint(""++u.frameRate, Point(10, 10));

//--

b.getn(0, b.numFrames-1, {|data| arr= data});

if(cnt==0, {

Pen.fillColor= Color.black; //erase first time

Pen.fillRect(Rect(0, 0, width, height));

});

Pen.fillColor= Color.grey(0, ~trails);

Pen.fillRect(u.bounds); //manually clear

Pen.strokeColor= Color.green;

switch(~version,

0, { //line

Pen.rotate(theta, w2, h2);

Pen.translate(0, h2);

arr.do{|y, x|

var p= Point(x, y*(height*~amp));

if(x==0, {Pen.moveTo(p)}, {Pen.lineTo(p)});

};

Pen.stroke;

},

1, { //warp

Pen.rotate(theta, w2, h2);

Pen.translate(w2, h2);

arr.do{|y, x|

var p= Point(x*~amp, y*~amp).rotate(y*2pi);

if(x==0, {Pen.moveTo(p)}, {Pen.lineTo(p)});

};

Pen.stroke;

},

2, { //flower

Pen.translate(w2, h2);

Pen.moveTo(Point(arr[0], 0)*arr[0]);

arr.do{|y, x|

var p= Point(y, x)*y;

var a= x%width/width*2pi+theta;

Pen.lineTo(p.rotate(a));

};

Pen.stroke;

}

);

theta= theta+~speed;

cnt= cnt+1;

};

//--window management

u.clearOnRefresh= false; //do not erase - just draw on top of

w.onClose= {

b.free;

};

w.front;

CmdPeriod.doOnce({if(w.isClosed.not, {w.close})});

u.animate= true;

};

)



//some synth that writes into the buffer

v= {RecordBuf.ar(Saw.ar, b)}.play


//change these while the program is running

~trails= 0.2;

~speed= 0.1;

~speed= -0.05;

~trails= 0.01;

~amp= 0.02;

~speed= pi*0.25;

~amp= 0.2;

~version= 1;

~trails= 0.2;

~version= 2;

~version= 1;

~speed= 2pi*1.001;

~amp= 0.5;

v.free;


//keep window open - start this synth and move mouse around

v= {RecordBuf.ar(SinOsc.ar(0, BPF.ar(VarSaw.ar(MouseX.kr(1, 1000, 1)), MouseY.kr(50, 5000, 1), 0.5)), b)}.play

~version= 1;

~trails= 0.01;

~speed= -0.03;

~speed= -0.05;

~trails= 1;

~amp= 0.5;

~speed= 2pi*0.25;

~trails= 0.1

~amp= 0.2;

~version= 2;

~version= 0;

~speed= 2pi*1.001;

~amp= 10;

~speed= 0;

v.free




//----------------------------

//session #02.4

//spectrograms (frequency domain)


//tracking amplitude with a bunch of band-pass filters

(

s.latency= 0.05;

s.waitForBoot{

//--window setup

var width= 500, height= 500;

var w= Window("amptrack", Rect(99, 99, width, height), false, false);

var u= UserView(w, Rect(0, 0, width, height));

//--variables

var fps= 60;

var num= 100; //number of tuned filter synths

var cnt= 0; //vertical drawing position

var amps= 0.dup(num); //array of current amplitudes

var o= OSCresponder(s.addr, '/tr', {|t, r, m| amps= amps.put(m[2], m[3])}).add;

var syns;

var wn= width/num;

var w2= width*0.5;

var h2= height*0.5;

//--interface

~freqMin= 200;

~freqMax= 6000;

~width= 120;

~speed= 1;

~extra= 1;

~version= 1;

//--synths

SynthDef(\avTrk, {|in, t_trig, time= 0.01, cutoff= 400, index= 0|

var z= In.ar(in, 1);

var val= Amplitude.kr(BPF.ar(BPF.ar(z, cutoff, 0.1, 5), cutoff, 0.1, 5), time, time);

SendTrig.kr(t_trig, index, val);

}).send(s);

s.sync;

syns= {|i| //each tracker with an unique peakfilter

Synth(\avTrk, [\in, 0, \index, i, \cutoff, i.linexp(0, num-1, ~freqMin, ~freqMax)]);

}.dup(num);

s.sync;

//--main loop

u.drawFunc= {

//--first frame clear to black

if(cnt==0, {

Pen.fillColor= Color.black;

Pen.fillRect(Rect(0, 0, width, height));

});

//--optional oval mask

/*

Pen.moveTo(Point(w2, 0));

Pen.arcTo(Point(width, 0), Point(width, h2), w2);

Pen.arcTo(Point(width, height), Point(w2, height), w2);

Pen.arcTo(Point(0, height), Point(0, h2), w2);

Pen.arcTo(Point(0, 0), Point(w2, 0), w2);

Pen.clip;

*/

switch(~version,

0, {

Pen.translate(wn*0.5, cnt%height);

amps.do{|amp, i|

Pen.fillColor= Color.grey((amp*~extra).clip(0, 1));

Pen.fillRect(Rect.aboutPoint(Point(wn*i, 0), wn*0.5, ~width));

};

cnt= cnt+~speed;

},

1, {

amps.do{|amp, i|

Pen.rotate(cnt, w2, h2);

Pen.strokeColor= Color.grey((amp*~extra).clip(0, 1));

Pen.strokeRect(Rect.aboutPoint(Point(wn*i, 0), ~width*0.1, ~width));

cnt= cnt+(~speed*0.000001);

};

},

2, {

Pen.rotate(cnt, w2, h2);

Pen.translate(w2, h2);

amps.do{|amp, i|

Pen.strokeColor= Color.grey((amp*~extra).clip(0, 1));

Pen.strokeOval(Rect.aboutPoint(Point(i*~speed, 0), ~width*0.5, ~width*0.5));

};

cnt= cnt+(~speed*0.01);

}

);

syns.do{|x| x.set(\t_trig, 1)}; //request amp data

};

//--window management

u.clearOnRefresh= false; //do not erase - just draw on top of

w.front;

CmdPeriod.doOnce({if(w.isClosed.not, {w.close}); o.remove;});

//Routine({while({w.isClosed.not}, {u.refresh; (1/fps).wait})}).play(AppClock);

u.animate= true;

};

)


a= {Saw.ar(100*SinOsc.ar(SinOsc.ar(SinOsc.ar(0.1)*0.2)).abs+50, 0.5)}.play


//change these while the program is running

~width= 50;

~width= 200;

~speed= 2;

~speed= -0.1;

~speed= pi;

~version= 0;

~width= 20;

~speed= 1;

~width= 1;

~speed= 10;

~width= 500;

~version= 2;

~width= 100;

~speed= 1;

~speed= -1.5;

~width= 20;

~extra= 7;

a.free


////keep window open - play your own sound or test with this...

//--tweet0014

a= play{a=SinOscFB;sum({|i|a.ar(a.ar(a.ar(a.ar(i+1,1/9,999),1/9,a.ar(1/9,1,1/9)),a.ar(0.1,3),i+2*999),a.ar(1/9,1/9),1/9)}!9)!2}//#SuperCollider

a.free




//using fft


(

s.latency= 0.05;

s.waitForBoot{

//--variables

var l= 512; //try with 1024 if you have a fast machine

var scale= if(l<=256, {2}, {1}); //scale can be 1 or 2

var cnt= 0; //horizontal drawing position

var fftArray= Array.fill(l, 0);

var o= OSCresponder(s.addr, '/tr', {|t, r, m|

var v= m[3].min(1); //brutal clip of mags here

var i= l.div(2);

fftArray= fftArray.put([i-m[2], i+m[2]], v); //mirror middle of array

}).add;

var trk;

//--window setup

var width= l+10, height= l+10;

var w= Window("fft", Rect(99, 99, width, height), false);

var u= UserView(w, Rect(0, 0, width, height));

//--interface

~speed= 1;

~version= 0;

~radius= 2/scale;

~depth= 0.01;

~trails= 0.5;

~fps= 60;

//--synths

b= Buffer.alloc(s, l, 1);

SynthDef(\avTrk, {|in= 0, t_trig= 0|

var z= In.ar(in, 1);

var chain= FFT(b, z);

Array.fill(l.div(2), {|i|

var a= Unpack1FFT(chain, l, i, 0);

var b= Demand.kr(chain>=0, 0, a);

SendTrig.kr(t_trig, i, b);

});

}).send(s);

s.sync;

trk= Synth(\avTrk, [\in, 0], RootNode(s), \addToTail);

s.sync;

//--main loop

u.drawFunc= {

switch(~version,

0, { //rectangles

Pen.translate(5, 5);

fftArray.do{|a, y|

var p= Point(cnt*scale, height-10-(y*scale));

Pen.fillColor= Color.grey((1-a).clip(0, 1));

Pen.fillRect(Rect.aboutPoint(p, scale*~radius, scale*~radius));

};

cnt= cnt+~speed%fftArray.size;

Pen.strokeColor= Color.red;

Pen.line(Point(cnt*scale, 0), Point(cnt*scale, l*scale));

Pen.stroke;

},

1, { //ovals with a little transparency

Pen.translate(5, 5);

fftArray.do{|a, y|

var p= Point(cnt*scale, height-10-(y*scale));

Pen.fillColor= Color.grey((1-a).clip(0, 1), 0.5);

Pen.fillOval(Rect.aboutPoint(p, scale*~radius, scale*~radius));

};

cnt= cnt+~speed%fftArray.size;

},

2, { //rotation

Pen.fillColor= Color.grey(1, ~trails);//clear color with some alpha

Pen.fillRect(Rect(0, 0, width, height));//manually clear with rect

fftArray.do{|a, y|

var p= Point(cnt*scale, height-(y*scale));

Pen.rotate(y/l*0.25*scale*2pi*~depth, width*0.5, height*0.5);

Pen.fillColor= Color.grey((1-a).clip(0, 1));

Pen.fillOval(Rect.aboutPoint(p, scale*~radius, scale*~radius));

};

cnt= cnt+~speed%fftArray.size;

},

3, { //lines

Pen.fillColor= Color.grey(1, ~trails);

Pen.fillRect(Rect(0, 0, width, height));

fftArray.do{|a, y|

var p= Point(cnt.fold(0, l*scale), height-y);

Pen.strokeColor= Color.grey(1-(a+0.5).clip(0, 1), 0.5);

Pen.moveTo(p*a); //move to before rotation special here

Pen.rotate(y/l*pi*0.5*scale*~depth, width*0.5, height*0.5);

Pen.lineTo(p);

Pen.stroke;

};

cnt= cnt+~speed;

}

);

trk.set(\t_trig, 1); //to all send trigs

};

//--window management

u.clearOnRefresh= false; //do not erase - just draw on top of

w.onClose= {

trk.free;

o.remove;

b.free;

};

w.front;

//Routine({while({w.isClosed.not}, {u.refresh; (1/~fps).wait})}).play(AppClock);

u.animate= true;

CmdPeriod.doOnce({if(w.isClosed.not, {w.close})});

};

)



//play your own sound or test with this...

//--tweet0014

a= play{a=SinOscFB;sum({|i|a.ar(a.ar(a.ar(a.ar(i+1,1/9,999),1/9,a.ar(1/9,1,1/9)),a.ar(0.1,3),i+2*999),a.ar(1/9,1/9),1/9)}!9)!2}//#SuperCollider


//change these while the program is running

~version= 1;

~radius= 4;

~speed= 8;

~speed= 256/6;

~radius= 256/25;

~speed= -1;

~version= 2;

~trails= 0.01;

~radius= 5;

~speed= 2;

~radius= 0.5;

~depth= -0.002;

~depth= 3;

~radius= 1;

~trails= 0.5;

~version= 3;

~depth= 0.5;

~speed= 5;

~depth= -0.1;

~depth= -0.01

~trails= 0.01;

a.free





//----------------------------

//session #02.5

//bitmaps and scrolling views


//show SCImage (osx cocoa only), RedGIF (in quark redSys)


GUI.cocoa;


i= SCImage(SCDoc.helpSourceDir +/+ "images/icon.supercollider.png");

a= i.plot

p= i.pixels;

i.pixels= p.as(Array).rotate(100).as(Int32Array)

a.refresh


i.pixels= p.as(Array).collect{|x| if(x< -1, {1}, {x})}.as(Int32Array)

a.refresh

1000.do{p.put(p.size.rand, p.choose)}

i.pixels= p

a.refresh


(

r= Routine({

inf.do{

a.refresh;

(1/60).wait;

};

}).play(AppClock);

)


500.do{i.setPixel([255, 255, 255].asRGBA, 50.rand, 50.rand)}


r.stop

i.free

a.close