3 summary:: A buffer plotting view.
5 related:: Classes/Stethoscope, Classes/FreqScopeView, Classes/FreqScope
9 ScopeView is mainly intended to support the implementation of link::Classes/Stethoscope:: (an oscilloscope), link::Classes/FreqScopeView:: (a basic frequency spectrum plotting view) and link::Classes/FreqScope:: (a frequency spectrum analyzer tool).
11 It is optimized to efficiently perform frequent plotting of the contents of a link::Classes/Buffer:: into which a link::Classes/ScopeOut:: UGen is writing. It will periodically poll the buffer for data and update the plot, as long as the ScopeOut UGen is writing into it; the buffer will not be plotted otherwise.
22 The number of the Buffer to plot.
24 As soon as a valid buffer number is set and a link::Classes/ScopeOut:: UGen is writing into it, the view starts periodically plotting the buffer. If the ScopeOut UGen stops writing, or an invalid buffer number is set, the plotting will pause.
32 ## 0 = the channels are vertically spaced
33 ## 1 = the channels are overlayed
34 ## 2 = lissajou; the first two channels are used for 2D plotting (as streams of x and y coordinates).
38 One of the above Integers.
41 The scaling factor on the horizontal axis.
47 The scaling factor on the vertical axis.
53 The horizontal offset.
63 The colors used to plot each of the channels.
66 An Array of Colors, one per channel.
70 SUBSECTION:: A step-by-step example
73 // execute these in succession
79 f = Buffer.alloc(s,1024,2);
83 c = ScopeView(w.view,w.view.bounds.insetAll(10,10,10,10));
87 // listening to the bus, using ScopeOut to write it to the buffer
88 a=SynthDef("monoscope", { arg bus, bufnum;
91 // ScopeOut writes the audio to the buffer
92 ScopeOut.ar(z, bufnum);
95 [\bus,b.index, \bufnum, f.bufnum] ,
96 \addToTail // make sure it goes after what you are scoping
99 // making noise onto the buffer
100 d=SynthDef("noise", { arg bus;
102 z = LFSaw.ar(SinOsc.kr(0.1).range(300,1000),[0,1]*pi) * 0.1;
110 c.style = 0 // vertically spaced
111 c.style = 1 // overlapped
115 //remember to free your stuff when finished
124 SUBSECTION:: An interactive example with sound
126 This explains all the options:
134 var func, sdef1, sdef2, syn1, syn2,startButton ;
135 f = Buffer.alloc(s,1024,2);
138 w=Window("Scope", Rect(150, SCWindow.screenBounds.height-500,790,400)).front;
139 c = ScopeView(w,Rect(10,10,380,380)); // this is SCScope
142 v=CompositeView(w,Rect(400,10,380,380)).background_(Color.rand(0.7));
143 v.decorator = n = FlowLayout(v.bounds, margin: 0@0, gap: 5@5);
145 a = StaticText(v, Rect(20, 70, 90, 20)).string_(" xZoom = 1").background_(Color.rand);
146 m = Slider(v, Rect(20, 60, 285, 20)).background_(a.background).action_({func.value}).value_(0.5);
147 d = StaticText(v, Rect(20, 70, 90, 20)).string_(" yZoom = 1").background_(Color.rand);
148 g = Slider(v, Rect(20, 60, 285, 20)).background_(d.background).action_({func.value}).value_(0.5);
150 h = StaticText(v, Rect(20, 70, 90, 20)).string_(" x = 0").background_(Color.rand);
151 i = Slider(v, Rect(20, 60, 285, 20)).background_(h.background).action_({func.value}).value_(0.5);
153 Button(v, Rect(0,0,380, 20))
154 .states_([["waveColors = [ Color.rand, ... ]",Color.black,Color.rand]])
155 .action_({c.waveColors = [Color.rand,Color.rand]});
157 Button(v, Rect(0,0,380, 20))
158 .states_([[" background = Color.rand(0.1,0.3) ",Color.black,Color.rand]])
159 .action_({c.background = Color.rand(0.1,0.3) });
161 t= Button(v, Rect(0,0,380, 20))
162 .states_([["Current style is 0",Color.black,Color.rand],
163 ["Current style is 1",Color.black,Color.rand],
164 ["Current style is 2",Color.black,Color.rand]])
165 .action_({func.value});
168 c.xZoom = ([0.25, 10, \exp, 1/8, 1].asSpec.map(m.value)); a.string = " xZoom = %".format(c.xZoom);
169 c.yZoom = ([0.25, 10, \exp, 1/8, 1].asSpec.map(g.value)); d.string = " yZoom = %".format(c.yZoom);
170 c.x = ([ -1024,1024, \linear, 1/8, 1].asSpec.map(i.value)); h.string = " x = %".format(c.x);
171 // c.y = ([-1,1, \linear, 1/16, 1].asSpec.map(k.value)); j.string = " y = %".format(c.y);
175 startButton = Button.new(v, Rect(0,0,380, 50))
176 .states_([["Start Sound",Color.black,Color.green],["Stop Sound",Color.black,Color.red]]).action_({});
180 (startButton.value==1).if{
181 syn1=SynthDef("test1", { arg bus, bufnum;
184 // ScopeOut writes the audio to the buffer
185 ScopeOut.ar(z, bufnum);
189 [\bus,b.index, \bufnum, f.bufnum] ,
190 \addToTail // make sure it goes after what you are scoping
193 // making noise onto the buffer
194 syn2=SynthDef("test2", { arg bus;
196 z = PMOsc.ar([300,250],*SinOsc.ar([0.027,0.017])*pi) * 0.1;
198 }).play(s,[\bus,b.index]);
202 }{syn1.free; syn2.free};
205 w.onClose={syn1.free; syn2.free; b.free; f.free};
206 CmdPeriod.doOnce({w.close});