Hi, I found the code! It was an email from Nick Nilson in 12/03/2013. The code need to be update. Don’t have time to do it now but maybe next week. In the meantime if anyone wants to do it… All the best, p |
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540 {\fonttbl\f0\fnil\fcharset0 Monaco;} {\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red0\green0\blue191;\red96\green96\blue96; \red191\green0\blue0;\red0\green115\blue0;} \deftab560 \pard\pardeftab560\ql\qnatural \f0\fs18 \cf2 p = \cf3 PathName\cf2 (\cf4 "/sounds/gran torso.aiff"\cf2 )\ \ (\ ~load = \{\cf3 |path,auto_segment=true|\cf2 \ \cf3 var\cf2 name,event=(),buffer,analysis,frames,beatdata,segments,pathName,parent_folder;\ fork\{\ pathName = \cf3 PathName\cf2 (path);\ parent_folder = pathName.pathOnly;\ name = pathName.fileNameWithoutExtension.split($ ).collect(\{\cf3 |x|\cf2 x\}).join;\ event.name = name;\ \cf4 "Loading Buffer"\cf2 .postln;\ buffer = \cf3 Buffer\cf2 .readChannel(s,path,channels:[0]);\ s.sync;\ event.buf = buffer;\ \cf4 "Buffer read"\cf2 .postln;\ if ((parent_folder++\cf4 "*"\cf2 ).pathMatch.find([parent_folder++pathName.fileNameWithoutExtension++\cf4 ".scmirZ"\cf2 ]).notNil) \{\ \cf4 "Found Analysis File...loading"\cf2 .postln;\ analysis = \cf3 SCMIRAudioFile\cf2 .newFromZ(path);\ analysis.load;\ \} \{\ \cf4 "New file...beginning analysis"\cf2 .postln;\ analysis = \cf3 SCMIRAudioFile\cf2 (path, [[\cf3 MFCC\cf2 ,4],[\cf3 SensoryDissonance\cf2 ],[\cf3 Loudness\cf2 ]]); \ analysis.extractFeatures(); \ analysis.extractBeats();\ analysis.save;\ \cf4 "File Saved"\cf2 .postln \ \};\ event.analysis = analysis;\ if (auto_segment) \{\ \cf5 //automatic segmentation\cf2 \ event.beatdata = analysis.beatdata;\ analysis.gatherFeaturesBySegments(event.beatdata, \cf3 true\cf2 ); \ n = analysis.numfeatures;\ event.frames = analysis.featuredata.clump(n);\ event.segments = \cf3 nil\cf2 ; \ \} \{\ \cf5 //blind segmentation\cf2 \ event.segments = (0,0.125..analysis.duration);\ analysis.gatherFeaturesBySegments(event.segments, \cf3 true\cf2 ); \ analysis.numsegments;\ n = analysis.numfeatures;\ event.frames = analysis.featuredata.clump(n); \ \};\ \cf4 "Processing Finished...analysis ready for use."\cf2 .postln;\ \};\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab560\ql\qnatural\pardirnatural \cf2 \cf3 SynthDef\cf2 (\cf6 \\grains\cf2 ,\{\cf3 |out,buf,pos,dur,rate,gate=1,pch=1,amp=1|\cf2 \ \cf3 var\cf2 son,trig;\ trig = \cf3 Dust\cf2 .ar(rate);\ son = \cf3 TGrains\cf2 .ar(2,trig,buf,pch,pos,dur);\ \cf3 Out\cf2 .ar(out,son*\cf3 Env\cf2 .asr.kr(2,gate))\ \}).add;\ \pard\pardeftab560\ql\qnatural \cf2 event\ \})\ \ ~data = ~load.(\cf4 "/sounds/gran torso.aiff"\cf2 ,\cf3 false\cf2 )\ \ \cf5 //-requires KDTree quark\cf2 \ \cf5 //Quarks.install("KDTree")\cf2 \ \ \cf5 //!main\cf2 \ (\ \cf3 var\cf2 w,but,f,width,isPlaying=\{\cf3 false\cf2 \}!x.size,osc,height;\ \cf3 var\cf2 plot;\ \ plot = \{\cf3 |w,buf,frames,segments,beatdata|\cf2 \ \cf3 var\cf2 radius=\{\cf3 nil\cf2 \}!frames.size,points=\cf3 List\cf2 (),check_mouse,draw_tuio=\cf3 true\cf2 ;\ \cf3 var\cf2 kdtree,grains;\ \cf3 var\cf2 map_patterns=\cf3 List\cf2 (),view;\ \ grains = \cf3 Synth\cf2 (\cf6 \\grains\cf2 ,[\cf6 \\buf\cf2 ,buf,\cf6 \\dur\cf2 ,2,\cf6 \\rate\cf2 ,35,\cf6 \\pos\cf2 ,0,\cf6 \\amp\cf2 ,0]);\ \ width = w.bounds.width;\ height = w.bounds.height;\ \ frames.do\{\cf3 |vector,index|\cf2 \ radius[index] = (15*vector[4].linexp(0,1,0.8,2))*vector.last.linexp(0,1,0.285,1.0);\ points.add([\cf3 Rect\cf2 ((vector[0]+vector[4]*1.25)*(width*vector[0]),((vector[1]).linlin(0,1,0.001,1.0)*height)+50,radius[index],radius[index]).center,index]);\ \};\ view = \cf3 SCUserView\cf2 (w,w.view.bounds)\ .mouseMoveAction_(\{\cf3 |v,x,y|\cf2 check_mouse.(x,y)\})\ .mouseDownAction_(\{\cf3 |v,x,y|\cf2 check_mouse.(x,y)\})\ .background_(\cf3 Color\cf2 .clear)\ .drawFunc_(\{\ \cf3 var\cf2 center;\ frames.do\{\cf3 |vector,index|\cf2 \ \cf3 Pen\cf2 .fillColor = \cf3 Color\cf2 .new(*vector[0..3]);\ \cf3 Pen\cf2 .smoothing_(\cf3 true\cf2 );\ center = \cf3 Rect\cf2 ((vector[0]+vector[4]*1.25)*(width*vector[0]),((vector[1]).linlin(0,1,0.001,1.0)*height)+50,radius[index],radius[index]).center;\ \cf3 Pen\cf2 .addArc(center,radius[index]*0.5,pi,2pi);\ \cf3 Pen\cf2 .fill;\ \}; \ \ \});\ \ w.front;\ \ kdtree = \cf3 KDTree\cf2 (points.collect(\{\cf3 |array,i|\cf2 array[0].asArray++i.asSymbol\}),lastIsLabel:\cf3 true\cf2 );\ \ check_mouse = \{\cf3 |x,y|\cf2 \ \cf3 var\cf2 p = \cf3 Point\cf2 (x,y),index,nearest,dist;\ nearest = kdtree.nearest([x,y])[0];\ index = nearest.label.asInteger;\ nearest = nearest.location.asPoint;\ dist = nearest.dist(p);\ if (dist <= (radius[index]*1)) \{\ grains.set(\cf6 \\amp\cf2 ,1);\ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardeftab560\ql\qnatural\pardirnatural \cf2 if (segments==\cf3 nil\cf2 ) \{\ grains.set(\cf6 \\pos\cf2 ,beatdata[index+rrand(-2,2)])\ \} \{\ grains.set(\cf6 \\pos\cf2 ,segments[index+rrand(-2,2)])\ \}\ \}\ \};\ \ \pard\pardeftab560\ql\qnatural \cf2 w.onClose_(\{grains.release\});\ \};\ \ w = \cf3 SCWindow\cf2 (\cf4 "Scatter"\cf2 ,\cf3 Rect\cf2 (250,250,800,500)).front;\ w.view.background_(\cf3 Color\cf2 .black);\ plot.(w,~data.buf,~data.frames,~data.segments,~data.beatdata);\ \ )\ \ }
|