# How to plot a SynthDef?

I just recently resumed my attempts at learning SuperCollider, and I am trying to make the leap from `play`ing functions directly to using SynthDefs. There seems to be one critically important ability (for a learner at least) that I seem to have lost while making this leap: the ability to See What I Compute.

How do I graph the output of a Synth created from a SynthDef?

There are two or three ways you can introspect the output or internal state of a Synth - the most easy and straightforward is to use the `poll` method:

``````SynthDef(\foo, {
var lfo = SinOsc.kr(1/10);
lfo.poll(1, "lfo");
``````

I built a slightly more accessible tool to graph control values of a Synth - youâ€™re welcome to try it out. Iâ€™ve been working on a bigger SynthDef introspection library to solve exactly this problem in a much more open-ended and automatic way, but thatâ€™s a long way off from being completeâ€¦

(Youâ€™ll need to include this or add it to and extension folder)

Example (you can reset min and max values by clicking on them):

``````~bus = Bus.control(s, 1);
SynthDef(\foo, {
var cutoff, sig;
sig = LFSaw.ar(120);
cutoff = SinOsc.kr(1/10).range(100, 400);
Out.kr(~bus, cutoff);
sig = LPF.ar(sig, cutoff);

~bus.debugScope();
``````
1 Like

You can also use `get`.

From the `Synth` help file:

``````(
SynthDef("help-Synth-get", { | out, freq = 440|
Out.ar(out, SinOsc.ar(freq, 0, 0.1));
)
x = Synth("help-Synth-get");
x.set(\freq, 220 + 440.rand);
x.get(\freq, { arg value; ("freq is now:" + value + "Hz").postln; });
x.free;
``````

BTW the reason why we can have `{ ... }.plot` but not `SynthDef(...).plot` is:

• When plotting a function, we can assume that the functionâ€™s return value (which is a network of UGen connections) is the signal that you want to plot.

• If itâ€™s a SynthDef, there is no guaranteed, reliable way to know what signal to plot. SynthDefs use `Out.ar` to write the signal to a bus. To plot, we would need to know which bus. There is a loose convention that SynthDefs should have an `out` argument for the output bus number. But if the user said `outbus` or `bus` or `audioOutputBus`, how would SynthDef:plot know this? (Worse, a lot of new users take a shortcut and write `Out.ar(0, ...)` in which case it would be impossible for a hypothetical SynthDef:plot method to isolate the signal from other things playing at the same time.)

`poll` is one workaround.

Another is to write a RecordBuf into the SynthDef (temporarily, delete it later), then plot the bufferâ€™s contents.

``````s.boot;

b = Buffer.alloc(s, 44100, 1);

(
// hack the default synthdef
SynthDef(\default, { arg out = 0, freq = 440, amp = 0.1, pan = 0, gate = 1;
var z;
z = LPF.ar(
Mix.new(VarSaw.ar(freq + [0, Rand(-0.4, 0.0), Rand(0.0, 0.4)], 0, 0.3, 0.3)),
XLine.kr(Rand(4000, 5000), Rand(2500, 3200), 1)
) * Linen.kr(gate, 0.01, 0.7, 0.3, 2);
RecordBuf.ar(z, b, loop: 0, doneAction: 2);  // <<-- inserted
OffsetOut.ar(out, Pan2.ar(z, pan, amp));
)

a = Synth(\default);  // will stop by itself

b.plot

b.getToFloatArray(wait: -1, timeout: 5, action: { |data| d = data; "done".postln });

d[0..500].plot;
``````

hjh

1 Like

@scztt
Hi Scott, your debugScope is so damn useful, I use it regularly in development and have suggested it to students and friends. How about making a Quark of it? I would happily do that if you donâ€™t have time, but I would like to know what you think about it, and correctly credit you.

And through time Iâ€™ve made little changes to your method, mainly to improve display using Layouts. Youâ€™ll find my version as a comment to your gist

I think this a fantastic idea. I think I did some initial sketches for a broader â€śserver debuggingâ€ť quark, that used this as a starting point, but it didnâ€™t go to far. Iâ€™ve actually fallen out of using it a little because I mostly debug with the `NodeSnapshot` quark in my day-to-day work, but if it were cleaned up a little it would fit right in as an additional tool for that Quark as well.

Iâ€™m going to try to find some time in the next week to do some basic clean-up and Quark-ification of it. From there, you (or anyone else) are welcome to add functionality - maybe it can become a basis for some more diverse debugging tools, or maybe it just gets a bit easier for students to install and use

1 Like