From dca175a0f7784be2f222b1cfd25b812329bcb29c Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Mon, 1 Nov 2021 10:30:41 +0000 Subject: [PATCH 1/6] removed extraneous postlns in FluidNormalize & FluidStats --- release-packaging/Classes/FluidNormalize.sc | 2 +- release-packaging/Classes/FluidStats.sc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release-packaging/Classes/FluidNormalize.sc b/release-packaging/Classes/FluidNormalize.sc index dc85c48..21cdea4 100644 --- a/release-packaging/Classes/FluidNormalize.sc +++ b/release-packaging/Classes/FluidNormalize.sc @@ -70,7 +70,7 @@ FluidNormalize : FluidModelObject { FluidNormalizeQuery : FluidRTMultiOutUGen { *kr{ |trig, model,inputBuffer,outputBuffer,min = 0 ,max = 1,invert = 0| - inputBuffer.asUGenInput.postln; + // inputBuffer.asUGenInput.postln; ^this.multiNew('control',trig, model.asUGenInput, min,max,invert, inputBuffer.asUGenInput, outputBuffer.asUGenInput) diff --git a/release-packaging/Classes/FluidStats.sc b/release-packaging/Classes/FluidStats.sc index a6a3187..03f0e53 100644 --- a/release-packaging/Classes/FluidStats.sc +++ b/release-packaging/Classes/FluidStats.sc @@ -9,7 +9,7 @@ FluidStats : MultiOutUGen { init {arg ...theInputs; inputs = theInputs; this.specialIndex = (inputs.size - 2).max(0); - this.specialIndex.postln; + // this.specialIndex.postln; ^this.initOutputs(inputs.size - 1,rate); } From edb1bc558f7cbbf69f77146f0d451dd0ac78027f Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 3 Nov 2021 16:15:10 +0000 Subject: [PATCH 2/6] corrected errors in DataSet classdef and help --- release-packaging/Classes/FluidDataSet.sc | 2 +- .../HelpSource/Classes/FluidDataSet.schelp | 23 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/release-packaging/Classes/FluidDataSet.sc b/release-packaging/Classes/FluidDataSet.sc index 3ec0061..60683d8 100644 --- a/release-packaging/Classes/FluidDataSet.sc +++ b/release-packaging/Classes/FluidDataSet.sc @@ -35,7 +35,7 @@ FluidDataSet : FluidDataObject deletePointMsg{|identifier| ^this.prMakeMsg(\deletePoint,id,identifier.asSymbol);} - deletePoint{|identifier, buffer, action| + deletePoint{|identifier, action| actions[\deletePoint] = [nil,action]; this.prSendMsg(this.deletePointMsg(identifier)); } diff --git a/release-packaging/HelpSource/Classes/FluidDataSet.schelp b/release-packaging/HelpSource/Classes/FluidDataSet.schelp index 6d90457..2adb0cd 100644 --- a/release-packaging/HelpSource/Classes/FluidDataSet.schelp +++ b/release-packaging/HelpSource/Classes/FluidDataSet.schelp @@ -39,6 +39,8 @@ ARGUMENT:: identifier The identifier for the point. ARGUMENT:: buffer A link::Classes/Buffer:: containing the data for the point. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: getPoint Retrieve a point from the data set into a link::Classes/Buffer::. If the identifier does not exist an error will be reported. @@ -46,10 +48,15 @@ ARGUMENT:: identifier The identifier for the point. ARGUMENT:: buffer A link::Classes/Buffer:: where the retrieved data will be stored. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: deletePoint -Remove a point from the data set. If the identifier doesn't exist an error will be reported. ​​ARGUMENT:: identifier +Remove a point from the data set. If the identifier doesn't exist an error will be reported. ​ +​ARGUMENT:: identifier The identifier to be deleted. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: setPoint Set the point. If the identifier exists, this method behaves like updatePoint. If the identifier doesn't exist, it behaves like addPoint. @@ -57,46 +64,38 @@ ARGUMENT:: identifier The identifier for the point. ARGUMENT:: buffer A link::Classes/Buffer:: containing the data for the point. -​​ +​​ARGUMENT:: action +A function to run when the operation completes. + METHOD:: clear Empty the data set. METHOD:: toBuffer Dump the content of the dataset to a link::Classes/Buffer::, with optional transposition, and a map of frames/channels to the original IDs as a link::Classes/FluidLabelSet::. - ARGUMENT:: buffer The buffer to write to. It will be resized. - ARGUMENT:: transpose If 0, each dataset point becomes a buffer frame, and each dataset dimension becomes a buffer channel. If 1, points become channels, and dimensions become frames. - ARGUMENT:: labelSet The link::Classes/FluidLabelSet:: in which to dump the point's IDs associated with their reference frame number (or channel number if transposed). - ARGUMENT:: action A function to run when the dump is done. METHOD:: fromBuffer Import to the dataset the content of a link::Classes/Buffer::, with optional transposition, and a map of frames/channels to the original IDs as a link::Classes/FluidLabelSet::. - ARGUMENT:: buffer The buffer to read from. The dataset will be resized. - ARGUMENT:: transpose If 0, each buffer frame becomes a dataset point, and each buffer channel becomes a dataset dimension. If 1, channels become points, and frames become dimensions. - ARGUMENT:: labelSet The link::Classes/FluidLabelSet:: from which to retrieve the point's IDs associated with their reference frame number (or channel number if transposed). - 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. From d33fef37d47796926f27669c18c75fa1c01a954e Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 3 Nov 2021 16:15:32 +0000 Subject: [PATCH 3/6] corrected errors in LabelSet classdef and help + added getIDs --- release-packaging/Classes/FluidLabelSet.sc | 9 +++++++++ .../HelpSource/Classes/FluidLabelSet.schelp | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/release-packaging/Classes/FluidLabelSet.sc b/release-packaging/Classes/FluidLabelSet.sc index 7f0d9c3..4d7f745 100644 --- a/release-packaging/Classes/FluidLabelSet.sc +++ b/release-packaging/Classes/FluidLabelSet.sc @@ -51,4 +51,13 @@ FluidLabelSet : FluidDataObject { actions[\print] = [string(FluidMessageResponse,_,_),action]; this.prSendMsg(this.printMsg); } + + getIdsMsg{|labelSet| + ^this.prMakeMsg(\getIds, id, labelSet.asUGenInput); + } + + getIds{|labelSet, action| + actions[\getIds] = [nil,action]; + this.prSendMsg(this.getIdsMsg(labelSet)); + } } diff --git a/release-packaging/HelpSource/Classes/FluidLabelSet.schelp b/release-packaging/HelpSource/Classes/FluidLabelSet.schelp index 24b1bba..2319562 100644 --- a/release-packaging/HelpSource/Classes/FluidLabelSet.schelp +++ b/release-packaging/HelpSource/Classes/FluidLabelSet.schelp @@ -33,20 +33,32 @@ ARGUMENT:: identifier The identifier for this label. ARGUMENT:: label The label to update. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: getLabel Retrieve the label associated with an identifier. Will report an error if the identifier is not present in the set. ARGUMENT:: identifier The identifier for the label to be retrieved. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: deleteLabel Delete a label given a certain identifier. ARGUMENT:: identifier The identifier to be deleted. +ARGUMENT:: action +A function to run when the operation completes. METHOD:: clear Empty the label set. +METHOD:: getIds +Export to the labelset 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:: print Post an abbreviated content of the label set in the window by default, but you can supply a custom action instead. From b27f0b0b8231cfefbc476fd46bd2f5e601fb2498 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Wed, 3 Nov 2021 17:03:01 +0000 Subject: [PATCH 4/6] Updated Guide to include FluidPlotter and FluidWaveform --- .../HelpSource/Guides/FluidCorpusManipulation.schelp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/release-packaging/HelpSource/Guides/FluidCorpusManipulation.schelp b/release-packaging/HelpSource/Guides/FluidCorpusManipulation.schelp index bc2974b..e0c55f3 100644 --- a/release-packaging/HelpSource/Guides/FluidCorpusManipulation.schelp +++ b/release-packaging/HelpSource/Guides/FluidCorpusManipulation.schelp @@ -110,6 +110,13 @@ table:: ##link::Classes/FluidBufSelectEvery:: || Select every N elements (frame-wise or channel wise) ##link::Classes/FluidBufFlatten:: || Flatten multichannel data into single channel 'point' :: + +subsection::Viewers +table:: +##link::Classes/FluidPlotter:: || View a FluidDataSet in a plotter window +##link::Classes/FluidWaveform:: || View an audio buffer with overlays, such as slices from a FluCoMa slicer +:: + subsection:: Corpus Building table:: ##link::Classes/FluidLoadFolder:: || Load a folder of sounds into a link::Classes/Buffer:: From 5815a2258f5a6d82aa93830a7c97a74381c952be Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Wed, 3 Nov 2021 17:04:04 +0000 Subject: [PATCH 5/6] include FluidPlotter and FluidWaveform --- .../HelpSource/Classes/FluidPlotter.schelp | 304 ++++++++++++++++++ .../HelpSource/Classes/FluidWaveform.schelp | 43 +++ 2 files changed, 347 insertions(+) create mode 100644 release-packaging/HelpSource/Classes/FluidPlotter.schelp create mode 100644 release-packaging/HelpSource/Classes/FluidWaveform.schelp diff --git a/release-packaging/HelpSource/Classes/FluidPlotter.schelp b/release-packaging/HelpSource/Classes/FluidPlotter.schelp new file mode 100644 index 0000000..a67eba3 --- /dev/null +++ b/release-packaging/HelpSource/Classes/FluidPlotter.schelp @@ -0,0 +1,304 @@ +TITLE:: FluidPlotter +summary:: A view for plotting data +categories:: Libraries>FluidCorpusManipulation +related:: Classes/FluidDataSet, Classes/FluidLabelSet, Classes/FluidKDTree, Classes/FluidKMeans + +DESCRIPTION:: +FluidPlotter is a viewer for plotting data. + + +CLASSMETHODS:: + +METHOD:: new +Creates a new instance of FluidPlotter + +ARGUMENT:: parent +A parent view to embed the FluidPlotter in. If no parent is passed, FluidPlotter will create a window for itself at the given bounds. + +ARGUMENT:: bounds +Where to show the FluidPlotter, either within the parent or on the screen (if no parent is passed). + +ARGUMENT:: dict +A link::Classes/Dictionary:: from a FluidDataSet dump method (or a similarly formatted Dictionary) that contains the data to be plotted. + +ARGUMENT:: mouseMoveAction +A function to execute on mouse down or mouse drag. This funtion is passed the strong::view:: (itself), strong::x position:: (scaled according to the xmin and xmax arguments of FluidPlotter), strong::y position:: (scaled according to the ymin and ymax arguments of FluidPlotter), strong::modifiers::, strong::button number::, and strong::click count::. The last two arguments are only useful on mouse down, not on mouse drag. + +ARGUMENT:: xmin +Minimum of the X range to display. Default is 0. + +ARGUMENT:: xmax +Maximum of the X range to display. Default is 1. + +ARGUMENT:: ymin +Minimum of the Y range to display. Default is 0. + +ARGUMENT:: ymax +Maximum of the Y range to display. Default is 1. + +returns:: +An instance of FluidPlotter + +INSTANCEMETHODS:: + +METHOD:: background +Set the background link::Classes/Color::. + +METHOD:: pointSize +Set the size of a specific point. + +ARGUMENT:: identifier +Which point to set the size of. + +ARGUMENT:: size +What size the point should be. This is a multiplier applied to the default point size which is 6 pixels. A point size of "2" will render a point with a diameter of 12 pixels. A point size of "0.5" will render a point with a diameter of 3 pixels. + +METHOD:: refresh +Refresh the link::Classes/UserView:: inside the FluidPlotter. + +METHOD:: xmin +Set xmin property and refresh the plotter. + +returns:: +xmin property. + +METHOD:: xmax +Set xmax property and refresh the plotter. + +METHOD:: ymin +Set ymin property and refresh the plotter. + +METHOD:: ymax +Set ymax property and refresh the plotter. + +METHOD:: addPoint +Manually add a single point to the FluidPlotter. Similar to the strong::addPoint:: method of link::Classes/FluidDataSet::, addPoint_ will not overwrite a point that already exists at the given identifier. Instead, a warning will be thrown. + +ARGUMENT:: identifier +The identifier associated with this point. + +ARGUMENT:: x +X position of the point. + +ARGUMENT:: y +Y position of the point. + +ARGUMENT:: color +What link::Classes/Color:: to make the point. If nothing is provided the point will default to link::Classes/Color::.black. + +ARGUMENT:: size +What size to make the point. This is a multiplier that modifies the default point size of 6 pixels. The default is 1. See strong::pointSize:: method above. + +METHOD:: setPoint +Similar to the strong::setPoint:: method of link::Classes/FluidDataSet::, setPoint_ will add a new point to the FluidPlotter. If a point already exists at the given identifier, it will be overwritten. + +ARGUMENT:: identifier +The identifier associated with this point. + +ARGUMENT:: x +X position of the point. + +ARGUMENT:: y +Y position of the point. + +ARGUMENT:: color +What link::Classes/Color:: to make the point. If nothing is provided the point will default to link::Classes/Color::.black. + +ARGUMENT:: size +What size to make the point. This is a multiplier that modifies the default point size of 6 pixels. The default is 1. See strong::pointSize:: method above. + +METHOD:: highlight +Increase the size of a point to make it more salient. Only one point can be "highlighted" at a time. To increase the size of multiple points, use method strong::pointSize::. + +ARGUMENT:: identifier +The identifier of the point to make salient. If nil is passes, not points' sizes will be changed. + +METHOD:: dict +Set a new link::Classes/Dictionary:: of points. Overwrites all previous points and Dictionaries. + +ARGUMENT:: d + +METHOD:: shape +Change the shape of the points, the options are \circle or \square. The default is \circle. + +ARGUMENT:: sh +(describe argument here) + +METHOD:: pointSizeScale +Scale all the points by a multiplier. See strong::pointSize_:: method above. The default is 1. + +ARGUMENT:: ps +(describe argument here) + +METHOD:: close +Close the plotter and/or its parent. + +METHOD:: pointColor +Change the link::Classes/Color:: of a point. + +ARGUMENT:: identifier +Identifier of the point to change the color of. + +ARGUMENT:: color +The link::Classes/Color:: to change the point to. + +METHOD:: parent + +returns:: The parent link::Classes/View:: of the FluidPlotter + +METHOD:: categories +Set categories to display as colors. + +ARGUMENT:: labelSetDict +This must be a link::Classes/Dictionary:: from a link::Classes/FluidLabelSet:: dump method, or a similarly formatted Dictionary. + +EXAMPLES:: + +code:: +( +// make some dummy data and plot it +~dummy_data = { + arg xmin = 20, xmax = 20000, ymin = -130, ymax = 0; + Dictionary.newFrom([ + "cols",2, + "data",Dictionary.newFrom(Array.fill(200,{ + arg i; + var return; + if((i % 2) == 0,{ + return = "example-%".format((i/2).asInteger); + },{ + return = [rrand(xmin,xmax),rrand(ymin,ymax)]; + }); + // return.postln; + return; + })) + ]); +}; + +Window.closeAll; +// self window +d = ~dummy_data.value; +// d.postln; +~fp = FluidPlotter(bounds:Rect(200,200,600,600),dict:d,mouseMoveAction:{ + arg view, x, y, modifiers; + [view, x, y, modifiers].dopostln; + "".postln; +},xmin:20,xmax:20000,ymin:-130,ymax:0); +) + +// click and drag on the plotter to report stuff in the mouseMoveAction callback function + +// change point size of just one point +~fp.pointSize_("example-5",10); + +// change it back +~fp.pointSize_("example-5",1); + +// change all points size bigger... +~fp.pointSizeScale_(2); + +// ...smaller... +~fp.pointSizeScale_(0.5); + +// ...back to normal +~fp.pointSizeScale_(1); + +( +// change 10 random points red +10.do({ + ~fp.pointColor_("example-%".format(rrand(0,99)),Color.red); +}); +) +// "highlight" a point (makes it a little bigger) +~fp.highlight_("example-95"); + +// a different one +~fp.highlight_("example-94"); + +// none +~fp.highlight_(nil); + +// put some different data in +~fp.dict_(~dummy_data.value); + +// change the ranges +( +~fp.ymin_(-140); +~fp.ymax_(10); +~fp.xmin_(-200); +~fp.xmax_(21000); +) + +// change the point shapes +~fp.shape_(\square); + +// change back to circles +~fp.shape_(\circle); + +// change the color of just one point +~fp.pointColor_("example-7",Color.red); + +// change the background color +~fp.background_(Color.red) +~fp.background_(Color.white) + +// ==== perform KMeans on the data and colorize the categories ====== +( +s.waitForBoot{ + Routine{ + var labelset = FluidLabelSet(s); + var kmeans = FluidKMeans(s); + var ds = FluidDataSet(s); + + s.sync; + + ds.load(~fp.dict,{ + kmeans.fitPredict(ds,labelset,{ + labelset.dump({ + arg lsdict; + defer{~fp.categories_(lsdict)}; + "done".postln; + }); + }); + }); + }.play; +} +) + +// close it or it's parent +~fp.close; + + +// a FluidPlotter inside a parent with parent +( +Window.closeAll; +d = Dictionary.newFrom([ + "cols",2, + "data",Dictionary.newFrom(Array.fill(200,{ + arg i; + var return; + if((i%2) == 0,{ + return = "example-%".format((i/2).asInteger); + },{ + return = [exprand(20,20000),rrand(-130,0)]; + }); + return; + })) +]); +w = Window("test",Rect(50,50,800,600)).front; +~fp = FluidPlotter(w,Rect(50,50,400,400),dict:d,mouseMoveAction:{ + arg view, x, y, modifiers; + [view, x, y, modifiers].dopostln; + "".postln; +},xmin:20,xmax:20000,ymin:-130,ymax:0); +) + +// you can make an empty one and then set the dict later +( +Window.closeAll; +~fp = FluidPlotter(bounds:Rect(100,100,500,500)) +) + +// now set data +~fp.dict_(~dummy_data.(0.01,1,0.0,1.0).postln); +:: diff --git a/release-packaging/HelpSource/Classes/FluidWaveform.schelp b/release-packaging/HelpSource/Classes/FluidWaveform.schelp new file mode 100644 index 0000000..e3279cd --- /dev/null +++ b/release-packaging/HelpSource/Classes/FluidWaveform.schelp @@ -0,0 +1,43 @@ +TITLE:: FluidWaveform +summary:: Buffer waveform display with optional overlays +categories:: Libraries>FluidCorpusManipulation +related:: Classes/FluidPlotter, Classes/FluidBufNoveltySlide, Classes/FluidBufOnsetSlice, Classes/FluidBufAmpSlice + +DESCRIPTION:: +FluidWaveform plots a buffer with optional overlays such as slices derived from a FluCoMa Slicer. + +CLASSMETHODS:: + +METHOD:: new +Create a new instance of FluidWaveform. + +ARGUMENT:: audio_buf +The audio buffer to plot. + +ARGUMENT:: slices_buf +A buffer of slice indices. This will very likely be in the form of a buffer output from a FluCoMa slicer object. Currently this buffer must be only one channel, therefore it will not work with the output of link::Classes/FluidBufAmpGate::. + +ARGUMENT:: bounds +A link::Classes/Rect:: of where to place the FluidWaveform. + +returns:: A new instance of FluidWaveform. + + +INSTANCEMETHODS:: + +EXAMPLES:: + +code:: + +// load a sound to slice +~drums = Buffer.read(s,File.realpath(FluidBufAmpSlice.class.filenameSymbol).dirname.withTrailingSlash ++ "../AudioFiles/Nicol-LoopE-M.wav"); + +// create a buffer to put indices into +~indices = Buffer(s); + +// do a slice analysis +FluidBufAmpSlice.process(s,~drums,indices:~indices,fastRampUp: 10,fastRampDown: 2205,slowRampUp: 4410,slowRampDown: 4410,onThreshold: 10,offThreshold: 5,floor: -40,minSliceLength: 4410,highPassFreq: 20); + +// plot the buffer with the indices overlayed +FluidWaveform(~drums,~indices,Rect(0,0,800,200)); +:: From 5933b96cff70bc73b90014151e5b67034363167e Mon Sep 17 00:00:00 2001 From: Pierre Alexandre Tremblay Date: Wed, 3 Nov 2021 20:56:08 +0000 Subject: [PATCH 6/6] correct typo --- release-packaging/HelpSource/Classes/FluidWaveform.schelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-packaging/HelpSource/Classes/FluidWaveform.schelp b/release-packaging/HelpSource/Classes/FluidWaveform.schelp index e3279cd..6979245 100644 --- a/release-packaging/HelpSource/Classes/FluidWaveform.schelp +++ b/release-packaging/HelpSource/Classes/FluidWaveform.schelp @@ -1,7 +1,7 @@ TITLE:: FluidWaveform summary:: Buffer waveform display with optional overlays categories:: Libraries>FluidCorpusManipulation -related:: Classes/FluidPlotter, Classes/FluidBufNoveltySlide, Classes/FluidBufOnsetSlice, Classes/FluidBufAmpSlice +related:: Classes/FluidPlotter, Classes/FluidBufNoveltySlice, Classes/FluidBufOnsetSlice, Classes/FluidBufAmpSlice DESCRIPTION:: FluidWaveform plots a buffer with optional overlays such as slices derived from a FluCoMa Slicer.