SCScope oscilliscope: render a buffer to a view in real time
Inherits from: Object : SCView
An oscilloscope-type view.
See also: SCStethoscope, SCFreqScope,SCFreqScopeWindow
Some Important Issues Regarding SCScope
SCScope can only work with the internal Server.
Creation / Class Methods
*new (parent, bounds)
parent - The parent view.
bounds - An instance of Rect, or a Point indicating width@height.
Accessing Instance and Class Variables
bufnum
bufnum_ (num)
num - An integer.The bufnum of the scope's Buffer.
style_ (val)
The display style of the scope.
val - an integer.
0 = vertically spaced
1 = overlapped
2 = x/y
xZoom
xZoom_ (val)
The x- scaling of the scope.
val - An instance of Float. Must be in steps of 2**(1/n ), where n is a positive integer
yZoom
yZoom_ (val)
The y- scaling of the scope. Must be in steps of 2**(1/n ), where n is a positive integer
val - An instance of Float.
x
x_ (val)
The x offset of the scope in samples.
val - An Integer.
waveColors
waveColors_ (arrayOfColors)
arrayOfColors - An Array of Colors. [ color1, color2, color2, ...], corresponding to the number of channels.
Subclassing and Internal Methods
The following methods are usually not used directly or are called by a primitive. Programmers can still call or override these as needed.
properties
returns;
[ \bounds, \visible, \enabled, \canFocus, \resize, \background, \minWidth, \maxWidth, \minHeight, \maxHeight, \bufnum, \x, \y, \xZoom, \yZoom, \gridColor, \waveColors, \style]
gridColor
gridColor_ (color)
y
y_ (val)
Examples
// execute these in succession
// the cross platform syntax for SCScope is ScopeView
(
s = Server.internal;
s.boot;
)
(
f = Buffer.alloc(s,1024,2);
b = Bus.audio(s,1);
w=Window.new.front;
c = ScopeView(w.view,w.view.bounds.insetAll(10,10,10,10)); // this is SCScope
c.bufnum = f.bufnum;
)
(
// listening to the bus, using ScopeOut to write it to the buffer
a=SynthDef("monoscope", { arg bus, bufnum;
var z;
z = In.ar(bus,2);
// ScopeOut writes the audio to the buffer
ScopeOut.ar(z, bufnum);
}).play(
RootNode(s),
[\bus,b.index, \bufnum, f.bufnum] ,
\addToTail // make sure it goes after what you are scoping
);
// making noise onto the buffer
d=SynthDef("noise", { arg bus;
var z;
z = LFSaw.ar(SinOsc.kr(0.1).range(300,1000),[0,1]*pi) * 0.1;
Out.ar(bus, z);
}).play(
s,
[\bus,b.index]
);
)
c.style = 0 // vertically spaced
c.style = 1 // overlapped
c.style = 2 // x/y
(
//remember to free your stuff when finished
a.free;
d.free;
f.free;
b.free;
w.close;
)
/***** Interactive Example with Sound (explains all the options) *****/
(
s = Server.internal;
s.waitForBoot({
var func, sdef1, sdef2, syn1, syn2,startButton ;
f = Buffer.alloc(s,1024,2);
b = Bus.audio(s,1);
w=Window("Scope", Rect(150, SCWindow.screenBounds.height-500,790,400)).front;
c = ScopeView(w,Rect(10,10,380,380)); // this is SCScope
c.bufnum = f.bufnum;
v=CompositeView(w,Rect(400,10,380,380)).background_(Color.rand(0.7));
v.decorator = n = FlowLayout(v.bounds, margin: 0@0, gap: 5@5);
a = StaticText(v, Rect(20, 70, 90, 20)).string_(" xZoom = 1").background_(Color.rand);
m = Slider(v, Rect(20, 60, 285, 20)).background_(a.background).action_({func.value}).value_(0.5);
d = StaticText(v, Rect(20, 70, 90, 20)).string_(" yZoom = 1").background_(Color.rand);
g = Slider(v, Rect(20, 60, 285, 20)).background_(d.background).action_({func.value}).value_(0.5);
h = StaticText(v, Rect(20, 70, 90, 20)).string_(" x = 0").background_(Color.rand);
i = Slider(v, Rect(20, 60, 285, 20)).background_(h.background).action_({func.value}).value_(0.5);
Button(v, Rect(0,0,380, 20))
.states_([["waveColors = [ Color.rand, ... ]",Color.black,Color.rand]])
.action_({c.waveColors = [Color.rand,Color.rand]});
Button(v, Rect(0,0,380, 20))
.states_([[" background = Color.rand(0.1,0.3) ",Color.black,Color.rand]])
.action_({c.background = Color.rand(0.1,0.3) });
t= Button(v, Rect(0,0,380, 20))
.states_([["Current style is 0",Color.black,Color.rand],
["Current style is 1",Color.black,Color.rand],
["Current style is 2",Color.black,Color.rand]])
.action_({func.value});
func={
c.xZoom = ([0.25, 10, \exp, 1/8, 1].asSpec.map(m.value)); a.string = " xZoom = %".format(c.xZoom);
c.yZoom = ([0.25, 10, \exp, 1/8, 1].asSpec.map(g.value)); d.string = " yZoom = %".format(c.yZoom);
c.x = ([ -1024,1024, \linear, 1/8, 1].asSpec.map(i.value)); h.string = " x = %".format(c.x);
// c.y = ([-1,1, \linear, 1/16, 1].asSpec.map(k.value)); j.string = " y = %".format(c.y);
c.style=t.value
};
startButton = Button.new(v, Rect(0,0,380, 50))
.states_([["Start Sound",Color.black,Color.green],["Stop Sound",Color.black,Color.red]]).action_({});
startButton.action_{
(startButton.value==1).if{
syn1=SynthDef("test1", { arg bus, bufnum;
var z;
z = In.ar(bus,2);
// ScopeOut writes the audio to the buffer
ScopeOut.ar(z, bufnum);
Out.ar(0,z);
}).play(
RootNode(s),
[\bus,b.index, \bufnum, f.bufnum] ,
\addToTail // make sure it goes after what you are scoping
);
// making noise onto the buffer
syn2=SynthDef("test2", { arg bus;
var z;
z = PMOsc.ar([300,250],*SinOsc.ar([0.027,0.017])*pi) * 0.1;
Out.ar(bus, z);
}).play(s,[\bus,b.index]);
}{syn1.free; syn2.free};
};
w.onClose={syn1.free; syn2.free; b.free; f.free};
CmdPeriod.doOnce({w.close});
})
)