SwingOSC – Java-based cross-platform replacements for Cocoa GUI classes

This class is meant as an emulation of Stethoscope class. last mod: 17-jul-09 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 Stethoscope if possible!

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)

)

}.scope;

)

// 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)

)

}.scope( bufsize: 1024 );

)

JMouseBase.makeGUI;

// server.scope only changes the properies explicitly given:

GUI.swing; // Use swing for the stethoscope !

s.scope( numChannels: 5 );

s.scope( index: 12 );

s.scope( zoom: 4 );

s.scope( 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.scope;

c = Bus.control( s, 3 );

{ WhiteNoise.kr( 1.dup( 4 ) * JMouseX.kr )}.play( s, c.index );

c.scope;

JMouseBase.makeGUI;

// note that scoping control rate buses shows block size interpolation

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;

)