// soni(a)c hair // strang based soundreactive particle systems // author: info@toxi.co.uk // requires SONIA v2.4 or later by mr.amit pitaru // http://pitaru.com/sonia/ Hair[] h; int hCount=0; float XSPREAD=8; float YSPREAD=200; float HAIR_MOVEMENT=0.15; float w2,h2; // audio input sensitivity threshold float sensThresh=0.15; float prevLevel; void setup() { size(200,323); w2=width*0.5; h2=height*0.5; ellipseMode(CENTER_DIAMETER); rectMode(CORNERS); h=new Hair[800]; liveInput.start(512); } void loop() { background(220,208,192); // compute input level derivative (delta level to previous frame) // hair will only react if the input volume is changing rapidly, // based on the delta level and the sensitivity threshold // if input volume is clipping (too loud) the delta will be reduced // and might not reach threshold even though the audio signal is very strong // in this case please reduce input gain via the system control panel float currLevel = float(liveInput.getLevel(0)+liveInput.getLevel(1)); float deltaLevel=currLevel-prevLevel; // show current input and delta level stroke(160,148,132); line(1,height,1,height-deltaLevel*height); line(3,height,3,height-currLevel*h2); prevLevel=currLevel; // switch to 3d mode translate(w2,h2,0); if (hCountsensThresh) { for(int i=0; i0.75) { baseR=baseG=baseB=random(40,80); shiftR=shiftG=shiftB=random(4,10); } else { baseR=random(60,88); baseG=baseR*0.5; baseB=0; shiftR=random(4,10); shiftG=shiftR*0.5; shiftB=0.5; } // build initial segments nVert=0; addSegment(x,y,z); while(nVert0) { d=1/d; nx*=d; ny*=d; nz*=d; } // add to vertex list addSegment(x+=seg_len*nx,y+=seg_len*ny,z+=seg_len*nz); } } void addSegment(float x,float y, float z) { vx[nVert]=x; vy[nVert]=y; vz[nVert++]=z; } // align hair to new direction vector // applies smoothness, curling and gravity void update(float nnx,float nny, float nnz) { // increase hair length seg_len+=(max_len-seg_len)*grow_speed; // add new direction to existing vector nx+=nnx; ny+=nny; nz+=nnz; // normalize new vector float d=sqrt(nx*nx+ny*ny+nz*nz); if (d>0) d=(1/d)*seg_len; nx*=d; ny*=d; nz*=d; // iterate and update all vertices with decreasing effect float sm=smoothness*(seg_len/max_len); float grav=0; curlAngle=0; for(int i=1; i