| 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);\
\
)\
\
}
|