Merge branch 'clients/inter_client_comms' of https://bitbucket.org/flucoma/flucoma-supercollider into clients/inter_client_comms
commit
d5f692cf0e
@ -1,149 +0,0 @@
|
|||||||
// TB2 SC Playground V0
|
|
||||||
|
|
||||||
/*
|
|
||||||
Current stinkers:
|
|
||||||
1) Producing flat datapoints for FluidDataSet (i.e. flattening and cherry picking a multichannel buffer) takes bloody ages due to all the server syncing. I can't work out how to do it reliably outwith a Routine (which would certainly be quicker, to my mind)
|
|
||||||
2) Functions from the classes don't yet directly return things, and you have to access their return data through actions. This is partly because I don't know what the correct thing to do w/r/t blocking is, so I'm hoping GR will do it properly
|
|
||||||
*/
|
|
||||||
|
|
||||||
//STEP 0: start server
|
|
||||||
s.reboot;
|
|
||||||
|
|
||||||
if(s.hasBooted.not){"Warning: server not running".postln};
|
|
||||||
|
|
||||||
//STEP 1: Get some files
|
|
||||||
Buffer.freeAll;
|
|
||||||
(
|
|
||||||
FileDialog.new(fileMode:2,okFunc:{|x| ~path = x[0];
|
|
||||||
~audioBuffers = SoundFile.collectIntoBuffers(~path+/+'*',s);
|
|
||||||
~lookup = Dictionary(n:~audioBuffers.size);
|
|
||||||
~audioBuffers.do{|b| ~lookup.add(b.path->b)};
|
|
||||||
});
|
|
||||||
)
|
|
||||||
|
|
||||||
//STEP 2: Make a FluidDataSet
|
|
||||||
~dataset = FluidDataSet.new(s,"mfccs");
|
|
||||||
|
|
||||||
//STEP 3A: EITHER populate the dataset like so (and cry about how long the data point assembly takes)
|
|
||||||
(
|
|
||||||
Routine{
|
|
||||||
var tmpMFCCs = Buffer.new(s);
|
|
||||||
var tmpStats = Buffer.new(s);
|
|
||||||
var tmpFlat = Buffer.alloc(s,12 * 4 * 2, 1);//12 dims * 4 stats * 2 derivatives
|
|
||||||
s.sync;
|
|
||||||
~audioBuffers.do{|b|
|
|
||||||
("Analyzing" + b.path).postln;
|
|
||||||
FluidBufMFCC.process(s,b,features: tmpMFCCs);
|
|
||||||
FluidBufStats.process(s,source:tmpMFCCs, stats: tmpStats,numDerivs:1);
|
|
||||||
"stats".postln;
|
|
||||||
12.do{|i|
|
|
||||||
//This takes ages becayse of server syncing :-(
|
|
||||||
FluidBufCompose.process(s,tmpStats,0,2, i+1,1, destination: tmpFlat, destStartFrame: (i*8));
|
|
||||||
FluidBufCompose.process(s,tmpStats,4,1, i+1,1, destination: tmpFlat, destStartFrame: (i*8) + 2);
|
|
||||||
FluidBufCompose.process(s,tmpStats,6,3, i+1,1, destination:tmpFlat, destStartFrame: (i*8) + 3);
|
|
||||||
FluidBufCompose.process(s,tmpStats,11,1, i+1,1, destination: tmpFlat, destStartFrame: (i*8) + 6);
|
|
||||||
FluidBufCompose.process(s,tmpStats,13,1, i+1,1, destination:tmpFlat, destStartFrame: (i*8) + 7);
|
|
||||||
};
|
|
||||||
~dataset.addPoint(b.path,tmpFlat);
|
|
||||||
};
|
|
||||||
s.sync;
|
|
||||||
"Done".postln;
|
|
||||||
tmpFlat.free;
|
|
||||||
tmpStats.free;
|
|
||||||
tmpMFCCs.free;
|
|
||||||
}.play
|
|
||||||
)
|
|
||||||
|
|
||||||
//STEP 3B: OR populate the dataset with the flattening happening in langage side (much faster for now)
|
|
||||||
(
|
|
||||||
Routine{
|
|
||||||
var tmpMFCCs = Buffer.new(s);
|
|
||||||
var tmpStats = Buffer.new(s);
|
|
||||||
var langStats;
|
|
||||||
var langFlat;
|
|
||||||
var tmpFlat = Buffer.alloc(s,12 * 4 * 2, 1); //12 dims * 4 stats * 2 derivatives
|
|
||||||
s.sync;
|
|
||||||
~audioBuffers.do{|b|
|
|
||||||
("Analyzing" + b.path).postln;
|
|
||||||
FluidBufMFCC.process(s,b,features: tmpMFCCs);
|
|
||||||
FluidBufStats.process(s,source:tmpMFCCs, stats: tmpStats,numDerivs:1);
|
|
||||||
tmpStats.getn(0,182,{|y| langStats = y;});
|
|
||||||
s.sync;
|
|
||||||
"stats".postln;
|
|
||||||
langFlat = Array.new();
|
|
||||||
//taking the mean, std, min and max, and the mean, std, min and max of the first derivative, of each MFCCs except coeff 0 to dismiss amplitude)
|
|
||||||
[0,1,4,6,7,8,11,13].do({|i| var j,k; j =((i*13)+1); k = j + 11;langFlat = langFlat ++ langStats[j..k]});
|
|
||||||
tmpFlat.setn(0,langFlat);
|
|
||||||
s.sync;
|
|
||||||
~dataset.addPoint(b.path,tmpFlat);
|
|
||||||
};
|
|
||||||
s.sync;
|
|
||||||
"Done".postln;
|
|
||||||
tmpStats.free;
|
|
||||||
tmpMFCCs.free;
|
|
||||||
tmpFlat.free;
|
|
||||||
}.play
|
|
||||||
)
|
|
||||||
|
|
||||||
//check
|
|
||||||
~dataset.size({|x| x.postln})
|
|
||||||
|
|
||||||
//save
|
|
||||||
(
|
|
||||||
FileDialog.new(fileMode: 0, acceptMode: 1, okFunc:{|x| var file = x[0];
|
|
||||||
//if the file exists and is a json, delete it
|
|
||||||
if ((file.splitext[1] == "json") && (File.existsCaseSensitive(file)), {File.delete(file);"File Overwritten".postln;});
|
|
||||||
//if not json, make it so
|
|
||||||
if (file.splitext[1] != "json", {file = file ++ ".json";});
|
|
||||||
// then write
|
|
||||||
~dataset.write(file);
|
|
||||||
});
|
|
||||||
)
|
|
||||||
|
|
||||||
//STEP 3C: OR load in one you rolled earlier
|
|
||||||
FileDialog.new(fileMode: 0, acceptMode: 0, okFunc:{|x| ~dataset.read(x[0])});
|
|
||||||
|
|
||||||
//peek
|
|
||||||
c = Buffer.new(s)
|
|
||||||
~dataset.getPoint(~audioBuffers[3].path,c, { c.getn(0,96,{|x| x.postln})})
|
|
||||||
|
|
||||||
/*************************************/
|
|
||||||
//FluidKDTree
|
|
||||||
~kdtree = FluidKDTree.new(s)
|
|
||||||
~kdtree.fit(~dataset,action:{"fit".postln})
|
|
||||||
|
|
||||||
//match
|
|
||||||
~kdtree.kNearest(c,5,{|x| ~matches = x;})
|
|
||||||
~kdtree.kNearestDist(c,5,{|x| x.postln})
|
|
||||||
|
|
||||||
~lookup[~matches[4]].postln
|
|
||||||
|
|
||||||
/*************************************/
|
|
||||||
//FluidKMeans
|
|
||||||
~kMeans= FluidKMeans.new(s)
|
|
||||||
~kMeans.fit(~dataset,k:5,action:{"fit".postln})
|
|
||||||
|
|
||||||
|
|
||||||
// predicts in which cluster a point would be
|
|
||||||
~kMeans.predictPoint(c,{|x|x.postln})
|
|
||||||
|
|
||||||
// predicts which cluster each points of a dataset would be in, as a label
|
|
||||||
~labels = FluidLabelSet.new(s,"clusters")
|
|
||||||
~kMeans.predict(~dataset,~labels, {|x| x.postln})
|
|
||||||
|
|
||||||
~labels.getLabel(~audioBuffers[2].path,action:{|c| c.postln})
|
|
||||||
|
|
||||||
//query each item
|
|
||||||
(
|
|
||||||
Routine{
|
|
||||||
~labels.size({|x|x.do {|i|
|
|
||||||
~audioBuffers[i].path.postln;
|
|
||||||
~labels.getLabel(~audioBuffers[i].path,action:{|c| c.postln});
|
|
||||||
s.sync;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}.play
|
|
||||||
)
|
|
||||||
|
|
||||||
//labelset can be written as json
|
|
||||||
~labels.write(~path+/+"labels.json")
|
|
||||||
Loading…
Reference in New Issue