[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-dev] [commit] multichannel Buffer-plot and Function-plot



Hi Scott,
I think i posted earlier that i have a SoundFilePlot that displays interlaced multichannel SoundFiles like a Scope.
this is much faster than using a MultiSlider.
And it has the x-axis as frames or time. I did not commit it yet because i think it could need some more testing and there are some things that i would like to add, like different kinds of selection-functionalities.
if you like i can commit the current state, so you can have a look.

-jan

On Dec 21, 2004, at 6:44 PM, Scott Wilson wrote:

Hi all,

I've just committed changes to ArrayedCollection-plot, which add a numChannels argument. This treats the array as an interlaced multichannel dataset. The default is 1, and it comes last, so this should not break anything. At some point it would probably be good to move the code which draws the views to a separate method, as this would allow plotting nested arrays, but for the moment this works well enough with interlaced data such as one gets from SoundFile, etc. The option to express things like time rather than index would also be useful.

This allows for two things: Correct plotting of multichannel Buffers, and a rudimentary implementation of Function-plot. The latter is somewhat limited, and could probably be done better another way, but it's a start. At the moment it's audio rate only (as RecordBuf is as well...) and operates in realtime. Ideally it would be NRT, but given the lingering Panther popen bug I figured this was a better way to go. It also doesn't work with explicit Out UGens (need those Float-from32bits and Float-from64bits methods to get a SynthDesc without writing to disk) so your function should return a UGen or an Array of them. I suppose an alternative implementation would be to store the def and then just delete it afterwards, but in any case what I've committed is there and working. Help file is updated with examples.

Cheers from snowy Poland...

S.

________________

+ ArrayedCollection{
	
	plot { arg name, bounds, discrete=false, numChannels = 1;
var plotter, txt, chanArray, unlaced, val, minval, maxval, window, thumbsize, zoom, width,
			layout;
		bounds = bounds ?  Rect(200 , 140, 705, 410);
		
		width = bounds.width-8;
		zoom = (width / (this.size / numChannels));
		
		if(discrete) {
			thumbsize = max(1.0, zoom);
		}{
			thumbsize = 1;
		};
		
		name = name ? "plot";
		minval = this.minItem;
		maxval = this.maxItem;
		unlaced = this.unlace(numChannels);
		chanArray = Array.newClear(numChannels);
		unlaced.do({ |chan, j|
			val = Array.newClear(width);
			width.do { arg i;
				var x;
				x = chan.blendAt(i / zoom);
				val[i] = x.linlin(minval, maxval, 0.0, 1.0);
			};
			chanArray[j] = val;
		});
		window = SCWindow(name, bounds);
		txt = SCStaticText(window, Rect(8, 0, width, 18))
				.string_("index: 0, value: " ++ this[0].asString);
		layout = SCVLayoutView(window, Rect(4, txt.bounds.height, width,
			bounds.height - 30 - txt.bounds.height)).resize_(5);
		numChannels.do({ |i|
			plotter = SCMultiSliderView(layout, Rect(0, 0,
					layout.bounds.width,layout.bounds.height))
				.readOnly_(true)
				.drawLines_(discrete.not)
				.drawRects_(discrete)
				.thumbSize_(thumbsize)
				.valueThumbSize_(1)
				.colors_(Color.black, Color.blue(1.0,1.0))
				.action_({|v|
txt.string_("index: " ++ (v.index / zoom).roundUp(0.01).asString ++ ", value: " ++ v.currentvalue.linlin(0.0, 1.0, minval, maxval).asString) })
				.value_(chanArray[i])
				.resize_(5)
				.elasticMode_(1);
		});
		^window.front;
		
	}
}

+ Function {
	plot { arg duration  = 0.01, server, bounds;
		var buffer, def, synth, name, value, numChannels;
		server = server ? Server.default;
server.isLocal.not.if({"Function-plot only works with a localhost server".warn; ^nil });
		server.serverRunning.not.if({"Server not running!".warn; ^nil });
		value = this.value;
if(value.size == 0, { numChannels = 1 }, { numChannels = value.size }); buffer = Buffer.new(server, duration * server.sampleRate, numChannels);
		// no need to check for rate as RecordBuf is ar only
		name = this.hash.asString;
		def = SynthDef(name, {
			RecordBuf.ar(this.value,  buffer.bufnum, loop:0);
			Line.ar(dur: duration, doneAction: 2);
		});
		Routine.run({
			var c;
			c = Condition.new;
			server.sendMsgSync(c, *buffer.allocMsg);
			server.sendMsgSync(c, "/d_recv", def.asBytes);
			synth = Synth.basicNew(name, server);
			OSCpathResponder(server.addr, ['/n_end', synth.nodeID], {
				buffer.loadToFloatArray(action: { |array, buf|
					{array.plot(bounds: bounds, numChannels: buf.numChannels) }.defer;
					buffer.free;
				});
			}).add.removeWhenDone;
			server.listSendMsg(synth.newMsg);
		});
	}

}_______________________________________________
sc-dev mailing list
sc-dev@xxxxxxxxxxxxxxx
http://www.create.ucsb.edu/mailman/listinfo/sc-dev