supercollider

redLeech

clean-up #28:

code that performs itself. this is number six in a series all working in a similar manner. see low life, more low life and even more low life.
this virtual leech runs around the code and suck up words now and then. when it's full (c.size>30) it spits them all out wherever it happens to be. and some characters are lost so the code slowly disappears.
in the end of the video it got stuck in a loop so i killed it off manually with the delete key.

thanks to chris for the title.

supercollider document attached below. osx only afaik.

AttachmentSize
Binary Data redLeech.scd993 bytes

redUniverse: clean-up and some new features

clean-up #26:

my redUniverse quark still have a lot of features missing that i want to put in. it is endless work and i only get to it now and then. but at least after today the helpfiles are in a bit better shape, and examples are changed to use animate to run more smoothly (most now look a lot better!).

* new helpfiles for RedHiddenObject, RedParticle, RedBoid, RedRock, RedFood, RedAgent.
* slightly changed formatting for almost all the other included helpfiles.
* wrote addForceWander1D and addForceWander3D methods for RedBoid.
* wrote addForceAngular3D, pendulumOffset3D, pendulumLoc3D.
* added 2 boids examples and 1 pendulum to show the new features.
* changed almost all the other examples to use animate instead of play and to close the window at cmd+.

here is the complete svn diff.

vertex

clean-up #25:

attached is a little class that draws polygons in supercollider. with inspiration from processing.
if you want to use the \point type of shape it will look better with smoothing set to false and Vertex.pointSize= 0;

update 101211: attached a simple BezierVertez class. it works like this one.
update 101215: improved the \triangleFan type in vertex.sc.
update 141012: minor update to BezierVertez.sc - added close argument

(
        var win= Window("vertex test", Rect(100, 100, 430, 320), false);
        win.drawHook= {
                Pen.fillColor= Color.white;
                Pen.strokeColor= Color.black;
               
                Pen.use{
                        Pen.translate(10, 10);
                        Vertex.beginShape();
                        Vertex(Point(30, 20));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex(Point(30, 75));
                        Vertex.endShape(1);             //1 means close
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(110, 10);
                        Vertex.beginShape(\points);
                        Vertex(Point(30, 20));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex(Point(30, 75));
                        Vertex.endShape();
                        Pen.stroke;
                };
                Pen.use{
                        Pen.translate(210, 10);
                        Vertex.beginShape(\lines);
                        Vertex(Point(30, 20));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex(Point(30, 75));
                        Vertex.endShape();
                        Pen.stroke;
                };
                Pen.use{
                        Pen.translate(310, 10);
                        Vertex.beginShape();
                        Vertex(Point(30, 20));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex(Point(30, 75));
                        Vertex.endShape(0);             //0 means not close (default)
                        Pen.stroke;
                };
               
                Pen.use{
                        Pen.translate(10, 110);
                        Vertex.beginShape();
                        Vertex(Point(30, 20));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex(Point(30, 75));
                        Vertex.endShape(1);             //1 means close
                        Pen.stroke;
                };
                Pen.use{
                        Pen.translate(110, 110);
                        Vertex.beginShape(\triangles);
                        Vertex(Point(30, 75));
                        Vertex(Point(40, 20));
                        Vertex(Point(50, 75));
                        Vertex(Point(60, 20));
                        Vertex(Point(70, 75));
                        Vertex(Point(80, 20));
                        Vertex.endShape();
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(210, 110);
                        Vertex.beginShape(\triangleStrip);
                        Vertex(Point(30, 75));
                        Vertex(Point(40, 20));
                        Vertex(Point(50, 75));
                        Vertex(Point(60, 20));
                        Vertex(Point(70, 75));
                        Vertex(Point(80, 20));
                        Vertex(Point(90, 75));
                        Vertex.endShape();
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(310, 110);
                        Vertex.beginShape(\triangleFan);
                        Vertex(Point(57.5, 50));
                        Vertex(Point(57.5, 15));
                        Vertex(Point(92, 50));
                        Vertex(Point(57.5, 85));
                        Vertex(Point(22, 50));
                        Vertex(Point(57.5, 15));
                        Vertex.endShape();
                        Pen.fillStroke;                 //also try fill and stroke
                };
               
                Pen.use{
                        Pen.translate(10, 210);
                        Vertex.beginShape(\quads);
                        Vertex(Point(30, 20));
                        Vertex(Point(30, 75));
                        Vertex(Point(50, 75));
                        Vertex(Point(50, 20));
                        Vertex(Point(65, 20));
                        Vertex(Point(65, 75));
                        Vertex(Point(85, 75));
                        Vertex(Point(85, 20));
                        Vertex.endShape();
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(110, 210);
                        Vertex.beginShape(\quadStrip);
                        Vertex(Point(30, 20));
                        Vertex(Point(30, 75));
                        Vertex(Point(50, 20));
                        Vertex(Point(50, 75));
                        Vertex(Point(65, 20));
                        Vertex(Point(65, 75));
                        Vertex(Point(85, 20));
                        Vertex(Point(85, 75));
                        Vertex.endShape();
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(210, 210);
                        Vertex.beginShape();
                        Vertex(Point(20, 20));
                        Vertex(Point(40, 20));
                        Vertex(Point(40, 40));
                        Vertex(Point(60, 40));
                        Vertex(Point(60, 60));
                        Vertex(Point(20, 60));
                        Vertex.endShape(1);             //also try 0 here
                        Pen.fillStroke;                 //also try fill and stroke
                };
                Pen.use{
                        Pen.translate(310, 210);
                        Vertex.beginShape();
                        14.do{
                                Vertex(Point(85.rand, 85.rand));
                        };
                        Vertex.endShape(1);             //also try 0 here
                        Pen.fillStroke;                 //also try fill and stroke
                };
        };
        win.front;
)
//http://processing.org/reference/bezierVertex_.html
(
        var win= Window("beziervertex test1", Rect(100, 100, 300, 300), false);
        win.drawHook= {
                Pen.fillColor= Color.white;
                Pen.strokeColor= Color.black;
                BezierVertex.beginShape(Point(30, 20));
                BezierVertex(Point(80, 0), Point(80, 75), Point(30, 75));
                BezierVertex.endShape;
                Pen.stroke;                             //also try fillStroke and fill
        };
        win.front;
)

//http://processing.org/reference/bezierVertex_.html
(
        var win= Window("beziervertex test2", Rect(100, 100, 300, 300), false);
        win.drawHook= {
                Pen.fillColor= Color.white;
                Pen.strokeColor= Color.black;
                BezierVertex.beginShape(Point(30, 20));
                BezierVertex(Point(80, 0), Point(80, 75), Point(30, 75));
                BezierVertex(Point(50, 80), Point(60, 25), Point(30, 20));
                BezierVertex.endShape;
                Pen.fillStroke;                 //also try stroke and fill
        };
        win.front;
)

AttachmentSize
Binary Data Vertex.sc1.6 KB
Binary Data BezierVertex.sc342 bytes

k-means

clean-up #24:

i took some code i had for performing k-means clustering and made it into a proper class. i also found Dan Stowell's KMeans quark and borrowed some concepts from that one. my version works slightly different and uses RedVectors of any dimension.
the class is part of my redUniverse quark and the best way to install it is as always... download it with Quarks.checkoutAll; and then install via Quarks.gui; a helpfile and simple examples are included but i hope to write more elaborate demonstrations of this later on.

this is a screenshot from the example in the helpfile. 1000 random points are categorised into 5 groups/clusters. the bigger circles are the 5 mean points/centroids.

also see 190-kmeans.scd for an example running in realtime.

anneVideotracking

clean-up #23:

the screenshot below is of a simple little mac application i made in max/msp/jitter. it takes realtime input from a web or dv-camera, chops it into six regions and tracks activity in each of those regions separately. the result is sent over to supercollider via osc.

the analysis/tracking is just a simple average luminescence per frame. i.e. it takes the mean of all the red, green and blue values in one frame and then calculate the luma with (0.299*red)+(0.587*green)+(0.114*blue). the luma will be close to 0 for dark frames and close to 1 for very bright video frames.

to tune this system to produce maximal output, one should first make sure the camera sits still and has sufficient and stable light. then in the software there are colour, brightness and contrast controls to help get even better readings. (completely inverting all the colours might help in really dark places.)
the luma values (float 0.0-1.0) can be rounded off to nearest number and also smoothed out. this is often necessary to avoid flutter and noise. and most important - there is manual calibration of the luma values - either per region or globally.
to calibrate one should first empty the camera's view of any objects and then press the 'calibrate min' button in the lower left corner. then move some objects around to see what is the maximum reading. last put that number into the 'set max' numberbox. one can also calibrate each region separately with the min and max buttons next to the preview windows.

download the mac osx standalone from here.

and here is supercollider code to read the data and make some simple sounds out of it.

//to start: select all + enter
//to stop: cmd + .
(
n= 6;
s.latency= 0.05;
s.waitForBoot{
        var osc, dlast= 0.dup(n);
        d= {Bus.control(s, 1)}.dup(n);
        e= {Bus.control(s, 1)}.dup(n);
        osc= OSCresponder(nil, \anneVideoTracking, {|t, r, m|
                var index= m[1], val= m[2], diff= (val-dlast[index]).abs;
                //m.postln;
                d[index].set(val);
                e[index].set(diff);
                dlast.put(index, val);
        }).add;
        CmdPeriod.doOnce({osc.remove; d.do{|x| x.free}; e.do{|x| x.free}});
        SynthDef(\annetest, {
                var src= Mix({|i| SinOsc.ar(i*100+400, 0, LagUD.kr(In.kr(e[i].index), 0.01, 0.1))}.dup(n));
                Out.ar(0, Pan2.ar(src));
        }).send(s);
        s.sync;
        Synth(\annetest);
};
)

tweets

clean-up #22:

here are my best-of twitter tweets so far. see twitter.com/redFrik for the rest. with the hard limitation of 140 characters, it is really challenging to write a piece of supercollider code that fits and sounds good _and is interesting to listen to for more than a few seconds.

 

//--tweet0001

r{99.do{|i|x={Pan2.ar(SinOsc.ar(i+1,SinOsc.ar((i%9).div(3)*100+(i%9)+500),0.03),1.0.rand2)}.play;2.wait;x.release(25)}}.play//#SuperCollider

99 sine oscillators played one after the other with a two seconds interval. each oscillator lasts for 27 seconds. so the total duration is 99*2+27= 225 seconds. the oscillators are phase modulated with other sine oscillators with frequencies repeating in the number series: 500, 501, 502, 603, 604, 605, 706, 707, 708. the base frequencies of the 99 carrier oscillators slowly raise by one hertz from 1 to 99. the only random thing is the stereo panning position for each oscillator.

 

//--tweet0006

r{loop{x={GVerb.ar(MoogFF.ar(ClipNoise.ar*0.4,LFPar.kr({0.3.rand}!2,0,600,990)),9,9,1)}.play(s,0,19);3.wait;x.release}}.play//#SuperCollider

a clip noise generator runs through a moog filter and then a reverb. every third second there is a new noise added and each noise lasts for 22 seconds. each moog filter has two unique parabolic lfos that runs at a random rate between 0 and 0.3 hertz - each in one channel. at the most there are 8 number of overlapping noises playing at the same time. as there are so many reverbs playing here at once one needs to allocate more memory to sc server. something like this... Server.local.options.memSize= 32768; and then reboot the localhost server.

 

//--tweet0014

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

this one is completely deterministic although it is hard to believe when hearing it. a lot of nested feedbacking sine oscillators. nine parallel oscillators are mixed down to 1 and duplicated in left and right channels. each of the nine oscillators is frequency and feedback modulated but have a static amplitude of 1/9. the frequency modulator consist of yet more modulated feedbacking sine oscillators, while the feedback of the outer is only modulated with a single feedbacking sine oscillator running at 0.1 hertz. all in all there are 109 unit generators in total running in this tweet and it peaks at about 9.3% of my computer's cpu.

 

//--tweet0016 - tweet0019
these four all work the same way. they only differ in buffer size and what kind of oscillator is used for reading back samples from the buffer. there is not much progress over longer time but they do have characted and subtle though deterministic variation in the details.

 

play{b=LocalBuf(9e4,2).clear;i=Sweep.ar(BufRd.ar(2,b,Saw.ar(12,3e4,4e4)),9e4);BufWr.ar(Saw.ar([8,9]),b,i);BufRd.ar(2,b,i)/2}//#SuperCollider


 

play{b=LocalBuf(8e4,2).clear;i=Sweep.ar(BufRd.ar(2,b,Saw.ar(3.1,4e4,4e4)),8e4);BufWr.ar(Blip.ar([2,3]),b,i);BufRd.ar(2,b,i)}//#SuperCollider


 

play{b=LocalBuf(5e3,2).clear;i=Sweep.ar(BufRd.ar(2,b,Saw.ar(50,2e3,5e3)),6e4);BufWr.ar(Saw.ar([4,3]),b,i);BufRd.ar(2,b,i)/6}//#SuperCollider


 

play{b=LocalBuf(1e4,2).clear;i=Sweep.ar(BufRd.ar(2,b,Saw.ar(1,2e3,5e3)),5e5);BufWr.ar(Saw.ar([8,50]),b,i);BufRd.ar(2,b,i)/3}//#SuperCollider


 

//--tweet0020

play{a=LFPulse;b=(1..4);Mix(a.ar(a.ar(a.ar(a.ar(b/32)+1/8)+1*b)+(Mix(a.ar(b/64))+a.ar(4/b)*(a.ar(a.ar(b/8))*2+b))*100))/8!2}//#SuperCollider

this tweet is also totally deterministic and without any randomness. here a lot of nested square wave oscillators creates the complexity. basically there are 4 channels/voices mixed down to one and then duplicated in left and right channel. there are three levels deep nesting of frequency modulation with another set of square waves mixed and added.

 

//--tweet0021

r{{|j|a=play{sin(Decay.ar(Duty.ar(1/50,0,Dseq(flat({|i|asBinaryDigits(j+1*i)}!8),4),2),j+1*0.008))/2!2};5.12.wait}!256}.play//#SuperCollider

binary numbers from 0 to 255 form the rhythmic patterns in this tweet. each number first repeats 8 times - each time all the bits are shifted one position to the left. that creates an array of 64 ones and zeros. this array is then repeated four times. this is what makes it sound like a 4 x 4/4 bar theme (i.e. 4 bars per number). the total 64*4*256 binary digits are played in sequence and each digit lasts for 1/50th of a second. the total duration becomes 64*4*256/50= 1310.72 seconds. the sound is generated by the ones and the zeros directly. there is an exponential decay for these flipflop pulses that slowly increases throughout the 256 numbers. it starts with a decay time of 0.008 seconds and ends with 2.04 seconds. in the mp3 below only the numbers 0-31 are played.

 

//--tweet0024

{|j|r{{|i|x=sin(i/5+(j*5));Ndef(i%5+(j*5),{Pan2.ar(LFCub.ar(j*2+x*40+400+i)/15,i%5/2-1)}).play;wait(x.abs+0.5)}!500}.play}!5//#SuperCollider

another tweet without any randomness. there are five paralles routines and all do something 500 times. what they do is to define or redefine a node proxy. there are 25 proxies in total and each one contains a sine shaped oscillator panned to one out of four positions in the stereo field. the frequencies are climbing upwards in a slightly jaggered curve. the exact length is a bit complicated to calculate but it is around 575 seconds. in the end the proxies do not stop to play but just keeps the last assigned frequency and the whole soundscape becomes static.

Pages

Subscribe to RSS - supercollider