Audiovisuals with SC -Example19 - japan balls
Submitted by f0 on Thu, 2009-02-05 00:00
//Example19 - japan balls ( s.waitForBoot{ //--window setup var width= 500, height= 500; var w= Window("Example19 - japan balls", Rect(99, 99, width, height), false); var u= UserView(w, Rect(0, 0, width, height)); //--variables var theta= 0; //a counter var num= 15; //try also with more balls var syns= { SynthDef(\av, {|freq= 400, amp= 0, pan= 0| var z= SinOsc.ar(0, SinOsc.ar(freq, 0, 2pi), amp); Out.ar(0, Pan2.ar(z, pan)); }, #[0.02, 0.05, 0.05]).play(s); }.dup(num); s.sync; //--interface ~speed= 0.5; ~radius= 10; ~spread= 10; ~distancex= 1; ~distancey= 0.5; ~offsetx= -0.1; ~offsety= -0.2; ~root= 100; //--main loop u.drawFunc= { Pen.fillColor= Color.red; //set the fill color to red Pen.fillOval(u.bounds); //draw a filled oval with the size of the whole window Pen.translate(width*0.5, height*0.5); //offset all drawing to middle of the window Pen.fillColor= Color.grey(1, 0.5); //set the fill color with 50% alpha num.do{|i| var a, x, y; a= i%num/num*2pi+theta; //angle in radians x= sin(a+(i*~offsetx))*(~spread+(i*~distancex)); y= cos(a+(i*~offsety))*(~spread+(i*~distancey)); Pen.fillOval(Rect.aboutPoint(Point(x, y), ~radius, ~radius)); if(((x.hypot(y)/1.42/~spread).min(0.5)/num).isNil, {"nil".postln}); syns[i].set( //update corresponding synth \freq, y.linexp(height.neg*0.5, height*0.5, ~root, 1000), \amp, (x.hypot(y)/1.42/~spread).min(0.5)/num, \pan, x.linlin(width.neg*0.5, width*0.5, -1, 1) ); }; theta= theta-~speed%2pi; //our counter counts in radians }; //--window management u.clearOnRefresh= true; u.background= Color.white; w.onClose= {syns.do{|x| x.free}}; w.front; Routine({while({w.isClosed.not}, {u.refresh; (1/30).wait})}).play(AppClock); }; ) ( //use midi input to control the program MIDIIn.connect(device:1); //edit to match your own setup MIDIIn.control= {|src, chan, num, val| switch(num.postln, 1, {~speed= val.linlin(0, 127, 0, 2pi)}, //ctrl number 1 sets the ~speed 2, {~radius= val.linlin(0, 127, 1, 100)}, 3, {~spread= val.linlin(0, 127, 0, 300)}, 4, {~distancex= val.linlin(0, 127, -10, 10)}, 5, {~distancey= val.linlin(0, 127, -10, 10)}, 6, {~offsetx= val.linlin(0, 127, -pi*0.5, pi*0.5)}, 7, {~offsety= val.linlin(0, 127, -pi*0.5, pi*0.5)} ); }; MIDIIn.noteOn= {|src, chan, num, vel| ~root= num.postln.midicps; //note set root frequency }; ) //change these while the program is running ~spread= 25; ~distancey= -2.2; ~distancey= -5.7; ~distancex= -6.7; ~spread= 150; ~radius= 50; ~offsetx= 0; ~offsety= -0.6; ~radius= 8; ~spread= 60; ~speed= pi*0.99; ~distancex= -10; ~distancey= 3; ~speed= 0.5; ~speed= -0.15; ~offsety= 0.1; ~offsetx= -0.5; ~offsety= 1; ~speed= 0.02; ~speed= 0.3; ~distancex= 0.12; ~distancey= -9.2; ~speed= 0.2; ~distancex= 5.5; ~offsetx= -0.1; ~offsety= -0.21; ~spread= 100; ~spread= 800; ~spread= 2; ~offsety= 0; ~distancey= 0; ~speed= 0.1 ~speed= 22; ~root= 60; ~root= 120; //close the window to stop