3 plot { arg name, bounds, discrete=false, numChannels, minval, maxval, parent, labels=true;
4 var plotter, txt, chanArray, unlaced, val, window, thumbsize, zoom, width,
5 layout, write=false, msresize, gui;
12 if(parent.respondsTo(\view)) {
18 Rect(200 ,140, 705, 410);
22 width = bounds.width - 8;
26 numChannels = numChannels ? this.first.size.max(1);
27 flattened = if(numChannels > 1) { this.flat } { this };
28 unlaced = flattened.unlace(numChannels);
30 minval = if(minval.isArray) {
31 numChannels.collect {|index| minval.wrapAt(index) ?? { unlaced[index].minItem } }
33 { minval ?? { flattened.minItem } }.dup(numChannels);
35 maxval = if(maxval.isArray) {
36 numChannels.collect{|index| maxval.wrapAt(index) ?? { unlaced[index].maxItem } }
38 {maxval ?? { flattened.maxItem }}.dup(numChannels);
41 chanArray = Array.newClear(numChannels);
44 thumbsize = max(1.0, width / (flattened.size / numChannels));
45 unlaced.do { |chan, j|
46 chanArray[j] = chan.linlin( minval[j], maxval[j], 0.0, 1.0 );
49 zoom = (width / (flattened.size / numChannels));
51 unlaced.do { |chan, j|
52 val = Array.newClear(width);
55 x = chan.blendAt(i / zoom);
56 val[i] = x.linlin(minval[j], maxval[j], 0.0, 1.0);
61 window = parent ?? { gui.window.new( name, bounds ) };
63 layout = gui.vLayoutView.new(window,
65 Rect(bounds.left + 4, bounds.top + 4, bounds.width - 10, bounds.height - 10)
67 Rect(4, 4, bounds.width - 10, bounds.height - 10)
72 txt = gui.staticText.new(layout, Rect( 8, 0, width, 18))
73 .string_("index: 0, value: " ++ flattened[0].asString);
77 plotter = gui.multiSliderView.new(layout,
79 // compensate for the text
80 layout.bounds.width, layout.bounds.height - if(labels, {26}, {0})
83 .drawLines_(discrete.not)
85 .indexThumbSize_(thumbsize)
87 .background_(Color.white)
88 .colors_(Color.black, Color.blue(1.0,1.0))
91 curval = v.currentvalue.linlin(0.0, 1.0, minval[i], maxval[i]);
94 txt.string_("index: " ++ (v.index / zoom).roundUp(0.01).asString ++
95 ", value: " ++ curval);
97 if(write) { flattened[(v.index / zoom).asInteger * numChannels + i ] = curval };
99 .keyDownAction_({ |v, char|
100 if(char === $l) { write = write.not; v.readOnly = write.not; };
102 .value_(chanArray[i])
104 if(numChannels > 1) { plotter.resize_(5) };
107 ^window.tryPerform(\front) ?? { window }
114 plot { arg name, bounds;
116 super.plot(name, bounds);
123 plot { arg name, bounds, minval, maxval, parent, labels=true;
124 ^this.asSignal.plot(name, bounds, minval: minval, maxval: maxval, parent: parent, labels: labels);
129 plot { arg name, bounds, minval = -1.0, maxval = 1.0, parent, labels=true;
132 this.loadToFloatArray(action: { |array, buf|
135 array.plot(name, bounds, numChannels: buf.numChannels, minval: minval, maxval: maxval, parent: parent, labels: labels);
144 loadToFloatArray { arg duration = 0.01, server, action;
145 var buffer, def, synth, name, numChannels, val, rate;
146 server = server ? Server.default;
147 if(server.serverRunning.not) { "Server not running!".warn; ^nil };
149 name = this.hash.asString;
150 def = SynthDef(name, { |bufnum|
151 var val = this.value;
152 if(val.isValidUGenInput.not) {
154 Error("loadToFloatArray failed: % is no valid UGen input".format(val)).throw
156 val = UGen.replaceZeroesWithSilence(val.asArray);
158 if(rate == \audio) { // convert mixed rate outputs:
159 val = val.collect { |x| if(x.rate != \audio) { K2A.ar(x) } { x } }
161 if(val.size == 0) { numChannels = 1 } { numChannels = val.size };
162 RecordBuf.perform(RecordBuf.methodSelectorForRate(rate), val, bufnum, loop:0);
163 Line.perform(Line.methodSelectorForRate(rate), dur: duration, doneAction: 2);
169 numFrames = duration * server.sampleRate;
170 if(rate == \control) { numFrames = numFrames / server.options.blockSize };
171 buffer = Buffer.new(server, numFrames, numChannels);
172 server.sendMsgSync(c, *buffer.allocMsg);
173 server.sendMsgSync(c, "/d_recv", def.asBytes);
174 synth = Synth(name, [\bufnum, buffer], server);
175 OSCpathResponder(server.addr, ['/n_end', synth.nodeID], {
176 buffer.loadToFloatArray(action: { |array, buf|
177 action.value(array, buf);
179 server.sendMsg("/d_free", name);
181 }).add.removeWhenDone;
185 plot { arg duration = 0.01, server, bounds, minval = -1.0, maxval = 1.0, parent, labels=true;
188 this.loadToFloatArray(duration, server, { |array, buf|
190 numChan = buf.numChannels;
193 array.plot(bounds: bounds, numChannels: numChan, minval: minval, maxval: maxval,
194 parent: parent, labels: labels)
203 plotGraph { arg n=500, from = 0.0, to = 1.0, name, bounds, discrete = false,
204 numChannels, minval, maxval, parent, labels = true;
205 var array = Array.interpolation(n, from, to);
206 var res = array.collect { |x| this.value(x) };
207 res.plot(name, bounds, discrete, numChannels, minval, maxval, parent, labels)
210 plotGraph2 { arg n=500, from = 0.0, to = 1.0, name, bounds, discrete = false,Ê
211 numChannels, minval, maxval, parent, labels = true;
212 var array = Array.interpolation(n, from, to);
213 var res = array.collect { |x| this.value(x) };
214 res.plot2(name, bounds, discrete, numChannels, minval, maxval, parent, labels)
223 bounds = bounds ?? { Rect( 200, 140, 705, 410 )};
224 win = gui.window.new(this.path.split.last, bounds);
225 view = gui.soundFileView.new(win, win.bounds.width@win.bounds.height).resize_(5);
226 view.soundfile_(this);
227 view.elasticMode_(1);