From 9ab48a6def0fd55bf488291805a3f33e4021bffa Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Mon, 12 Apr 2021 08:58:04 +0100 Subject: [PATCH 1/8] add getIds to dataset (and correct help) --- .../HelpSource/Classes/FluidDataSet.schelp | 11 ++++++++++- .../HelpSource/Classes/FluidDataSetWr.schelp | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) 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)); }; From 7d09d83f4fbaa35c59a4b15d296d7eacc951d6c2 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Mon, 12 Apr 2021 09:38:50 +0100 Subject: [PATCH 2/8] all examples with DataSetWr have the right counting/bypassing now --- .../0-demo-dataset-maker-utilities.scd | 4 ++-- .../10a-weighted-MFCCs-comparison.scd | 22 +++++++++---------- .../11-compositing-datasets.scd | 6 ++--- .../12-windowed-clustered-segmentation.scd | 4 ++-- .../8c-mlp-regressor-as-dim-redux.scd | 2 +- .../HelpSource/Classes/FluidMDS.schelp | 4 ++-- .../HelpSource/Classes/FluidNormalize.schelp | 2 +- .../HelpSource/Classes/FluidPCA.schelp | 4 ++-- .../Classes/FluidProcessSlices.schelp | 4 ++-- .../Classes/FluidRobustScale.schelp | 2 +- .../Classes/FluidStandardize.schelp | 2 +- 11 files changed, 28 insertions(+), 28 deletions(-) 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..ae629df 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], 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, 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); }); ) 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/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); From f29c011e94dd8b11523c03fb837a4e857cf5db21 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Mon, 12 Apr 2021 15:00:03 +0100 Subject: [PATCH 3/8] Add padding param to BufLoudness --- release-packaging/Classes/FluidBufLoudness.sc | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 ); } } From 1c2995c02455530da92ea4392f710a8fc68ab97a Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Mon, 12 Apr 2021 15:24:06 +0100 Subject: [PATCH 4/8] added padding to loudness help --- release-packaging/HelpSource/Classes/FluidBufLoudness.schelp | 3 +++ 1 file changed, 3 insertions(+) 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 From 54c1fc2e5b49da06c73c3fec5de362eaccf318e4 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Tue, 13 Apr 2021 09:40:25 +0100 Subject: [PATCH 5/8] fix example with new padding in loudness --- .../1-learning examples/10a-weighted-MFCCs-comparison.scd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 ae629df..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 @@ -35,7 +35,7 @@ label = data.key; voice = data.value[\voice]; 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], trig:Done.kr(mfcc), 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); @@ -47,7 +47,7 @@ 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, 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)); From f413364ff24e456658bfc111c8d763c2262d7d39 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Tue, 13 Apr 2021 09:40:54 +0100 Subject: [PATCH 6/8] KMeans - new methods - new extensive doc and examples --- .../HelpSource/Classes/FluidKMeans.schelp | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidKMeans.schelp b/release-packaging/HelpSource/Classes/FluidKMeans.schelp index 8c49e9a..58d895c 100644 --- a/release-packaging/HelpSource/Classes/FluidKMeans.schelp +++ b/release-packaging/HelpSource/Classes/FluidKMeans.schelp @@ -25,7 +25,7 @@ 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 @@ -56,55 +56,51 @@ 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 DataSet 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. 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 From cc13acc9523de0df20ef2580fb2548ee326e5573 Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Tue, 13 Apr 2021 09:58:36 +0100 Subject: [PATCH 7/8] and now, with less typos --- .../HelpSource/Classes/FluidKMeans.schelp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidKMeans.schelp b/release-packaging/HelpSource/Classes/FluidKMeans.schelp index 58d895c..1dcf71f 100644 --- a/release-packaging/HelpSource/Classes/FluidKMeans.schelp +++ b/release-packaging/HelpSource/Classes/FluidKMeans.schelp @@ -32,11 +32,11 @@ 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,12 +52,12 @@ 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:: transform -Given a trained object, return for each item of a provided DataSet its distance to each cluster as an array, often reffered to as the cluster-distance space. +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 @@ -68,7 +68,7 @@ A function to run when complete. METHOD:: fitTransform 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/FluidDataSet:: to contain the new cluster-distance space. ARGUMENT:: action @@ -77,9 +77,9 @@ A function to run when complete. METHOD:: transformPoint 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 to query. +A link::Classes/Buffer:: containing a data point to query. ARGUMENT:: targetBuffer -a link::Classes/Buffer:: containing a the distance of the source point to each cluster. +A link::Classes/Buffer:: containing a the distance of the source point to each cluster. ARGUMENT:: action A function to run when complete. From 3fdeaeb833e219fc750ab583baf065e3a6c0b239 Mon Sep 17 00:00:00 2001 From: Owen Green Date: Tue, 13 Apr 2021 23:56:01 +0100 Subject: [PATCH 8/8] Fix latency u_cmd by defining after the server knows the Unit exists --- include/wrapper/Realtime.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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); }