/usr/share/SuperCollider/HelpSource/Guides/Tracing-Processes.schelp is in supercollider-common 1:3.6.3~repack-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | title:: Tracing Processes
summary:: Tracing processes in SC
categories:: Debugging
related:: Guides/Debugging-tips
What goes on in a running system? In SC, various methods help to get information about processes on different levels: server side and client side (in sclang).
section:: Tracing sclang processes
In order to know more about objects as they are created by processes like tasks or even simply by evaluating a bit of code, one can insert messages like postln and postcs anywhere in the code.
calculating the sum of n subsequent squares
code::
var n = 8, x = 0;
(1..n).do { |num| x = x + num.squared };
x
::
what happens while we are doing this?
code::
var n = 8, x = 0;
(1..n).do { |num| x = x + num.squared.postln; };
x
::
or more in detail:
code::
var n = 8, x = 0;
(1..n).do { |num| [\before, x].postln; x = x + num.squared; [\after, x].postln;};
x
::
when posting several values, some more verbose posts can be useful.
postf formats a string and inserts values for %-characters.
here separate statements are needed.
code::
var n = 8, x = 0;
(1..n).do { |num| x = x + num.squared; "num: % num-squared: % new x: %\n".postf(num, num.squared, x) };
x
::
in some cases, postln will only post part of the data, or a simplified
representation.
code::
// n times 200 random numbers
// will just add ... etc ... after 123
var n = 3;
(1..n).do { |num| { 1000.rand }.dup(200).postln };
::
posts the compile string, i.e. the code needed to recreate the receiver (here the array)
code::
var n = 3;
(1..n).do { |num| { num.rand }.dup(200).postcs };
::
subsection:: Streams, tasks and routines
in streams, tasks and routines, this works just as well:
code::
fork {
var n = 14;
(1..n).do { |num|
{ num.rand }.dup(200).postcs;
1.wait;
};
}
::
code::
fork {
var str = Routine { |in| 10.do { in = in.rand.yield } };
12.0.do { |i|
str.next(i).postln;
0.5.wait;
};
}
::
for creating a pattern that once it is used posts its values,
the message trace can be used (in returns a Ptrace)
code::
a = Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf).trace(prefix: "value: ");
b = a.asStream;
b.next;
b.next;
b.next;
b.next;
::
in a running stream:
code::
Pbind(
\degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf).trace(prefix: "value: "),
\dur, 0.2
).play
::
post only a slot of the events
code::
Pbind(
\degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf),
\dur, 0.2
).trace(\degree).play
::
several slots at once:
code::
Pbind(
\degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf),
\dur, Pwhite(0.2, 0.4, inf)
).trace([\degree, \dur], prefix: ["degree ", "dur "]).play
::
section:: Tracing server processes
Using postln or post on a UGen will only return the UGen, but not the values it produces in a running synth. The poll message creates a Poll UGen which posts at regular intervals when given a time value or as a response to a trigger (see link::Classes/Poll:: helpfile)
code::
// postln returns only the UGen itself (a MulAdd here)
{ SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).postln) * 0.1 }.play;
// poll traces the values
{ SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).poll) * 0.1 }.play;
// using a label:
{ SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).poll(label: "freq")) * 0.1 }.play;
::
For demand ugens, poll does not work - these ugens are called by a Demand or Duty Ugen at certain intervals. The message dpoll creates a Dpoll ugen that posts when they are called (see link::Classes/Dpoll:: helpfile)
code::
{ SinOsc.ar(Duty.kr(0.5, 0, (Dseries(0, 1, inf) * 200 + 300).dpoll)) * 0.1 }.play;
{ SinOsc.ar(Duty.kr(0.5, 0, (Dseries(0, 1, inf) * 200 + 300).dpoll(label: "freq"))) * 0.1 }.play;
::
The scope window can give valuable information about the ongoing sound (see link::Classes/Stethoscope:: help):
code::
{ SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400)) * 0.1 }.scope;
::
A FreqScope window can be used for observing the spectrum of the output:
code::
// create a new analyzer
FreqScope.new;
{ SinOsc.ar(SinOsc.ar(0.2, 0, 3000, 4000)) * 0.1 }.play;
{ SinOsc.ar(SinOsc.ar((1..4) * 0.02, 0, 3000, 4000)).sum * 0.1 }.play;
::
|