diff --git a/include/wrapper/Realtime.hpp b/include/wrapper/Realtime.hpp index e6e183a..64bff83 100644 --- a/include/wrapper/Realtime.hpp +++ b/include/wrapper/Realtime.hpp @@ -34,8 +34,9 @@ public: static void setup(InterfaceTable* ft, const char* name) { - ft->fDefineUnitCmd(name, "latency", doLatency); + registerUnit(ft,name); + ft->fDefineUnitCmd(name, "latency", doLatency); } static void doLatency(Unit* unit, sc_msg_iter*) @@ -47,7 +48,7 @@ public: std::stringstream ss; ss << '/' << Wrapper::getName() << "_latency"; - std::cout << ss.str() << std::endl; + // std::cout << ss.str() << ": " << l[0] << std::endl; ft->fSendNodeReply(&unit->mParent->mNode, -1, ss.str().c_str(), 1, l); } diff --git a/release-packaging/Classes/FluidBufLoudness.sc b/release-packaging/Classes/FluidBufLoudness.sc index 0d3644e..8b15d68 100644 --- a/release-packaging/Classes/FluidBufLoudness.sc +++ b/release-packaging/Classes/FluidBufLoudness.sc @@ -1,6 +1,6 @@ FluidBufLoudness : FluidBufProcessor{ - *kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, trig = 1, blocking = 0| - + *kr { |source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, padding = 1, trig = 1, blocking = 0| + var maxwindowSize = windowSize.nextPowerOfTwo; source = source.asUGenInput; @@ -8,12 +8,12 @@ FluidBufLoudness : FluidBufProcessor{ source.isNil.if {"FluidBufPitch: Invalid source buffer".throw}; features.isNil.if {"FluidBufPitch: Invalid features buffer".throw}; - - ^FluidProxyUgen.kr(\FluidBufLoudnessTrigger, -1, source, startFrame, numFrames, startChan, numChans, features, kWeighting, truePeak, windowSize, hopSize, maxwindowSize, trig, blocking); + + ^FluidProxyUgen.kr(\FluidBufLoudnessTrigger, -1, source, startFrame, numFrames, startChan, numChans, features,padding, kWeighting, truePeak, windowSize, hopSize, maxwindowSize, trig, blocking); } - *process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, freeWhenDone = true, action| - + *process { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, padding = 1, freeWhenDone = true, action| + var maxwindowSize = windowSize.nextPowerOfTwo; source = source.asUGenInput; @@ -21,16 +21,16 @@ FluidBufLoudness : FluidBufProcessor{ source.isNil.if {"FluidBufPitch: Invalid source buffer".throw}; features.isNil.if {"FluidBufPitch: Invalid features buffer".throw}; - + ^this.new( server, nil, [features] ).processList( - [source, startFrame, numFrames, startChan, numChans, features, kWeighting, truePeak, windowSize, hopSize, maxwindowSize,0],freeWhenDone,action + [source, startFrame, numFrames, startChan, numChans, features, padding, kWeighting, truePeak, windowSize, hopSize, maxwindowSize,0],freeWhenDone,action ); } - *processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, freeWhenDone = true, action| - + *processBlocking { |server, source, startFrame = 0, numFrames = -1, startChan = 0, numChans = -1, features, kWeighting = 1, truePeak = 1, windowSize = 1024, hopSize = 512, padding = 1, freeWhenDone = true, action| + var maxwindowSize = windowSize.nextPowerOfTwo; source = source.asUGenInput; @@ -38,11 +38,11 @@ FluidBufLoudness : FluidBufProcessor{ source.isNil.if {"FluidBufPitch: Invalid source buffer".throw}; features.isNil.if {"FluidBufPitch: Invalid features buffer".throw}; - + ^this.new( server, nil, [features] ).processList( - [source, startFrame, numFrames, startChan, numChans, features, kWeighting, truePeak, windowSize, hopSize, maxwindowSize,1],freeWhenDone,action + [source, startFrame, numFrames, startChan, numChans, features,padding, kWeighting, truePeak, windowSize, hopSize, maxwindowSize,1],freeWhenDone,action ); } } diff --git a/release-packaging/Examples/dataset/0-demo-dataset-maker-utilities.scd b/release-packaging/Examples/dataset/0-demo-dataset-maker-utilities.scd index 9ceb017..d07a730 100644 --- a/release-packaging/Examples/dataset/0-demo-dataset-maker-utilities.scd +++ b/release-packaging/Examples/dataset/0-demo-dataset-maker-utilities.scd @@ -23,7 +23,7 @@ mfcc = FluidBufMFCC.kr(src, startFrame:start, numFrames:num, numChans:1, features:~mfccbuf[voice], trig:1, blocking: 1); stats = FluidBufStats.kr(~mfccbuf[voice], stats:~statsbuf[voice], trig:Done.kr(mfcc), blocking: 1); flatten = FluidBufFlatten.kr(~statsbuf[voice], ~flatbuf[voice], trig:Done.kr(stats), blocking: 1); - writer = FluidDataSetWr.kr(~ds, label, -1, ~flatbuf[voice], trig: Done.kr(flatten), blocking: 1) + writer = FluidDataSetWr.kr(~ds, label, nil, ~flatbuf[voice], trig: Done.kr(flatten), blocking: 1) }); ) @@ -166,4 +166,4 @@ Routine{ dur.wait; }; }.play; -) \ No newline at end of file +) diff --git a/release-packaging/Examples/dataset/1-learning examples/10a-weighted-MFCCs-comparison.scd b/release-packaging/Examples/dataset/1-learning examples/10a-weighted-MFCCs-comparison.scd index 8ed2aa0..1dc091b 100644 --- a/release-packaging/Examples/dataset/1-learning examples/10a-weighted-MFCCs-comparison.scd +++ b/release-packaging/Examples/dataset/1-learning examples/10a-weighted-MFCCs-comparison.scd @@ -23,10 +23,10 @@ var label, voice, mfcc, stats, flatten; label = data.key; voice = data.value[\voice]; - mfcc = FluidBufMFCC.kr(src,startFrame:start,numFrames:num,numChans:1,features:~mfccbuf[voice],trig:1,blocking: 1); + mfcc = FluidBufMFCC.kr(src, startFrame:start, numFrames:num, numChans:1, features:~mfccbuf[voice], padding: 2, trig:1, blocking: 1); stats = FluidBufStats.kr(~mfccbuf[voice], stats:~statsbuf[voice], numDerivs: 1, trig:Done.kr(mfcc), blocking: 1); - flatten = FluidBufFlatten.kr(~statsbuf[voice],~flatbuf[voice],trig:Done.kr(stats),blocking: 1); - FluidDataSetWr.kr(~ds,label, -1, ~flatbuf[voice], Done.kr(flatten),blocking: 1); + flatten = FluidBufFlatten.kr(~statsbuf[voice], ~flatbuf[voice], trig:Done.kr(stats), blocking: 1); + FluidDataSetWr.kr(~ds, label, nil, ~flatbuf[voice], Done.kr(flatten), blocking: 1); }); // here we make another processor, this time with doing an amplitude weighing @@ -34,12 +34,12 @@ var label, voice, loud, weights, mfcc, stats, flatten; label = data.key; voice = data.value[\voice]; - mfcc = FluidBufMFCC.kr(src,startFrame:start,numFrames:num,numChans:1,features:~mfccbuf[voice],trig:1,blocking: 1); - loud = FluidBufLoudness.kr(src,startFrame:start,numFrames:num,numChans:1,features:~loudbuf[voice],trig:Done.kr(mfcc),blocking: 1); - weights = FluidBufScale.kr(~loudbuf[voice],numChans: 1,destination: ~weightbuf[voice],inputLow: -70,inputHigh: 0, trig: Done.kr(loud),blocking: 1); + mfcc = FluidBufMFCC.kr(src, startFrame:start, numFrames:num, numChans:1, features:~mfccbuf[voice], padding: 2, trig:1, blocking: 1); + loud = FluidBufLoudness.kr(src, startFrame:start, numFrames:num, numChans:1, features:~loudbuf[voice], padding: 2, trig:Done.kr(mfcc), blocking: 1); + weights = FluidBufScale.kr(~loudbuf[voice], numChans: 1, destination: ~weightbuf[voice], inputLow: -70, inputHigh: 0, trig: Done.kr(loud), blocking: 1); stats = FluidBufStats.kr(~mfccbuf[voice], stats:~statsbuf[voice], numDerivs: 1, weights: ~weightbuf[voice], trig:Done.kr(weights), blocking: 1); - flatten = FluidBufFlatten.kr(~statsbuf[voice],~flatbuf[voice],trig:Done.kr(stats),blocking: 1); - FluidDataSetWr.kr(~dsW,label, -1, ~flatbuf[voice], Done.kr(flatten),blocking: 1); + flatten = FluidBufFlatten.kr(~statsbuf[voice], ~flatbuf[voice], trig:Done.kr(stats), blocking: 1); + FluidDataSetWr.kr(~dsW, label, nil, ~flatbuf[voice], Done.kr(flatten), blocking: 1); }); // and here we make a little processor for loudness if we want to poke at it @@ -47,10 +47,10 @@ var label, voice, loud, stats, flatten; label = data.key; voice = data.value[\voice]; - loud = FluidBufLoudness.kr(src,startFrame:start,numFrames:num,numChans:1,features:~mfccbuf[voice],trig:1,blocking: 1); + loud = FluidBufLoudness.kr(src, startFrame:start, numFrames:num, numChans:1, features:~mfccbuf[voice], trig:1, padding: 2, blocking: 1); stats = FluidBufStats.kr(~mfccbuf[voice], stats:~statsbuf[voice], numDerivs: 1, trig:Done.kr(loud), blocking: 1); - flatten = FluidBufFlatten.kr(~statsbuf[voice],~flatbuf[voice],trig:Done.kr(stats),blocking: 1); - FluidDataSetWr.kr(~dsL,label, -1, ~flatbuf[voice], Done.kr(flatten),blocking: 1); + flatten = FluidBufFlatten.kr(~statsbuf[voice], ~flatbuf[voice], trig:Done.kr(stats), blocking: 1); + FluidDataSetWr.kr(~dsL, label, nil, ~flatbuf[voice], Done.kr(flatten), blocking: 1); }); ) @@ -150,10 +150,10 @@ FluidBufCompose.process(s,~loader.buffer,a,(b-a),numChans: 1, destination: ~targ ( { var loud, weights, mfcc, stats, flatten, stats2, written; - mfcc = FluidBufMFCC.kr(~targetsound,features:~mfccbuf[0],trig:1); + mfcc = FluidBufMFCC.kr(~targetsound,features:~mfccbuf[0],padding: 2, trig:1); stats = FluidBufStats.kr(~mfccbuf[0],stats:~statsbuf[0], numDerivs: 1,trig:Done.kr(mfcc)); flatten = FluidBufFlatten.kr(~statsbuf[0],~flatbuf[0],trig:Done.kr(stats)); - loud = FluidBufLoudness.kr(~targetsound,features:~loudbuf[0],trig:Done.kr(flatten),blocking: 1); + loud = FluidBufLoudness.kr(~targetsound,features:~loudbuf[0],padding: 2,trig:Done.kr(flatten),blocking: 1); weights = FluidBufScale.kr(~loudbuf[0],numChans: 1,destination: ~weightbuf[0],inputLow: -70,inputHigh: 0,trig: Done.kr(loud),blocking: 1); stats2 = FluidBufStats.kr(~mfccbuf[0],stats:~statsbuf[0], numDerivs: 1, weights: ~weightbuf[0], trig:Done.kr(weights),blocking: 1); written = FluidBufFlatten.kr(~statsbuf[0],~flatbuf[1],trig:Done.kr(stats2)); diff --git a/release-packaging/Examples/dataset/1-learning examples/11-compositing-datasets.scd b/release-packaging/Examples/dataset/1-learning examples/11-compositing-datasets.scd index 9b55fcf..5b3aee6 100644 --- a/release-packaging/Examples/dataset/1-learning examples/11-compositing-datasets.scd +++ b/release-packaging/Examples/dataset/1-learning examples/11-compositing-datasets.scd @@ -38,19 +38,19 @@ pitchweights = FluidBufThresh.kr(~pitchbuf[voice], numChans: 1, startChan: 1, destination: ~weightPitchbuf[voice], threshold: 0.7, trig:Done.kr(pitch), blocking: 1);//pull down low conf pitchstats = FluidBufStats.kr(~pitchbuf[voice], stats:~statsPitchbuf[voice], numDerivs: 1, weights: ~weightPitchbuf[voice], outliersCutoff: 1.5, trig:Done.kr(pitchweights), blocking: 1); pitchflat = FluidBufFlatten.kr(~statsPitchbuf[voice],~flatPitchbuf[voice],trig:Done.kr(pitchstats),blocking: 1); - writePitch = FluidDataSetWr.kr(~pitchDS,label, -1, ~flatPitchbuf[voice], Done.kr(pitchflat),blocking: 1); + writePitch = FluidDataSetWr.kr(~pitchDS,label, nil, ~flatPitchbuf[voice], Done.kr(pitchflat),blocking: 1); // the mfcc need loudness to weigh, so let's start with that loud = FluidBufLoudness.kr(src,startFrame:start, numFrames:num, numChans:1, features:~loudbuf[voice], trig:Done.kr(writePitch), blocking: 1);//here trig was 1 //we can now flatten and write Loudness in its own trigger tree statsLoud = FluidBufStats.kr(~loudbuf[voice], stats:~statsLoudbuf[voice], numDerivs: 1, trig:Done.kr(loud), blocking: 1); flattenLoud = FluidBufFlatten.kr(~statsLoudbuf[voice],~flatLoudbuf[voice],trig:Done.kr(statsLoud),blocking: 1); - writeLoud = FluidDataSetWr.kr(~loudDS,label, -1, ~flatLoudbuf[voice], Done.kr(flattenLoud),blocking: 1); + writeLoud = FluidDataSetWr.kr(~loudDS,label, nil, ~flatLoudbuf[voice], Done.kr(flattenLoud),blocking: 1); //we can resume from the loud computation trigger mfcc = FluidBufMFCC.kr(src,startFrame:start,numFrames:num,numChans:1,features:~mfccbuf[voice],trig:Done.kr(writeLoud),blocking: 1);//here trig was loud mfccweights = FluidBufScale.kr(~loudbuf[voice],numChans: 1,destination: ~weightMFCCbuf[voice],inputLow: -70,inputHigh: 0, trig: Done.kr(mfcc), blocking: 1); mfccstats = FluidBufStats.kr(~mfccbuf[voice], stats:~statsMFCCbuf[voice], startChan: 1, numDerivs: 1, weights: ~weightMFCCbuf[voice], trig:Done.kr(mfccweights), blocking: 1);//remove mfcc0 and weigh by loudness instead mfccflat = FluidBufFlatten.kr(~statsMFCCbuf[voice],~flatMFCCbuf[voice],trig:Done.kr(mfccstats),blocking: 1); - FluidDataSetWr.kr(~mfccDS,label, -1, ~flatMFCCbuf[voice], Done.kr(mfccflat),blocking: 1); + FluidDataSetWr.kr(~mfccDS,label, nil, ~flatMFCCbuf[voice], Done.kr(mfccflat),blocking: 1); }); ) diff --git a/release-packaging/Examples/dataset/1-learning examples/12-windowed-clustered-segmentation.scd b/release-packaging/Examples/dataset/1-learning examples/12-windowed-clustered-segmentation.scd index 5167a5d..69d17d5 100644 --- a/release-packaging/Examples/dataset/1-learning examples/12-windowed-clustered-segmentation.scd +++ b/release-packaging/Examples/dataset/1-learning examples/12-windowed-clustered-segmentation.scd @@ -38,11 +38,11 @@ a = Slider(w, Rect(10, 20, 330, 20)) features = FluidBufMFCC.kr(src,startFrame:start,numFrames:num,numChans:1, numCoeffs: 20, features:~featuresbuf[voice],trig:1,blocking: 1); stats = FluidBufStats.kr(~featuresbuf[voice],stats:~statsbuf[voice],trig:Done.kr(features),blocking: 1); flatten = FluidBufFlatten.kr(~statsbuf[voice],~flatbuf[voice],trig:Done.kr(stats),blocking: 1); - writer = FluidDataSetWr.kr(~slicesMFCC,label, -1, ~flatbuf[voice], Done.kr(flatten),blocking: 1); + writer = FluidDataSetWr.kr(~slicesMFCC,label, nil, ~flatbuf[voice], Done.kr(flatten),blocking: 1); features = FluidBufSpectralShape.kr(src,startFrame:start,numFrames:num,numChans:1, features:~featuresbuf[voice],trig:Done.kr(writer),blocking: 1); stats = FluidBufStats.kr(~featuresbuf[voice],stats:~statsbuf[voice],trig:Done.kr(features),blocking: 1); flatten = FluidBufFlatten.kr(~statsbuf[voice],~flatbuf[voice],trig:Done.kr(stats),blocking: 1); - writer = FluidDataSetWr.kr(~slicesShapes,label, -1, ~flatbuf[voice], Done.kr(flatten),blocking: 1); + writer = FluidDataSetWr.kr(~slicesShapes,label, nil, ~flatbuf[voice], Done.kr(flatten),blocking: 1); }); ) diff --git a/release-packaging/Examples/dataset/1-learning examples/8c-mlp-regressor-as-dim-redux.scd b/release-packaging/Examples/dataset/1-learning examples/8c-mlp-regressor-as-dim-redux.scd index 6bf9101..6c59b6e 100644 --- a/release-packaging/Examples/dataset/1-learning examples/8c-mlp-regressor-as-dim-redux.scd +++ b/release-packaging/Examples/dataset/1-learning examples/8c-mlp-regressor-as-dim-redux.scd @@ -31,7 +31,7 @@ FluidBufMelBands.process(s,~audio, features: ~melfeatures,action: {\done.postln; 40.do{|i| bufWr = BufWr.kr(rd[i], buf, DC.kr(i)); }; - dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats)); + dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats)); LocalOut.kr( Done.kr(dsWr)); FreeSelf.kr(count - 99); Poll.kr(trig,(100-count)); diff --git a/release-packaging/HelpSource/Classes/FluidBufLoudness.schelp b/release-packaging/HelpSource/Classes/FluidBufLoudness.schelp index 74e0cae..86651fd 100644 --- a/release-packaging/HelpSource/Classes/FluidBufLoudness.schelp +++ b/release-packaging/HelpSource/Classes/FluidBufLoudness.schelp @@ -51,6 +51,9 @@ ARGUMENT:: windowSize ARGUMENT:: hopSize How much the buffered window moves forward, in samples. By default 512 to be similar with all other FluCoMa objects, the EBU specifies other values as per the examples below. +ARGUMENT:: padding + Controls the zero-padding added to either end of the source buffer or segment. Possible values are 0 (no padding), 1 (default, half the window size), or 2 (window size - hop size). Padding ensures that all input samples are completely analysed: with no padding, the first analysis window starts at time 0, and the samples at either end will be tapered by the STFT windowing function. Mode 1 has the effect of centering the first sample in the analysis window and ensuring that the very start and end of the segment are accounted for in the analysis. Mode 2 can be useful when the overlap factor (window size / hop size) is greater than 2, to ensure that the input samples at either end of the segment are covered by the same number of analysis frames as the rest of the analysed material. + ARGUMENT:: freeWhenDone Free the server instance when processing complete. Default true diff --git a/release-packaging/HelpSource/Classes/FluidDataSet.schelp b/release-packaging/HelpSource/Classes/FluidDataSet.schelp index b28cbaf..6643181 100644 --- a/release-packaging/HelpSource/Classes/FluidDataSet.schelp +++ b/release-packaging/HelpSource/Classes/FluidDataSet.schelp @@ -77,7 +77,16 @@ The link::Classes/FluidLabelSet:: from which to retrieve the point's IDs associa ARGUMENT:: action A function to run when the import is done. + +METHOD:: getIds +Export to the dataset IDs to a link::Classes/FluidLabelSet::. + +ARGUMENT:: labelSet +The link::Classes/FluidLabelSet:: to export to. Its content will be replaced. ​ +ARGUMENT:: action +A function to run when the export is done. + METHOD:: merge Merge sourceDataSet in the current DataSet. It will update the value of points with the same label if overwrite is set to 1. To add columns instead, see the 'transformJoin' method of link::Classes/FluidDataSetQuery:: @@ -136,7 +145,7 @@ fork{ var count = PulseCount.kr(trig) - 1; var buf = LocalBuf(1); BufWr.kr(count, buf); - FluidDataSetWr.kr(~ds.asUGenInput, buf: buf, trig: trig); + FluidDataSetWr.kr(~ds.asUGenInput, idNumber: count, buf: buf, trig: trig); FreeSelf.kr(count - 8); }.play.onFree{~ds.dump{|o| o.postln;~ds.free}} ) diff --git a/release-packaging/HelpSource/Classes/FluidDataSetWr.schelp b/release-packaging/HelpSource/Classes/FluidDataSetWr.schelp index dd1c27e..f92de08 100644 --- a/release-packaging/HelpSource/Classes/FluidDataSetWr.schelp +++ b/release-packaging/HelpSource/Classes/FluidDataSetWr.schelp @@ -114,7 +114,7 @@ OSCFunc({ var buf = LocalBuf.newFrom([0,1,2,3]); var noise = 4.collect{WhiteNoise.kr()}; var trig = Impulse.kr(2); - var count = PulseCount.kr(trig,); + var count = PulseCount.kr(trig); 4.do{|i| BufWr.kr(noise[i], buf, DC.kr(i)); }; diff --git a/release-packaging/HelpSource/Classes/FluidKMeans.schelp b/release-packaging/HelpSource/Classes/FluidKMeans.schelp index 8c49e9a..1dcf71f 100644 --- a/release-packaging/HelpSource/Classes/FluidKMeans.schelp +++ b/release-packaging/HelpSource/Classes/FluidKMeans.schelp @@ -25,18 +25,18 @@ INSTANCEMETHODS:: PRIVATE::k METHOD:: fit -Identify code::k:: clusters in a link::Classes/FluidDataSet:: +Identify code::numClusters:: clusters in a link::Classes/FluidDataSet::. It will optimise until no improvement is possible, or up to code::maxIter::, whichever comes first. Subsequent calls will continue training from the stopping point with the same conditions. ARGUMENT:: dataSet A link::Classes/FluidDataSet:: of data points. ARGUMENT:: action A function to run when fitting is complete, taking as its argument an array with the number of data points for each cluster. METHOD:: predict -Given a trained object, return the cluster ID for each data point in a DataSet to a label set. +Given a trained object, return the cluster ID for each data point in a link::Classes/FluidDataSet:: to a link::Classes/FluidLabelSet::. ARGUMENT:: dataSet -a link::Classes/FluidDataSet:: containing the data to predict. +A link::Classes/FluidDataSet:: containing the data to predict. ARGUMENT:: labelSet -a link::Classes/FluidLabelSet:: to retrieve the predicted clusters. +A link::Classes/FluidLabelSet:: to retrieve the predicted clusters. ARGUMENT:: action A function to run when the server responds. @@ -52,59 +52,55 @@ A function to run when the server responds METHOD:: predictPoint Given a trained object, return the cluster ID for a data point in a link::Classes/Buffer:: ARGUMENT:: buffer -a link::Classes/Buffer:: containing a data point. +A link::Classes/Buffer:: containing a data point. ARGUMENT:: action A function to run when the server responds, taking the ID of the cluster as its argument. -METHOD:: predict -Report cluster assignments for previously unseen data. -ARGUMENT:: dataSet -A link::Classes/FluidDataSet:: of data points. -ARGUMENT:: labelSet -A link::Classes/FluidLabelSet:: to contain assignments. +METHOD:: transform +Given a trained object, return for each item of a provided link::Classes/FluidDataSet:: its distance to each cluster as an array, often reffered to as the cluster-distance space. +ARGUMENT:: srcDataSet +A link::Classes/FluidDataSet:: of data points to transform. +ARGUMENT:: dstDataSet +A link::Classes/FluidDataSet:: to contain the new cluster-distance space. ARGUMENT:: action -A function to run when complete, taking an array of the counts for each category as its argument. +A function to run when complete. METHOD:: fitTransform -Run link::Classes/FluidKMeans#*fit:: and link::Classes/FluidKMeans#*predict:: in a single pass: i.e. train the model on the incoming link::Classes/FluidDataSet:: and then return the learned clustering to the passed link::Classes/FluidLabelSet:: +Run link::Classes/FluidKMeans#*fit:: and link::Classes/FluidKMeans#*transform:: in a single pass: i.e. train the model on the incoming link::Classes/FluidDataSet:: and then return its cluster-distance space in the destination link::Classes/FluidDataSet:: ARGUMENT:: srcDataSet -a link::Classes/FluidDataSet:: containing the data to fit and predict. +A link::Classes/FluidDataSet:: containing the data to fit and transform. ARGUMENT:: dstDataSet -a link::Classes/FluidLabelSet:: to retrieve the predicted clusters. +A link::Classes/FluidDataSet:: to contain the new cluster-distance space. ARGUMENT:: action -A function to run when the server responds +A function to run when complete. METHOD:: transformPoint -Given a trained object, return the cluster ID for a data point in a link::Classes/Buffer:: +Given a trained object, return the distance of the provided point to each cluster. Both points are handled as link::Classes/Buffer:: ARGUMENT:: sourceBuffer -a link::Classes/Buffer:: containing a data point. +A link::Classes/Buffer:: containing a data point to query. ARGUMENT:: targetBuffer -a link::Classes/Buffer:: containing a data point. -ARGUMENT:: action -A function to run when the server responds, taking the ID of the cluster as its argument. - -METHOD:: transform -Report cluster assignments for previously unseen data. -ARGUMENT:: srcDataSet -A link::Classes/FluidDataSet:: of data points. -ARGUMENT:: dstDataSet -A link::Classes/FluidLabelSet:: to contain assignments. +A link::Classes/Buffer:: containing a the distance of the source point to each cluster. ARGUMENT:: action -A function to run when complete, taking an array of the counts for each category as its argument. +A function to run when complete. METHOD:: getMeans -Report cluster assignments for previously unseen data. +Given a trained object, retrieve the means (centroids) of each cluster as a link::Classes/FluidDataSet:: ARGUMENT:: dataSet -A link::Classes/FluidDataSet:: of data points. +A link::Classes/FluidDataSet:: of clusers with a mean per column. ARGUMENT:: action -A function to run when complete, taking an array of the counts for each category as its argument. +A function to run when complete. METHOD:: setMeans -Report cluster assignments for previously unseen data. +Overwrites the means (centroids) of each cluster, and declare the object trained. ARGUMENT:: dataSet -A link::Classes/FluidDataSet:: of data points. +A link::Classes/FluidDataSet:: of clusers with a mean per column. +ARGUMENT:: action +A function to run when complete. + +METHOD:: clear +Reset the object status to not fitted and untrained. ARGUMENT:: action -A function to run when complete, taking an array of the counts for each category as its argument. +A function to run when complete. EXAMPLES:: code:: @@ -192,30 +188,40 @@ subsection:: Accessing the means We can get and set the means for each cluster, their centroid. code:: +// with the dataset and kmeans generated and trained in the code above ~centroids = FluidDataSet(s); ~kmeans.getMeans(~centroids, {~centroids.print}); - - +// We can also set them to arbitrary values to seed the process ~centroids.load(Dictionary.newFrom([\cols, 2, \data, Dictionary.newFrom([\0, [0.5,0.5], \1, [-0.5,0.5], \2, [0.5,-0.5], \3, [-0.5,-0.5]])])); ~centroids.print ~kmeans.setMeans(~centroids, {~kmeans.predict(~dataSet,~clusters,{~clusters.dump{|x|var count = 0.dup(4); x["data"].keysValuesDo{|k,v|count[v[0].asInteger] = count[v[0].asInteger] + 1;};count.postln}})}); -~kmeans.clear -~kmeans.predict(~dataSet,~clusters) - +// We can further fit from the seeded means +~kmeans.fit(~dataSet) +// then retreive the improved means +~kmeans.getMeans(~centroids, {~centroids.print}); +//subtle in this case but still.. each quadrant is where we seeded it. :: subsection:: Cluster-distance Space -You can get the euclidian distance of a given point to each cluster. +We can get the euclidian distance of a given point to each cluster. This is often referred to as the cluster-distance space as it creates new dimensions for each given point, one distance per cluster. code:: +// with the dataset and kmeans generated and trained in the code above b = Buffer.sendCollection(s,[0.5,0.5]) c = Buffer(s) +// get the distance of our given point (b) to each cluster, thus giving us 4 dimensions in our cluster-distance space ~kmeans.transformPoint(b,c,{|x|x.query;x.getn(0,x.numFrames,{|y|y.postln})}) +// we can also transform a full dataset +~srcDS = FluidDataSet(s) +~cdspace = FluidDataSet(s) +// make a new dataset with 4 points +~srcDS.load(Dictionary.newFrom([\cols, 2, \data, Dictionary.newFrom([\pp, [0.5,0.5], \np, [-0.5,0.5], \pn, [0.5,-0.5], \nn, [-0.5,-0.5]])])); +~kmeans.transform(~srcDS, ~cdspace, {~cdspace.print}) :: subsection:: Queries in a Synth diff --git a/release-packaging/HelpSource/Classes/FluidMDS.schelp b/release-packaging/HelpSource/Classes/FluidMDS.schelp index c5444f2..b1f7722 100644 --- a/release-packaging/HelpSource/Classes/FluidMDS.schelp +++ b/release-packaging/HelpSource/Classes/FluidMDS.schelp @@ -89,14 +89,14 @@ FluidBufMFCC.process(s,~audio, features: ~mfcc_feature); var chunkLen = (~mfcc_feature.numFrames / 100).asInteger; var stats = FluidBufStats.kr( source: ~mfcc_feature, startFrame: count * chunkLen, - startChan:1, numFrames: chunkLen, stats: ~stats, trig: trig,blocking:1 + startChan:1, numFrames: chunkLen, stats: ~stats, trig: trig, blocking:1 ); var rd = BufRd.kr(12, ~stats, DC.kr(0), 0, 1); var bufWr, dsWr; 12.do{|i| bufWr = BufWr.kr(rd[i], buf, DC.kr(i)); }; - dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats),blocking:1); + dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats),blocking:1); LocalOut.kr(Done.kr(dsWr)); FreeSelf.kr(count - 99); Poll.kr(trig,(100-count)); diff --git a/release-packaging/HelpSource/Classes/FluidNormalize.schelp b/release-packaging/HelpSource/Classes/FluidNormalize.schelp index d0b4043..5718cd6 100644 --- a/release-packaging/HelpSource/Classes/FluidNormalize.schelp +++ b/release-packaging/HelpSource/Classes/FluidNormalize.schelp @@ -97,7 +97,7 @@ FluidBufPitch.process(s,~audio, features: ~pitch_feature); var rd = BufRd.kr(2, ~stats, DC.kr(0), 0, 1);// pick only mean pitch and confidence var wr1 = BufWr.kr(rd[0], buf, DC.kr(0)); var wr2 = BufWr.kr(rd[1], buf, DC.kr(1)); - var dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats)); + var dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats)); LocalOut.kr( Done.kr(dsWr)); Poll.kr(trig,count,\count); FreeSelf.kr(count - 9); diff --git a/release-packaging/HelpSource/Classes/FluidPCA.schelp b/release-packaging/HelpSource/Classes/FluidPCA.schelp index aaf6a00..d271202 100644 --- a/release-packaging/HelpSource/Classes/FluidPCA.schelp +++ b/release-packaging/HelpSource/Classes/FluidPCA.schelp @@ -59,7 +59,7 @@ Run when done. The function is passed code::destBuffer:: as argument. EXAMPLES:: code:: -s.boot; +s.reboot; //Preliminaries: we want some audio, a couple of FluidDataSets, some Buffers, a FluidStandardize and a FluidPCA ( ~audiofile = File.realpath(FluidBufPitch.class.filenameSymbol).dirname +/+ "../AudioFiles/Tremblay-ASWINE-ScratchySynth-M.wav"; @@ -99,7 +99,7 @@ FluidBufMFCC.process(s,~audio, features: ~mfcc_feature,action:{"Done MFCCs".post 12.do{|i| bufWr = BufWr.kr(rd[i], buf, DC.kr(i)); }; - dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats)); + dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats)); LocalOut.kr( Done.kr(dsWr)); FreeSelf.kr(count - 99); Poll.kr(trig,(100 - count)); diff --git a/release-packaging/HelpSource/Classes/FluidProcessSlices.schelp b/release-packaging/HelpSource/Classes/FluidProcessSlices.schelp index 9e27f2e..5de64ec 100644 --- a/release-packaging/HelpSource/Classes/FluidProcessSlices.schelp +++ b/release-packaging/HelpSource/Classes/FluidProcessSlices.schelp @@ -52,7 +52,7 @@ code:: statsbuf = LocalBuf(7); pitch = FluidBufPitch.kr(src,start,num,numChans:1,features:~featurebuffers[voice]); stats = FluidBufStats.kr(~featurebuffers[voice],numChans:1, stats:statsbuf,trig:Done.kr(pitch)); - FluidDataSetWr.kr(label,statsbuf,~mydataset,Done.kr(stats)) + FluidDataSetWr.kr(~mydataset, label, nil, statsbuf,Done.kr(stats)) }; :: @@ -112,7 +112,7 @@ s.reboot; label = data.key; pitch = FluidBufPitch.kr(src,start,num,features:~pitchbufs[i]); stats = FluidBufStats.kr(~pitchbufs[i],stats:~statsbufs[i],trig:Done.kr(pitch)); - FluidDataSetWr.kr(~pitchdata,label,-1,buf:~statsbufs[i],trig:Done.kr(stats)) + FluidDataSetWr.kr(~pitchdata,label,nil,buf:~statsbufs[i],trig:Done.kr(stats)) }); ) diff --git a/release-packaging/HelpSource/Classes/FluidRobustScale.schelp b/release-packaging/HelpSource/Classes/FluidRobustScale.schelp index 85848a0..5237e55 100644 --- a/release-packaging/HelpSource/Classes/FluidRobustScale.schelp +++ b/release-packaging/HelpSource/Classes/FluidRobustScale.schelp @@ -96,7 +96,7 @@ FluidBufPitch.process(s,~audio, features: ~pitch_feature); var rd = BufRd.kr(2, ~stats, DC.kr(0), 0, 1);// pick only mean pitch and confidence var wr1 = BufWr.kr(rd[0], buf, DC.kr(0)); var wr2 = BufWr.kr(rd[1], buf, DC.kr(1)); - var dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats)); + var dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats)); LocalOut.kr( Done.kr(dsWr)); Poll.kr(trig,count,\count); FreeSelf.kr(count - 9); diff --git a/release-packaging/HelpSource/Classes/FluidStandardize.schelp b/release-packaging/HelpSource/Classes/FluidStandardize.schelp index c4d3b2b..a10ceab 100644 --- a/release-packaging/HelpSource/Classes/FluidStandardize.schelp +++ b/release-packaging/HelpSource/Classes/FluidStandardize.schelp @@ -90,7 +90,7 @@ FluidBufPitch.process(s,~audio, features: ~pitch_feature,action:{"Analysed Pitch var rd = BufRd.kr(2, ~stats, DC.kr(0), 0, 1);// pick only mean pitch and confidence var wr1 = BufWr.kr(rd[0], buf, DC.kr(0)); var wr2 = BufWr.kr(rd[1], buf, DC.kr(1)); - var dsWr = FluidDataSetWr.kr(~raw, buf: buf, trig: Done.kr(stats)); + var dsWr = FluidDataSetWr.kr(~raw, buf: buf, idNumber: count, trig: Done.kr(stats)); LocalOut.kr( Done.kr(dsWr)); FreeSelf.kr(count - 9); Poll.kr(trig,count, \count);