SwingOSC – Java-based cross-platform replacements for Cocoa GUI classes
This class is meant as an emulation of Stethoscope class. last mod: 21-jan-07 sciss
no-op / not working
different behaviour
server uses Server.default instead of Server.internal. the default server
cannot be the internal server, however.
threading methods needn't be called in the app thread
painting the lines are slightly thinner
extended functionality
known issues / todo
updates sometimes the display update stops; to re-start, press + and –
; there is jitter since the /b_getn commands are not in sync
with the RecordBuf UGen ; this is visible as "glitches" in the waveform
gridColor (JSCScope) not yet working
synchronization when changing buffers, a "/b_getn index of out range error" can occur
which is harmless, however
activity since in this implementation the scope view doesn't get any information about
the scope synth, pausing the synth (pressing period) will not pause the display
update, so there's still OSC traffic even when the display is frozen
this could possibly be fixed with some trick
switching chan # (bug) sometimes switching the # of channels results in wrong display
JStethoscope scope window
Note: please use the abstraction layer GUI.stethoscope if possible! (see [GUI])
a graphical interface to navigate on buses
Note: the following doesn't apply to SwingOSC:
"works only with internal server"
instead : SwingOSC can not scope the
internal server because it has no network address.
However, instead of assuming Server.local to be the
scope'd server, we also refer to Server.default, thus
be sure to make Server.default = Server.local
the scope window can be controlled by the following keys:
Note: the scope panel has no initial focus as of v0.38, click once into the panel to make it active and respond to keyboard presses.
J one channel back
K switch rate (audio vs. control)
L one channel forward
O jump to first hardware output channel and adjust numChannels to hardware
I jump to first hardware input channel and adjust numChannels to hardware
space run, if not running anyway.
. (period) stop.
M toggle screen size
+ / - zoom horizontally
* / _ zoom vertically
S change style between parallel and overlay
shift S change style to lissajou (use only with fast computer and small buffer size)
Note: in this mode, channel 0 controls horizontal beam, channel 1 vertical beam
(unlike a normal oscilloscope in XY mode, where the second channel controls h.beam)
Note: there is a nice bug in SwingOSC ;-) that allows you to go back to parallel or
overlap mode without leaving lissajou. this happens if you do not disable lissajou by
pressing shift+S again, but instead go to the other modes pressing S.
shift A allocate buffer size so it fills the screen (to next power of two)
// "this can be dangerous, might crash" (not dangerous in SwingOSC)
Note: it seems the default zoom is always such that only 1/4th of the waveform snapshot
is shown ; if you don't wish to zoom out, shift+A will speed up display signifcantly
because OSC traffic decreases and RecordBuf's cycle duration is much smaller
instance creation:
*new(server, numChannels, index, bufsize, zoom, rate, view)
returns a new instance of Stethoscope.
by the message .scope:
aServer.scope(numChannels, index, bufsize, zoom, rate)
opens a scope window for the server, stores it in the server instance var scopeWindow
aBus.scope(bufsize, zoom)
displays buffer channels in scope
aFunction.scope(numChannels, outbus, fadeTime, bufsize, zoom)
plays a function and shows output in scope, returns synth object, like { }.play
instance methods:
allocBuffer(size)
(re)allocate the buffer to a given size
run
start it if not playing anyway
free
end it, free the buffer
numChannels_
change the number of channels displayed
index_
change the offset index
rate_
change the rate (\audio or \control)
size_
set the window size (default: 222)
zoom_
set horizontal zoom
setProperties( numChannels, index, bufsize, zoom, rate )
any of these given will adjust the scope accordingly:
e.g. x.setProperties(zoom:8) will only zoom.
// examples:
(
Server.default = Server.local; // Server.internal;
s = Server.default;
s.boot;
)
(
{
SinOsc.ar([225, 450, 900], 0, 0.2)
+ LPF.ar(
LFPulse.ar(226 * [1, 2, 5],[0,0.1,0.1],0.2, 0.2),
JMouseX.kr(20, 10000, 1)
)
}.jscope;
)
// compare to cocoa
Server.internal.boot;
(
{
SinOsc.ar([225, 450, 900], 0, 0.2)
+ LPF.ar(
LFPulse.ar(226 * [1, 2, 5],[0,0.1,0.1],0.2, 0.2),
JMouseX.kr(20, 10000, 1)
)
}.scope;
)
// much faster with smaller buffer size (default is 4096)
(
{
SinOsc.ar([225, 450, 900], 0, 0.2)
+ LPF.ar(
LFPulse.ar(226 * [1, 2, 5],[0,0.1,0.1],0.2, 0.2),
JMouseX.kr(20, 10000, 1)
)
}.jscope( bufsize: 1024 );
)
JMouseBase.makeGUI;
// server.scope only changes the properies explicitly given:
s.jscope(numChannels:5);
s.jscope(index:12);
s.jscope(zoom:4);
s.jscope(index:0);
s.scopeWindow.size = 600;
s.scopeWindow.size = 222;
// scoping buses:
a = Bus.audio(s, 4);
{ WhiteNoise.ar(0.2.dup(4)) }.play(s, a.index);
a.jscope;
c = Bus.control(s, 3);
{ WhiteNoise.kr(1.dup(4) * JMouseX.kr) }.play(s, c.index);
c.jscope;
JMouseBase.makeGUI;
// note that scoping control rate buses shows block size interpolation (this is due to the
// fact that ScopeOut.kr doesn't work yet.) (RecordBuf.kr neither)
external use: you can pass your own view in to add a stethoscope to it;
(
w = JSCWindow.new("my own scope", Rect(20, 20, 400, 500));
w.view.decorator = FlowLayout(w.view.bounds);
c = JStethoscope.new(s, view:w.view);
w.onClose = { c.free }; // don't forget this
w.front;
)