You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.9 KiB
Python
165 lines
4.9 KiB
Python
FluidLoadFolder {
|
|
var path, labelFunc,channelFunc;
|
|
var < files;
|
|
var < index;
|
|
var < buffer;
|
|
|
|
*new{ |path, labelFunc, channelFunc |
|
|
^super.newCopyArgs(path, labelFunc,channelFunc);
|
|
}
|
|
|
|
play { |server, action|
|
|
var sizes,channels,maxChan, startEnd,counter;
|
|
server ?? server = Server.default;
|
|
files = SoundFile.collect(path +/+ '*');
|
|
sizes = files.collect{|f|f.numFrames()};
|
|
channels = files.collect{|f| f.numChannels()};
|
|
startEnd = sizes.inject([0],{|a,b| a ++ (b + a[a.size - 1])}).slide(2).clump(2);
|
|
maxChan = channels[channels.maxIndex];
|
|
counter = 0;
|
|
index = IdentityDictionary();
|
|
forkIfNeeded{
|
|
buffer = Buffer.alloc(server,sizes.reduce('+'),maxChan);
|
|
server.sync;
|
|
buffer.updateInfo;
|
|
buffer.query;
|
|
server.sync;
|
|
this.files.do{|f,i|
|
|
var channelMap,label,entry;
|
|
OSCFunc({
|
|
if(labelFunc.notNil)
|
|
{ label = labelFunc.value(path,i) }
|
|
{ label = (f.path.basename).asSymbol };
|
|
entry = IdentityDictionary();
|
|
entry.add(\bounds->startEnd[i]);
|
|
entry.add(\numchans->f.numChannels);
|
|
entry.add(\sr->f.sampleRate);
|
|
index.add(label->entry);
|
|
counter = counter + 1;
|
|
if(counter == (files.size)) {action !? action.value(index)};
|
|
},"/done",server.addr,argTemplate:["/b_readChannel"]).oneShot;
|
|
if(channelFunc.notNil)
|
|
{ channelMap = channelFunc.value(channels[i],maxChan,i) }
|
|
{ channelMap = Array.series(channels[i]).wrapExtend(maxChan) };
|
|
buffer.readChannel(f.path,bufStartFrame:startEnd[i][0], channels:channelMap);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
FluidSliceCorpus {
|
|
var < sliceFunc, labelFunc;
|
|
var < index;
|
|
|
|
*new { |sliceFunc, labelFunc|
|
|
^super.newCopyArgs(sliceFunc,labelFunc);
|
|
}
|
|
|
|
play{ |server,sourceBuffer,bufIdx, action|
|
|
var counter, tmpIndices,perf,jobs,total,uid, completed, pointstotal;
|
|
uid = UniqueID.next;
|
|
sourceBuffer ?? {"No buffer to slice".error; ^nil};
|
|
bufIdx ?? {"No slice point dictionary passed".error;^nil};
|
|
server ?? {server = Server.default};
|
|
index = IdentityDictionary();
|
|
counter = 0;
|
|
completed = 0;
|
|
jobs = List.newFrom(bufIdx.keys);
|
|
total = jobs.size;
|
|
pointstotal = 0;
|
|
perf = { |tmpIndices|
|
|
var idx,v,k = jobs.pop;
|
|
v = bufIdx[k];
|
|
counter = counter + 1;
|
|
idx = counter;
|
|
("Slicing" + counter ++ "/" ++ total).postln;
|
|
OSCFunc({
|
|
tmpIndices.loadToFloatArray(action:{ |a|
|
|
var sliceindex = 1;
|
|
completed = completed + 1;
|
|
("FluidSliceCorpus:" + ( completed.asString ++ "/" ++ total)).postln;
|
|
if(a[0] != -1){
|
|
var rawPoints = Array.newFrom(a).asInteger;
|
|
if(rawPoints[0] != [v[\bounds][0]]){rawPoints = [v[\bounds][0]] ++ rawPoints};
|
|
if(rawPoints.last != [v[\bounds][1]]){rawPoints=rawPoints ++ [v[\bounds][1]]};
|
|
rawPoints.doAdjacentPairs{|a,b|
|
|
var dict;
|
|
if ((b - a) >= 1){
|
|
dict = IdentityDictionary();
|
|
dict.putAll(v);
|
|
dict[\bounds] = [a,b];
|
|
dict[\prefix] = k;
|
|
dict[\index] = sliceindex;
|
|
index.add(((k ++ "-" ++sliceindex).asSymbol)->dict);
|
|
sliceindex = sliceindex + 1;
|
|
}
|
|
}
|
|
}{
|
|
var dict = IdentityDictionary();
|
|
dict.putAll(v);
|
|
index.add((k ++ "-1").asSymbol->dict);
|
|
};
|
|
if(jobs.size > 0){perf.value(tmpIndices)}{ tmpIndices.free };
|
|
if(completed == total) {action !? action.value(index)};
|
|
})
|
|
},'/doneslice' ++ uid ++ counter,server.addr).oneShot;
|
|
{
|
|
var numframes,onsets;
|
|
numframes = v[\bounds].reverse.reduce('-');
|
|
onsets = sliceFunc.value(sourceBuffer, v[\bounds][0],numframes,tmpIndices);
|
|
SendReply.kr(Done.kr(onsets),'/doneslice' ++ uid ++ idx);
|
|
FreeSelfWhenDone.kr(onsets);
|
|
}.play;
|
|
};
|
|
4.do{perf.value(Buffer.new)};
|
|
}
|
|
}
|
|
|
|
FluidProcessSlices{
|
|
var < featureFunc;
|
|
|
|
*new { |featureFunc|
|
|
^super.newCopyArgs(featureFunc);
|
|
}
|
|
|
|
play{ |server, sourceBuffer, bufIdx, action, tasks = 4|
|
|
var counter,perf,jobs,total,uid, completed;
|
|
|
|
sourceBuffer ?? {"No buffer to slice".error; ^nil};
|
|
bufIdx ?? {"No slice point dictionary passed".error;^nil};
|
|
server ?? {server = Server.default};
|
|
|
|
uid = UniqueID.next;
|
|
jobs = List.newFrom(bufIdx.keys);
|
|
total = jobs.size;
|
|
counter = 0;
|
|
completed = 0;
|
|
perf = {|jobID|
|
|
var idx,v, k = jobs.pop;
|
|
v = bufIdx[k];
|
|
counter = counter + 1;
|
|
("Processing" + counter ++ "/" ++ total).postln;
|
|
idx = counter;
|
|
v[\allindex] = counter;
|
|
v[\voice] = jobID;
|
|
OSCFunc({
|
|
completed = completed + 1;
|
|
("FluidProcessSlices:" + (completed.asString ++ "/" ++ total)).postln;
|
|
if(jobs.size > 0){perf.value(jobID)};
|
|
if(completed == total){action !? action.value(v);};
|
|
},"/doneFeature" ++ uid ++ counter,server.addr).oneShot;
|
|
|
|
{
|
|
var numframes,feature;
|
|
numframes = v[\bounds].reverse.reduce('-');
|
|
feature = featureFunc.value(sourceBuffer, v[\bounds][0], numframes, k->v);
|
|
SendReply.kr(Done.kr(feature),'/doneFeature' ++ uid ++ idx);
|
|
FreeSelfWhenDone.kr(feature);
|
|
}.play(server);
|
|
};
|
|
tasks ?? {tasks = 4};
|
|
tasks.asInteger.min(jobs.size).do{|jobIDs|perf.value(jobIDs)};
|
|
}
|
|
}
|