3 summary:: An oscilloscope
4 categories:: GUI>Interfaces
5 related:: Classes/ScopeView, Classes/FreqScope
9 Stethoscope provides a complete oscilloscope GUI. It displays a window containing a bus-plotting link::Classes/ScopeView:: and an interface to configure the plotting and choose among the buses.
11 SUBSECTION:: Creation by message .scope
13 Several classes provide a convenient 'scope' method that creates a Stethoscope to display their data. See for example: link::Classes/Server#-scope::, link::Classes/Bus#-scope::, link::Classes/Function#-scope::.
15 SUBSECTION:: Keyboard shortcuts
17 The following keyboard shortcuts may be used when focused on the Stethoscope display:
20 ## strong::Shortcut:: || strong::Action::
21 ## J || one channel back
22 ## K || switch rate (audio vs. control)
23 ## L || one channel forward
24 ## O || jump to first hardware output channel and adjust numChannels to hardware
25 ## I || jump to first hardware input channel and adjust numChannels to hardware
26 ## space || run, if not running already
28 ## M || toggle screen size
29 ## + / - || zoom horizontally
30 ## * / _ || zoom vertically
31 ## S || change style between parallel and overlay
32 ## Shift+S || change style to lissajou
33 ## Shift+A || allocate buffer size so it fills the screen (to next power of two) (this can be dangerous, might crash)
42 Create a Stethoscope, either as a window, or placed on a given parent view.
45 A valid Server (see link::#*isValidServer::), or code::nil::, in which case the link::#*defaultServer:: is used.
46 argument:: numChannels
47 An integer. Default value is 2.
49 The offset index. An Integer. Default is nil.
51 The size of the analysis buffer. Default is 4096. See also link::#-bufsize::.
53 Horizontal maginification of the displayed wave. Default is 1. See also link::#-xZoom::.
55 \audio or \control. Default is \audio.
57 The optional parent view. Default is nil. If nil, then it will open in its own Window.
59 The id number of the Buffer to analyze. Default value is nil. If nil, then a Buffer of size bufSize is allocated.
64 Server.default = s = Server.internal
66 {SinOsc.ar([330,440], 0, 0.4)}.play;
70 METHOD:: defaultServer
72 The default server used if no server is passed to the link::#*new#constructor::.
75 METHOD:: isValidServer
77 Tests whether Stethoscope can operate on the given server.
79 This is the current state of server support:
81 ## strong::Qt::: any local server (see link::Classes/Server#-isLocal::).
82 ## strong::Cocoa::: only the in-process (internal) server (see link::Classes/Server#*internal:: and link::Classes/Server#-inProcess::).
83 ## strong::SwingOSC::: any out-of-process server, even remote (see link::Classes/Server#-inProcess::).
87 A link::Classes/Server::.
93 Returns an array of the running ugen scopes.
96 Server.default = s = Server.internal
98 {[SinOsc.ar.scope,WhiteNoise.ar(0.5).scope]*0.1}.scope(2);
99 Stethoscope.ugenScopes; // returns the ugen scopes
104 A utility method used by link::Classes/UGen#-scope:: to tile scope windows.
117 The server on which the scope operates.
120 Whether to operate on audio or control busses.
122 One of the two symbols: code::\audio:: or code::\control::.
125 The starting index of the busses to scope.
130 The amount of adjacent busses to scope (from link::#-index:: on).
135 The size of the scoping buffer.
137 In strong::Swing:: and strong::Cococa:: GUI kits, this is the amount of signal frames that will be accumulated before they are displayed. However, it is strong::NOT ensured:: that the onsets of displayed portions of signals fall within any constant period. In other words, it is undefined how many frames will pass between one displayed portion, and another.
139 In strong::Qt:: GUI, this is not the issue; code::bufsize:: only defines the maximum allowed link::#-cycle::.
142 note:: Only available in Qt GUI ::
144 The exact scoping period, in signal frames. Reciprocal to what is also known as emphasis::sweep speed:: in analog oscilloscopes. It is dynamically adjustable while the scope is running.
146 Data from scoped signals will be accumulated into a buffer until it reaches code::cycle:: amount frames, at which point the buffering will immediatly restart. The view will repeatedly display the entire buffer; it may skip a cycle if the drawing is too slow to keep up with the speed of incoming data, but the cycle boundaries will never shift with respect to signals.
148 If you are scoping a periodic signal, setting code::cycle:: to match the signal's period will keep the waveform locked in place.
153 The (parent) Window of the scope.
156 Sets the width and the height of the scope window.
158 An Integer (the window is square).
162 Toggle between small and large size.
165 A synonym for link::#-xZoom::.
168 Magnifies the displayed wave horizontally to the given factor.
170 In strong::Qt GUI::, this sets link::#-cycle:: to code::1024 * xZoom.reciprocal::.
176 Magnifies the displayed wave vertically to the given factor.
184 ## 0 = the channels are vertically spaced
185 ## 1 = the channels are overlayed
186 ## 2 = lissajou; the first two channels are used for 2D plotting (as streams of x and y coordinates).
190 One of the above Integers.
193 SUBSECTION:: Operation
197 Starts the scope, if not already running.
201 Closes the window, and cleans up any used synths and buffers.
203 SUBSECTION:: Convenience
205 METHOD:: setProperties
207 Sets several properties at once: link::#-numChannels::, link::#-index::, link::#-bufsize::, link::#-zoom::, and link::#-rate::.
213 SUBSECTION:: A step-by-step example
216 Server.default = Server.internal;
222 SinOsc.ar([225, 450, 900], 0, 0.2)
224 LFPulse.ar(226 * [1, 2, 5],[0,0.1,0.1],0.2, 0.2),
225 MouseX.kr(20, 10000, 1)
230 // server.scope only changes the properies explicitly given:
232 s.scope(numChannels:5);
237 s.scopeWindow.size = 600;
238 s.scopeWindow.size = 222;
243 { WhiteNoise.ar(0.2.dup(4)) }.play(s, a);
247 c = Bus.control(s, 3);
248 { WhiteNoise.kr(1.dup(4) * MouseX.kr) }.play(s, c);
252 // note that scoping control rate buses shows block size interpolation (this is due to the
253 // fact that ScopeOut.kr doesn't work yet.)
256 SUBSECTION:: Embedded use
257 You can pass your own view in to add a stethoscope to it:
260 w = Window.new("my own scope", Rect(20, 20, 400, 500));
261 w.view.decorator = FlowLayout(w.view.bounds);
262 c = Stethoscope.new(s, view:w.view);
263 w.onClose = { c.free }; // don't forget this