Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / HelpSource / Guides / Tracing-Processes.schelp
blob520aa438fd126c359010cd6fab2cc6033e9b0020
1 title:: Tracing Processes
2 summary:: Tracing processes in SC
3 categories:: Debugging
4 related:: Guides/Debugging-tips
6 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).
8 section:: Tracing sclang processes
10 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.
12 calculating the sum of n subsequent squares
13 code::
14 var n = 8, x = 0;
15 (1..n).do { |num| x = x + num.squared };
19 what happens while we are doing this?
20 code::
21 var n = 8, x = 0;
22 (1..n).do { |num| x = x + num.squared.postln; };
25 or more in detail:
26 code::
27 var n = 8, x = 0;
28 (1..n).do { |num| [\before, x].postln; x = x + num.squared; [\after, x].postln;};
32 when posting several values, some more verbose posts can be useful.
33 postf formats a string and inserts values for %-characters.
34 here separate statements are needed.
35 code::
36 var n = 8, x = 0;
37 (1..n).do { |num| x = x + num.squared; "num: % num-squared: % new x: %\n".postf(num, num.squared, x) };
41 in some cases, postln will only post part of the data, or a simplified
42 representation.
43 code::
44 // n times 200 random numbers
45 // will just add ... etc ... after 123
46 var n = 3;
47 (1..n).do { |num| { 1000.rand }.dup(200).postln };
50 posts the compile string, i.e. the code needed to recreate the receiver (here the array)
51 code::
52 var n = 3;
53 (1..n).do { |num| { num.rand }.dup(200).postcs };
56 subsection:: Streams, tasks and routines
57 in streams, tasks and routines, this works just as well:
58 code::
59 fork {
60         var n = 14;
61         (1..n).do { |num|
62                 { num.rand }.dup(200).postcs;
63                 1.wait;
64         };
68 code::
69 fork {
70         var str = Routine { |in| 10.do { in = in.rand.yield } };
71         12.0.do { |i|
72                 str.next(i).postln;
73                 0.5.wait;
74         };
79 for creating a pattern that once it is used posts its values,
80 the message trace can be used (in returns a Ptrace)
81 code::
82 a = Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf).trace(prefix: "value: ");
83 b = a.asStream;
84 b.next;
85 b.next;
86 b.next;
87 b.next;
90 in a running stream:
91 code::
92 Pbind(
93         \degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf).trace(prefix: "value: "),
94         \dur, 0.2
95 ).play
98 post only a slot of the events
99 code::
100 Pbind(
101         \degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf),
102         \dur, 0.2
103 ).trace(\degree).play
106 several slots at once:
107 code::
108 Pbind(
109         \degree, Pseq([1, 4, 1, Pwhite(0, 6, 3), 100, 39], inf),
110         \dur, Pwhite(0.2, 0.4, inf)
111 ).trace([\degree, \dur], prefix: ["degree ", "dur "]).play
114 section:: Tracing server processes
116 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)
117 code::
118 // postln returns only the UGen itself (a MulAdd here)
119 { SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).postln) * 0.1 }.play;
121 // poll traces the values
122 { SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).poll) * 0.1 }.play;
124 // using a label:
125 { SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400).poll(label: "freq")) * 0.1 }.play;
128 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)
130 code::
131 { SinOsc.ar(Duty.kr(0.5, 0, (Dseries(0, 1, inf) * 200 + 300).dpoll)) * 0.1 }.play;
133 { SinOsc.ar(Duty.kr(0.5, 0, (Dseries(0, 1, inf) * 200 + 300).dpoll(label: "freq"))) * 0.1 }.play;
136 When using the internal server (see link::Classes/Server:: help), the scope window can give valuable information about the ongoing sound (see link::Classes/Stethoscope:: help):
137 code::
138 // must use internal server
139 s = Server.internal.boot;
140 { SinOsc.ar(SinOsc.kr(0.2, 0, 300, 400)) * 0.1 }.scope;
142 A FreqScope window can be used for observing the spectrum of the output:
143 code::
144 // must use internal server
145 Server.default = s = Server.internal.boot;
147 // create a new analyzer
148 FreqScope.new;
150 { SinOsc.ar(SinOsc.ar(0.2, 0, 3000, 4000)) * 0.1 }.play;
151 { SinOsc.ar(SinOsc.ar((1..4) * 0.02, 0, 3000, 4000)).sum * 0.1 }.play;