From 0e5980580a736707cc8e8d46e3e38cad214c05e8 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Thu, 28 Oct 2021 18:14:30 +0100 Subject: [PATCH 01/13] FluidPlotter and test file highlight method sets color --- release-packaging/Classes/FluidPlotter.sc | 170 ++++++++++++++++++++++ test/FluidPlotter_test.scd | 73 ++++++++++ 2 files changed, 243 insertions(+) create mode 100644 release-packaging/Classes/FluidPlotter.sc create mode 100644 test/FluidPlotter_test.scd diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc new file mode 100644 index 0000000..f9fa27e --- /dev/null +++ b/release-packaging/Classes/FluidPlotter.sc @@ -0,0 +1,170 @@ +FluidPlotter { + var Date: Thu, 28 Oct 2021 19:13:10 +0100 Subject: [PATCH 02/13] FluidPlotter is beta --- release-packaging/Classes/FluidPlotter.sc | 118 +++++++++++++++------- test/FluidPlotter_test.scd | 53 ++++++++-- 2 files changed, 124 insertions(+), 47 deletions(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index f9fa27e..2be0860 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -1,5 +1,23 @@ +FluidPlotterPoint { + var id, color, <>sizeMultiplier = 1; + + *new { + arg id, x, y, color, sizeMultiplier = 1; + ^super.new.init(id,x,y,color,sizeMultiplier); + } + + init { + arg id_, x_, y_, color_, sizeMultiplier_ = 1; + id = id_; + x = x_; + y = y_; + color = color_ ? Color.black; + sizeMultiplier = sizeMultiplier_; + } +} + FluidPlotter { - var (catColors.size-1),{"FluidPlotter:setCategories_ FluidPlotter doesn't have that many category colors. You can use the method 'setColor_' to set colors for individual points.".warn}); + col = catColors[cat]; + pt.color_(col); + }); + this.refresh; + } + + setSizeMultiplier_ { + arg identifier, sizeMultiplier; + if(dict_internal.at(identifier).notNil,{ + dict_internal.at(identifier).sizeMultiplier_(sizeMultiplier); + this.refresh; + },{ + "FluidPlotter::setSizeMultiplier_ identifier not found".warn; + }); + } + + setPoint_ { + arg identifier, x, y, sizeMultiplier = 1, color; + dict_internal.put(identifier,FluidPlotterPoint(identifier,x,y,color ? Color.black,sizeMultiplier)); + this.refresh; } setColor_ { arg identifier, color; - if(dict.at("data").at(identifier).notNil,{ - colors.put(identifier,color); + if(dict_internal.at(identifier).notNil,{ + dict_internal.at(identifier).color_(color); this.refresh; },{ "FluidPlotter::setColor_ identifier not found".warn; @@ -56,7 +98,7 @@ FluidPlotter { background_ { arg bg; - + userView.background_(bg); } refresh { @@ -72,11 +114,16 @@ FluidPlotter { dict_ { arg d; dict = d; - colors = Dictionary.newFrom(dict.at("data").keys.collect({ - arg key; - [key,Color.black]; - }).asArray.flatten); - this.refresh; + dict_internal = Dictionary.new; + dict.at("data").keysValuesDo({ + arg k, v; +/* k.postln; + v.postln;*/ + dict_internal.put(k,FluidPlotterPoint(k,v[0],v[1],Color.black,1)); + }); + if(userView.notNil,{ + this.refresh; + }); } xmin_ { @@ -104,22 +151,9 @@ FluidPlotter { } highlight_ { - arg identifier, color; - var found = false; - colors.keys.do{ - arg key; - if(key == identifier,{ - colors.put(key,color); - found = true; - },{ - colors.put(key,Color.black); - }); - }; - if(found,{ - this.refresh; - },{ - "FluidPlotter::highlight_ identifier not found".warn; - }); + arg identifier; + highlightIdentifier = identifier; + this.refresh; } dictNotProperlyFormatted { @@ -136,18 +170,30 @@ FluidPlotter { userView = UserView(parent,Rect(xpos,ypos,bounds.width,bounds.height)); userView.drawFunc_({ - dict.at("data").keysValuesDo({ + dict_internal.keysValuesDo({ arg key, pt; - var scaledx = pt[0].linlin(xmin,xmax,0,userView.bounds.width) - (pointSize/2); - var scaledy = pt[1].linlin(ymin,ymax,0,userView.bounds.height) - (pointSize/2); - var color = colors.at(key); + var pointSize_, scaledx, scaledy, color; + +/* key.postln; + pt.postln; + pt.x.postln; + pt.y.postln;*/ + + if(key == highlightIdentifier,{ + pointSize_ = pointSize * 2.3 * pt.sizeMultiplier + },{ + pointSize_ = pointSize * pt.sizeMultiplier + }); + + scaledx = pt.x.linlin(xmin,xmax,0,userView.bounds.width,nil) - (pointSize_/2); + scaledy = pt.y.linlin(ymax,ymin,0,userView.bounds.height,nil) - (pointSize_/2); shape.switch( - \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize,pointSize))}, - \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize,pointSize))} + \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize_,pointSize_))}, + \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize_,pointSize_))} ); - Pen.color_(color); + Pen.color_(pt.color); Pen.draw; }); }); @@ -160,8 +206,6 @@ FluidPlotter { }); if(parent_.isNil,{parent.front;}); - - this.dict_(dict_); } close { diff --git a/test/FluidPlotter_test.scd b/test/FluidPlotter_test.scd index 904f3b6..0657c85 100644 --- a/test/FluidPlotter_test.scd +++ b/test/FluidPlotter_test.scd @@ -15,9 +15,7 @@ })) ]); }; -) -( Window.closeAll; // self window d = ~dummy_data.value; @@ -29,7 +27,7 @@ d = ~dummy_data.value; },xmin:20,xmax:20000,ymin:-130,ymax:0); ) -~fp.pointSize_(6) +~fp.pointSize_(10); ( 10.do({ @@ -37,13 +35,50 @@ d = ~dummy_data.value; }); ) -~fp.highlight_("example-90",Color.red); +~fp.highlight_("example-95"); +~fp.highlight_(nil); ~fp.dict_(~dummy_data.value); -~fp.ymin_(-50) +( +~fp.ymin_(-140); +~fp.ymax_(10); +~fp.xmin_(-200); +~fp.xmax_(21000); +) + +~fp.shape_(\square); -~fp.shape_(\square) +~fp.setSizeMultiplier_("example-0",10); +~fp.setSizeMultiplier_("example-0",1); + +~fp.setColor_("example-7",Color.red); + +~fp.background_(Color.red) + +~fp.close; + +( +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.setCategories_(lsdict)}; + "done".postln; + }); + }); + }); + }.play; +} +) // with parent @@ -55,7 +90,7 @@ d = Dictionary.newFrom([ arg i; var return; if((i%2) == 0,{ - return = "exmaple-%".format((i/2).asInteger); + return = "example-%".format((i/2).asInteger); },{ return = [exprand(20,20000),rrand(-130,0)]; }); @@ -68,6 +103,4 @@ w = Window("test",Rect(50,50,800,600)).front; [view, x, y, modifiers].dopostln; "".postln; },xmin:20,xmax:20000,ymin:-130,ymax:0); -) - -~fp.setColor_("example-7",Color.red); \ No newline at end of file +) \ No newline at end of file From f96f5d7000747a2766ba3cd85d7f373addd56fa4 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Thu, 28 Oct 2021 19:55:43 +0100 Subject: [PATCH 03/13] added some error checks and warnings --- release-packaging/Classes/FluidPlotter.sc | 85 ++++++++++++----------- test/FluidPlotter_test.scd | 15 +++- 2 files changed, 58 insertions(+), 42 deletions(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index 2be0860..5d6e252 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -33,14 +33,8 @@ FluidPlotter { ymin = ymin_; ymax = ymax_; - if(dict_.isNil,{this.dictNotProperlyFormatted}); - if(dict_.size != 2,{this.dictNotProperlyFormatted}); - if(dict_.at("data").isNil,{this.dictNotProperlyFormatted}); - if(dict_.at("cols").isNil,{this.dictNotProperlyFormatted}); - if(dict_.at("cols") != 2,{this.dictNotProperlyFormatted}); - this.createCatColors; - this.dict_(dict_); + if(dict_.notNil,{this.dict_(dict_)}); this.createPlotWindow(bounds,parent_,mouseMoveAction,dict_); this.background_(Color.white); } @@ -54,14 +48,18 @@ FluidPlotter { setCategories_ { arg labelSetDict; - dict_internal.keysValuesDo({ - arg id, pt; - var col, cat = labelSetDict.at("data").at(id)[0].interpret; - if(cat > (catColors.size-1),{"FluidPlotter:setCategories_ FluidPlotter doesn't have that many category colors. You can use the method 'setColor_' to set colors for individual points.".warn}); - col = catColors[cat]; - pt.color_(col); + if(dict_internal.notNil,{ + dict_internal.keysValuesDo({ + arg id, pt; + var col, cat = labelSetDict.at("data").at(id)[0].interpret; + if(cat > (catColors.size-1),{"FluidPlotter:setCategories_ FluidPlotter doesn't have that many category colors. You can use the method 'setColor_' to set colors for individual points.".warn}); + col = catColors[cat]; + pt.color_(col); + }); + this.refresh; + },{ + "FluidPlotter::setCategories_ FluidPlotter cannot receive setCategories. It has no data. First set a dictionary.".warn; }); - this.refresh; } setSizeMultiplier_ { @@ -113,11 +111,18 @@ FluidPlotter { dict_ { arg d; + + if(d.isNil,{^this.dictNotProperlyFormatted}); + if(d.size != 2,{^this.dictNotProperlyFormatted}); + if(d.at("data").isNil,{^this.dictNotProperlyFormatted}); + if(d.at("cols").isNil,{^this.dictNotProperlyFormatted}); + if(d.at("cols") != 2,{^this.dictNotProperlyFormatted}); + dict = d; dict_internal = Dictionary.new; dict.at("data").keysValuesDo({ arg k, v; -/* k.postln; + /* k.postln; v.postln;*/ dict_internal.put(k,FluidPlotterPoint(k,v[0],v[1],Color.black,1)); }); @@ -170,31 +175,33 @@ FluidPlotter { userView = UserView(parent,Rect(xpos,ypos,bounds.width,bounds.height)); userView.drawFunc_({ - dict_internal.keysValuesDo({ - arg key, pt; - var pointSize_, scaledx, scaledy, color; - -/* key.postln; - pt.postln; - pt.x.postln; - pt.y.postln;*/ - - if(key == highlightIdentifier,{ - pointSize_ = pointSize * 2.3 * pt.sizeMultiplier - },{ - pointSize_ = pointSize * pt.sizeMultiplier + if(dict_internal.notNil,{ + dict_internal.keysValuesDo({ + arg key, pt; + var pointSize_, scaledx, scaledy, color; + + /* key.postln; + pt.postln; + pt.x.postln; + pt.y.postln;*/ + + if(key == highlightIdentifier,{ + pointSize_ = pointSize * 2.3 * pt.sizeMultiplier + },{ + pointSize_ = pointSize * pt.sizeMultiplier + }); + + scaledx = pt.x.linlin(xmin,xmax,0,userView.bounds.width,nil) - (pointSize_/2); + scaledy = pt.y.linlin(ymax,ymin,0,userView.bounds.height,nil) - (pointSize_/2); + + shape.switch( + \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize_,pointSize_))}, + \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize_,pointSize_))} + ); + + Pen.color_(pt.color); + Pen.draw; }); - - scaledx = pt.x.linlin(xmin,xmax,0,userView.bounds.width,nil) - (pointSize_/2); - scaledy = pt.y.linlin(ymax,ymin,0,userView.bounds.height,nil) - (pointSize_/2); - - shape.switch( - \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize_,pointSize_))}, - \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize_,pointSize_))} - ); - - Pen.color_(pt.color); - Pen.draw; }); }); diff --git a/test/FluidPlotter_test.scd b/test/FluidPlotter_test.scd index 0657c85..af31992 100644 --- a/test/FluidPlotter_test.scd +++ b/test/FluidPlotter_test.scd @@ -1,5 +1,6 @@ ( ~dummy_data = { + arg xmin = 20, xmax = 20000, ymin = -130, ymax = 0; Dictionary.newFrom([ "cols",2, "data",Dictionary.newFrom(Array.fill(200,{ @@ -8,7 +9,7 @@ if((i % 2) == 0,{ return = "example-%".format((i/2).asInteger); },{ - return = [exprand(20,20000),rrand(-130,0)]; + return = [rrand(xmin,xmax),rrand(ymin,ymax)]; }); // return.postln; return; @@ -54,6 +55,7 @@ d = ~dummy_data.value; ~fp.setColor_("example-7",Color.red); +~fp.background_(Color.white) ~fp.background_(Color.red) ~fp.close; @@ -67,7 +69,7 @@ s.waitForBoot{ s.sync; - ds.load(~fp.dict,{ + ds.load(~dummy_data.(),{ kmeans.fitPredict(ds,labelset,{ labelset.dump({ arg lsdict; @@ -103,4 +105,11 @@ w = Window("test",Rect(50,50,800,600)).front; [view, x, y, modifiers].dopostln; "".postln; },xmin:20,xmax:20000,ymin:-130,ymax:0); -) \ No newline at end of file +) + +( +Window.closeAll; +~fp = FluidPlotter(bounds:Rect(100,100,500,500)) +) + +~fp.dict_(~dummy_data.(0.01,1,0.0,1.0).postln); \ No newline at end of file From 636d9b2e7899df037ec28453db6aba91a0e3ff86 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Mon, 1 Nov 2021 11:18:13 +0000 Subject: [PATCH 04/13] FluidWaveform in alpha --- release-packaging/Classes/FluidWaveform.sc | 47 ++++++++++++++++++++++ test/FluidWaveform_test.scd | 14 +++++++ 2 files changed, 61 insertions(+) create mode 100644 release-packaging/Classes/FluidWaveform.sc create mode 100644 test/FluidWaveform_test.scd diff --git a/release-packaging/Classes/FluidWaveform.sc b/release-packaging/Classes/FluidWaveform.sc new file mode 100644 index 0000000..fe63c11 --- /dev/null +++ b/release-packaging/Classes/FluidWaveform.sc @@ -0,0 +1,47 @@ +FluidWaveform { + + *new { + arg audio_buf, slices_buf, bounds; + ^super.new.init(audio_buf,slices_buf, bounds); + } + + init { + arg audio_buf, slices_buf, bounds; + Task{ + var path = "%%_%_FluidWaveform.wav".format(PathName.tmp,Date.localtime.stamp,UniqueID.next); + var sfv, win, userView; + + bounds = bounds ? Rect(0,0,800,200); + win = Window("FluidWaveform",bounds); + audio_buf.write(path,"wav"); + + audio_buf.server.sync; + + sfv = SoundFileView(win,Rect(0,0,bounds.width,bounds.height)); + sfv.readFile(SoundFile(path)); + sfv.gridOn_(false); + + win.onClose_({ + File.delete(path) + }); + + slices_buf.loadToFloatArray(action:{ + arg slices_fa; + + userView = UserView(win,Rect(0,0,bounds.width,bounds.height)) + .drawFunc_({ + slices_fa.do{ + arg start_samp; + var x = start_samp.linlin(0,audio_buf.numFrames,0,bounds.width); + Pen.line(Point(x,0),Point(x,bounds.height)); + Pen.color_(Color.red); + Pen.stroke; + }; + }); + + win.front; + }); + }.play(AppClock); + } +} + diff --git a/test/FluidWaveform_test.scd b/test/FluidWaveform_test.scd new file mode 100644 index 0000000..93a5d55 --- /dev/null +++ b/test/FluidWaveform_test.scd @@ -0,0 +1,14 @@ +( +s.waitForBoot{ + + Task{ + var buf = Buffer.read(s,"/Users/macprocomputer/Desktop/_flucoma/code/flucoma-core-src/AudioFiles/Nicol-LoopE-M.wav"); + var slicepoints = Buffer(s); + + FluidBufAmpSlice.process(s,buf,indices:slicepoints,fastRampUp:10,fastRampDown:2205,slowRampUp:4410,slowRampDown:4410,onThreshold:10,offThreshold:5,floor:-40,minSliceLength:4410,highPassFreq:20,action:{ + FluidWaveform(buf,slicepoints,Rect(0,0,1600,400)); + }); + + }.play(AppClock); +} +) \ No newline at end of file From bf899a100bfd73638d3b6ec0a9e3639c514cb059 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Mon, 1 Nov 2021 13:23:23 +0000 Subject: [PATCH 05/13] updated fluid plotter to require fewer external defers --- release-packaging/Classes/FluidPlotter.sc | 86 ++++++++++++----------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index 5d6e252..a90b738 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -36,7 +36,6 @@ FluidPlotter { this.createCatColors; if(dict_.notNil,{this.dict_(dict_)}); this.createPlotWindow(bounds,parent_,mouseMoveAction,dict_); - this.background_(Color.white); } createCatColors { @@ -100,7 +99,7 @@ FluidPlotter { } refresh { - userView.refresh; + {userView.refresh}.defer; } pointSize_ { @@ -122,8 +121,6 @@ FluidPlotter { dict_internal = Dictionary.new; dict.at("data").keysValuesDo({ arg k, v; - /* k.postln; - v.postln;*/ dict_internal.put(k,FluidPlotterPoint(k,v[0],v[1],Color.black,1)); }); if(userView.notNil,{ @@ -168,51 +165,56 @@ FluidPlotter { createPlotWindow { arg bounds,parent_, mouseMoveAction,dict_; var xpos, ypos; + var mouseAction = { + arg view, x, y, modifiers, buttonNumber, clickCount; + x = x.linlin(pointSize/2,userView.bounds.width-(pointSize/2),xmin,xmax); + y = y.linlin(pointSize/2,userView.bounds.height-(pointSize/2),ymax,ymin); + mouseMoveAction.(this,x,y,modifiers,buttonNumber, clickCount); + }; if(parent_.isNil,{xpos = 0; ypos = 0},{xpos = bounds.left; ypos = bounds.top}); - - parent = parent_ ? Window("FluidPlotter",bounds); - userView = UserView(parent,Rect(xpos,ypos,bounds.width,bounds.height)); - - userView.drawFunc_({ - if(dict_internal.notNil,{ - dict_internal.keysValuesDo({ - arg key, pt; - var pointSize_, scaledx, scaledy, color; - - /* key.postln; - pt.postln; - pt.x.postln; - pt.y.postln;*/ - - if(key == highlightIdentifier,{ - pointSize_ = pointSize * 2.3 * pt.sizeMultiplier - },{ - pointSize_ = pointSize * pt.sizeMultiplier + { + parent = parent_ ? Window("FluidPlotter",bounds); + userView = UserView(parent,Rect(xpos,ypos,bounds.width,bounds.height)); + + userView.drawFunc_({ + if(dict_internal.notNil,{ + dict_internal.keysValuesDo({ + arg key, pt; + var pointSize_, scaledx, scaledy, color; + + /* key.postln; + pt.postln; + pt.x.postln; + pt.y.postln;*/ + + if(key == highlightIdentifier,{ + pointSize_ = pointSize * 2.3 * pt.sizeMultiplier + },{ + pointSize_ = pointSize * pt.sizeMultiplier + }); + + scaledx = pt.x.linlin(xmin,xmax,0,userView.bounds.width,nil) - (pointSize_/2); + scaledy = pt.y.linlin(ymax,ymin,0,userView.bounds.height,nil) - (pointSize_/2); + + shape.switch( + \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize_,pointSize_))}, + \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize_,pointSize_))} + ); + + Pen.color_(pt.color); + Pen.draw; }); - - scaledx = pt.x.linlin(xmin,xmax,0,userView.bounds.width,nil) - (pointSize_/2); - scaledy = pt.y.linlin(ymax,ymin,0,userView.bounds.height,nil) - (pointSize_/2); - - shape.switch( - \square,{Pen.addRect(Rect(scaledx,scaledy,pointSize_,pointSize_))}, - \circle,{Pen.addOval(Rect(scaledx,scaledy,pointSize_,pointSize_))} - ); - - Pen.color_(pt.color); - Pen.draw; }); }); - }); - userView.mouseMoveAction_({ - arg view, x, y, modifiers; - x = x.linlin(pointSize/2,userView.bounds.width-(pointSize/2),xmin,xmax); - y = y.linlin(pointSize/2,userView.bounds.height-(pointSize/2),ymin,ymax); - mouseMoveAction.(this,x,y,modifiers); - }); + userView.mouseMoveAction_(mouseAction); + userView.mouseDownAction_(mouseAction); + + this.background_(Color.white); - if(parent_.isNil,{parent.front;}); + if(parent_.isNil,{parent.front;}); + }.defer; } close { From 372fca134fade5d57a85e34d7367b5d65974bc2a Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Mon, 1 Nov 2021 17:09:27 +0000 Subject: [PATCH 06/13] fluid plotter synced up with james' max one, helpfile _started_ --- release-packaging/Classes/FluidPlotter.sc | 48 ++-- .../HelpSource/Classes/FluidPlotter.schelp | 267 ++++++++++++++++++ test/FluidPlotter_test.scd | 15 +- 3 files changed, 304 insertions(+), 26 deletions(-) create mode 100644 release-packaging/HelpSource/Classes/FluidPlotter.schelp diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index a90b738..d90f683 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -1,23 +1,23 @@ FluidPlotterPoint { - var id, color, <>sizeMultiplier = 1; + var id, color, <>size = 1; *new { - arg id, x, y, color, sizeMultiplier = 1; - ^super.new.init(id,x,y,color,sizeMultiplier); + arg id, x, y, color, size = 1; + ^super.new.init(id,x,y,color,size); } init { - arg id_, x_, y_, color_, sizeMultiplier_ = 1; + arg id_, x_, y_, color_, size_ = 1; id = id_; x = x_; y = y_; color = color_ ? Color.black; - sizeMultiplier = sizeMultiplier_; + size = size_; } } FluidPlotter { - var 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:: + +ARGUMENT:: mouseMoveAction +(describe argument here) + +ARGUMENT:: xmin +(describe argument here) + +ARGUMENT:: xmax +(describe argument here) + +ARGUMENT:: ymin +(describe argument here) + +ARGUMENT:: ymax +(describe argument here) + +returns:: (describe returnvalue here) + + +INSTANCEMETHODS:: + +METHOD:: background +(describe method here) + +ARGUMENT:: bg +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: xmin +(describe method here) + +ARGUMENT:: val +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: pointSize +(describe method here) + +ARGUMENT:: identifier +(describe argument here) + +ARGUMENT:: size +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: refresh +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: ymin +(describe method here) + +ARGUMENT:: val +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: userView +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: setPoint +(describe method here) + +ARGUMENT:: identifier +(describe argument here) + +ARGUMENT:: x +(describe argument here) + +ARGUMENT:: y +(describe argument here) + +ARGUMENT:: color +(describe argument here) + +ARGUMENT:: size +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: ymax +(describe method here) + +ARGUMENT:: val +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: xmax +(describe method here) + +ARGUMENT:: val +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: highlight +(describe method here) + +ARGUMENT:: identifier +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: dict +(describe method here) + +ARGUMENT:: d +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: createPlotWindow +(describe method here) + +ARGUMENT:: bounds +(describe argument here) + +ARGUMENT:: parent_ +(describe argument here) + +ARGUMENT:: mouseMoveAction +(describe argument here) + +ARGUMENT:: dict_ +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: addPoint +(describe method here) + +ARGUMENT:: identifier +(describe argument here) + +ARGUMENT:: x +(describe argument here) + +ARGUMENT:: y +(describe argument here) + +ARGUMENT:: color +(describe argument here) + +ARGUMENT:: size +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: shape +(describe method here) + +ARGUMENT:: sh +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: globalPointSize +(describe method here) + +ARGUMENT:: ps +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: close +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: createCatColors +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: pointColor +(describe method here) + +ARGUMENT:: identifier +(describe argument here) + +ARGUMENT:: color +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: dictNotProperlyFormatted +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: parent +(describe method here) + +returns:: (describe returnvalue here) + +METHOD:: categories +(describe method here) + +ARGUMENT:: labelSetDict +(describe argument here) + +returns:: (describe returnvalue here) + +METHOD:: init +(describe method here) + +ARGUMENT:: parent_ +(describe argument here) + +ARGUMENT:: bounds +(describe argument here) + +ARGUMENT:: dict_ +(describe argument here) + +ARGUMENT:: mouseMoveAction +(describe argument here) + +ARGUMENT:: xmin_ +(describe argument here) + +ARGUMENT:: xmax_ +(describe argument here) + +ARGUMENT:: ymin_ +(describe argument here) + +ARGUMENT:: ymax_ +(describe argument here) + +returns:: (describe returnvalue here) + + +EXAMPLES:: + +code:: +(some example code) +:: diff --git a/test/FluidPlotter_test.scd b/test/FluidPlotter_test.scd index af31992..ad09d1a 100644 --- a/test/FluidPlotter_test.scd +++ b/test/FluidPlotter_test.scd @@ -28,11 +28,13 @@ d = ~dummy_data.value; },xmin:20,xmax:20000,ymin:-130,ymax:0); ) -~fp.pointSize_(10); +~fp.pointSize_("example-5",10); +~fp.pointSize_("example-5",1); +~fp.pointSizeScale_(1); ( 10.do({ - ~fp.setColor_("example-%".format(rrand(0,99)),Color.yellow); + ~fp.pointColor_("example-%".format(rrand(0,99)),Color.yellow); }); ) @@ -50,13 +52,10 @@ d = ~dummy_data.value; ~fp.shape_(\square); -~fp.setSizeMultiplier_("example-0",10); -~fp.setSizeMultiplier_("example-0",1); +~fp.pointColor_("example-7",Color.red); -~fp.setColor_("example-7",Color.red); - -~fp.background_(Color.white) ~fp.background_(Color.red) +~fp.background_(Color.white) ~fp.close; @@ -73,7 +72,7 @@ s.waitForBoot{ kmeans.fitPredict(ds,labelset,{ labelset.dump({ arg lsdict; - defer{~fp.setCategories_(lsdict)}; + defer{~fp.categories_(lsdict)}; "done".postln; }); }); From 6b4f236e03b521d869e5deb9ea293cc81377b108 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Tue, 2 Nov 2021 12:31:34 +0000 Subject: [PATCH 07/13] fix/FluidPlotter only worked with KMeans, not it also works with a user created LabelSet --- release-packaging/Classes/FluidPlotter.sc | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index d90f683..f2637a0 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -48,12 +48,27 @@ FluidPlotter { categories_ { arg labelSetDict; if(dict_internal.notNil,{ + var label_to_int = Dictionary.new; + var counter = 0; dict_internal.keysValuesDo({ - arg id, pt; - var col, cat = labelSetDict.at("data").at(id)[0].interpret; - if(cat > (catColors.size-1),{"FluidPlotter:setCategories_ FluidPlotter doesn't have that many category colors. You can use the method 'setColor_' to set colors for individual points.".warn}); - col = catColors[cat]; - pt.color_(col); + arg id, fp_pt; + var category_string = labelSetDict.at("data").at(id)[0]; + var category_int; + var color; + + if(label_to_int.at(category_string).isNil,{ + label_to_int.put(category_string,counter); + counter = counter + 1; + }); + + category_int = label_to_int.at(category_string); + + if(category_int > (catColors.size-1),{ + "FluidPlotter:setCategories_ FluidPlotter doesn't have that many category colors. You can use the method 'setColor_' to set colors for individual points.".warn + }); + + color = catColors[category_int]; + fp_pt.color_(color); }); this.refresh; },{ From 97b16d418fe41eabda37b0501b804eb0a7d6e1ac Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Tue, 2 Nov 2021 14:38:57 +0000 Subject: [PATCH 08/13] FluidPlotter helpfile done --- .../HelpSource/Classes/FluidPlotter.schelp | 367 ++++++++++-------- test/FluidPlotter_test.scd | 44 ++- 2 files changed, 240 insertions(+), 171 deletions(-) diff --git a/release-packaging/HelpSource/Classes/FluidPlotter.schelp b/release-packaging/HelpSource/Classes/FluidPlotter.schelp index 0304da4..e424433 100644 --- a/release-packaging/HelpSource/Classes/FluidPlotter.schelp +++ b/release-packaging/HelpSource/Classes/FluidPlotter.schelp @@ -19,249 +19,286 @@ 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:: +A link::Classes/Dictionary:: from a FluidDataSet dump method (or a similarly formatted Dictionary) that contains the data to be plotted. ARGUMENT:: mouseMoveAction -(describe argument here) +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 -(describe argument here) +Minimum of the X range to display. Default is 0. ARGUMENT:: xmax -(describe argument here) +Maximum of the X range to display. Default is 1. ARGUMENT:: ymin -(describe argument here) +Minimum of the Y range to display. Default is 0. ARGUMENT:: ymax -(describe argument here) - -returns:: (describe returnvalue here) +Maximum of the Y range to display. Default is 1. +returns:: +An instance of FluidPlotter INSTANCEMETHODS:: METHOD:: background -(describe method here) - -ARGUMENT:: bg -(describe argument here) - -returns:: (describe returnvalue here) - -METHOD:: xmin -(describe method here) - -ARGUMENT:: val -(describe argument here) - -returns:: (describe returnvalue here) +Set the background link::Classes/Color::. METHOD:: pointSize -(describe method here) +Set the size of a specific point. ARGUMENT:: identifier -(describe argument here) +Which point to set the size of. ARGUMENT:: size -(describe argument here) - -returns:: (describe returnvalue here) +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 -(describe method here) - -returns:: (describe returnvalue here) +Refresh the link::Classes/UserView:: inside the FluidPlotter. -METHOD:: ymin -(describe method here) +METHOD:: xmin +Set xmin property and refresh the plotter. -ARGUMENT:: val -(describe argument here) +returns:: +xmin property. -returns:: (describe returnvalue here) +METHOD:: xmax +Set xmax property and refresh the plotter. -METHOD:: userView -(describe method here) +METHOD:: ymin +Set ymin property and refresh the plotter. -returns:: (describe returnvalue here) +METHOD:: ymax +Set ymax property and refresh the plotter. -METHOD:: setPoint -(describe method here) +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 -(describe argument here) +The identifier associated with this point. ARGUMENT:: x -(describe argument here) +X position of the point. ARGUMENT:: y -(describe argument here) +Y position of the point. ARGUMENT:: color -(describe argument here) +What link::Classes/Color:: to make the point. If nothing is provided the point will default to link::Classes/Color::.black. ARGUMENT:: size -(describe argument here) - -returns:: (describe returnvalue here) +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:: ymax -(describe method here) +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:: val -(describe argument here) +ARGUMENT:: identifier +The identifier associated with this point. -returns:: (describe returnvalue here) +ARGUMENT:: x +X position of the point. -METHOD:: xmax -(describe method here) +ARGUMENT:: y +Y position of the point. -ARGUMENT:: val -(describe argument here) +ARGUMENT:: color +What link::Classes/Color:: to make the point. If nothing is provided the point will default to link::Classes/Color::.black. -returns:: (describe returnvalue here) +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 -(describe method here) +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 -(describe argument here) - -returns:: (describe returnvalue here) +The identifier of the point to make salient. If nil is passes, not points' sizes will be changed. METHOD:: dict -(describe method here) +Set a new link::Classes/Dictionary:: of points. Overwrites all previous points and Dictionaries. ARGUMENT:: d -(describe argument here) - -returns:: (describe returnvalue here) - -METHOD:: createPlotWindow -(describe method here) - -ARGUMENT:: bounds -(describe argument here) - -ARGUMENT:: parent_ -(describe argument here) - -ARGUMENT:: mouseMoveAction -(describe argument here) - -ARGUMENT:: dict_ -(describe argument here) - -returns:: (describe returnvalue here) - -METHOD:: addPoint -(describe method here) - -ARGUMENT:: identifier -(describe argument here) - -ARGUMENT:: x -(describe argument here) - -ARGUMENT:: y -(describe argument here) - -ARGUMENT:: color -(describe argument here) - -ARGUMENT:: size -(describe argument here) - -returns:: (describe returnvalue here) METHOD:: shape -(describe method here) +Change the shape of the points, the options are \circle or \square. The default is \circle. ARGUMENT:: sh (describe argument here) -returns:: (describe returnvalue here) - -METHOD:: globalPointSize -(describe method here) +METHOD:: pointSizeScale +Scale all the points by a multiplier. See strong::pointSize_:: method above. The default is 1. ARGUMENT:: ps (describe argument here) -returns:: (describe returnvalue here) - METHOD:: close -(describe method here) - -returns:: (describe returnvalue here) - -METHOD:: createCatColors -(describe method here) - -returns:: (describe returnvalue here) +Close the plotter and/or its parent. METHOD:: pointColor -(describe method here) +Change the link::Classes/Color:: of a point. ARGUMENT:: identifier -(describe argument here) +Identifier of the point to change the color of. ARGUMENT:: color -(describe argument here) - -returns:: (describe returnvalue here) - -METHOD:: dictNotProperlyFormatted -(describe method here) - -returns:: (describe returnvalue here) +The link::Classes/Color:: to change the point to. METHOD:: parent -(describe method here) -returns:: (describe returnvalue here) +returns:: The parent link::Classes/View:: of the FluidPlotter METHOD:: categories -(describe method here) +Set categories to display as colors. ARGUMENT:: labelSetDict -(describe argument here) - -returns:: (describe returnvalue here) - -METHOD:: init -(describe method here) - -ARGUMENT:: parent_ -(describe argument here) - -ARGUMENT:: bounds -(describe argument here) - -ARGUMENT:: dict_ -(describe argument here) - -ARGUMENT:: mouseMoveAction -(describe argument here) - -ARGUMENT:: xmin_ -(describe argument here) - -ARGUMENT:: xmax_ -(describe argument here) - -ARGUMENT:: ymin_ -(describe argument here) - -ARGUMENT:: ymax_ -(describe argument here) - -returns:: (describe returnvalue here) - +This must be a link::Classes/Dictionary:: from a link::Classes/FluidLabelSet:: dump method, or a similarly formatted Dictionary. EXAMPLES:: code:: -(some example 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); +:: \ No newline at end of file diff --git a/test/FluidPlotter_test.scd b/test/FluidPlotter_test.scd index ad09d1a..55b606d 100644 --- a/test/FluidPlotter_test.scd +++ b/test/FluidPlotter_test.scd @@ -1,4 +1,5 @@ ( +// make some dummy data and plot it ~dummy_data = { arg xmin = 20, xmax = 20000, ymin = -130, ymax = 0; Dictionary.newFrom([ @@ -28,21 +29,42 @@ d = ~dummy_data.value; },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.yellow); + ~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); @@ -50,15 +72,20 @@ d = ~dummy_data.value; ~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) -~fp.close; - +// ==== perform KMeans on the data and colorize the categories ====== ( s.waitForBoot{ Routine{ @@ -68,7 +95,7 @@ s.waitForBoot{ s.sync; - ds.load(~dummy_data.(),{ + ds.load(~fp.dict,{ kmeans.fitPredict(ds,labelset,{ labelset.dump({ arg lsdict; @@ -81,8 +108,11 @@ s.waitForBoot{ } ) +// close it or it's parent +~fp.close; + -// with parent +// a FluidPlotter inside a parent with parent ( Window.closeAll; d = Dictionary.newFrom([ @@ -106,9 +136,11 @@ w = Window("test",Rect(50,50,800,600)).front; },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); \ No newline at end of file From 4096ff836b78c3653896c4085145b09e317060e7 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Tue, 2 Nov 2021 18:23:53 +0000 Subject: [PATCH 09/13] FluidWaveform delete temp file delete it right away instead of on close --- release-packaging/Classes/FluidWaveform.sc | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/release-packaging/Classes/FluidWaveform.sc b/release-packaging/Classes/FluidWaveform.sc index fe63c11..88934e3 100644 --- a/release-packaging/Classes/FluidWaveform.sc +++ b/release-packaging/Classes/FluidWaveform.sc @@ -21,26 +21,26 @@ FluidWaveform { sfv.readFile(SoundFile(path)); sfv.gridOn_(false); - win.onClose_({ - File.delete(path) - }); - - slices_buf.loadToFloatArray(action:{ - arg slices_fa; - - userView = UserView(win,Rect(0,0,bounds.width,bounds.height)) - .drawFunc_({ - slices_fa.do{ - arg start_samp; - var x = start_samp.linlin(0,audio_buf.numFrames,0,bounds.width); - Pen.line(Point(x,0),Point(x,bounds.height)); - Pen.color_(Color.red); - Pen.stroke; - }; + File.delete(path); + + if(slices_buf.notNil,{ + slices_buf.loadToFloatArray(action:{ + arg slices_fa; + + userView = UserView(win,Rect(0,0,bounds.width,bounds.height)) + .drawFunc_({ + slices_fa.do{ + arg start_samp; + var x = start_samp.linlin(0,audio_buf.numFrames,0,bounds.width); + Pen.line(Point(x,0),Point(x,bounds.height)); + Pen.color_(Color.red); + Pen.stroke; + }; + }); }); - - win.front; }); + + win.front; }.play(AppClock); } } From 511a8d19d4b35d89c68446e4bb8eb2c04171e01d Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Wed, 3 Nov 2021 15:14:51 +0000 Subject: [PATCH 10/13] initialize with internal dict a plotter initialized with no 'dict' now makes an empty internal dict so that one can use 'setPoint' and 'addPoint' right off the bat --- release-packaging/Classes/FluidPlotter.sc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index f2637a0..601b001 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -34,6 +34,7 @@ FluidPlotter { ymax = ymax_; this.createCatColors; + dict_internal = Dictionary.new; if(dict_.notNil,{this.dict_(dict_)}); this.createPlotWindow(bounds,parent_,mouseMoveAction,dict_); } @@ -47,7 +48,7 @@ FluidPlotter { categories_ { arg labelSetDict; - if(dict_internal.notNil,{ + if(dict_internal.size == 0,{ var label_to_int = Dictionary.new; var counter = 0; dict_internal.keysValuesDo({ @@ -98,7 +99,9 @@ FluidPlotter { setPoint_ { arg identifier, x, y, color, size = 1; + dict_internal.put(identifier,FluidPlotterPoint(identifier,x,y,color ? Color.black,size)); + this.refresh; } From e0d30986a2ec5b65fc29fd44e7c0b77cbd1512d2 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Wed, 3 Nov 2021 16:09:53 +0000 Subject: [PATCH 11/13] FluidWaveform helpfile made --- .../HelpSource/Classes/FluidWaveform.schelp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 release-packaging/HelpSource/Classes/FluidWaveform.schelp 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 44f91f8e820273f34a038a41b827c562ab8fb669 Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Thu, 4 Nov 2021 09:32:17 +0000 Subject: [PATCH 12/13] removed 'fromHex' in FluidPlotter --- release-packaging/Classes/FluidPlotter.sc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index 601b001..a73e992 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -40,10 +40,13 @@ FluidPlotter { } createCatColors { - catColors = "1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf".clump(6).collect({ - arg hex; - Color.newHex(hex); - }); + catColors = "1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf".clump(6).collect{ + arg six; + Color(*six.clump(2).collect{ + arg two; + "0x%".format(two).interpret / 255; + }); + }; } categories_ { From 159676b6d5c76676be186f5e195dadf6a727b98b Mon Sep 17 00:00:00 2001 From: Ted Moore Date: Thu, 4 Nov 2021 09:32:17 +0000 Subject: [PATCH 13/13] removed 'fromHex' in FluidPlotter --- release-packaging/Classes/FluidPlotter.sc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-packaging/Classes/FluidPlotter.sc b/release-packaging/Classes/FluidPlotter.sc index a73e992..9ef709d 100644 --- a/release-packaging/Classes/FluidPlotter.sc +++ b/release-packaging/Classes/FluidPlotter.sc @@ -51,7 +51,7 @@ FluidPlotter { categories_ { arg labelSetDict; - if(dict_internal.size == 0,{ + if(dict_internal.size != 0,{ var label_to_int = Dictionary.new; var counter = 0; dict_internal.keysValuesDo({