// title: 3D Scope // author: rukano // description: // This was inspired by http://sccode.org/1-1HR and a student wanted to do a 3D freq/spectrum plot over time. // The colors are just for extra funkyness.... feel free to change it to standerd retro green and scale the freqs and magnitudes at will ;) // code: ///////////////////////////////////////////////////////////////// // 3D Freq Scope // You will need PV_MagBuffer (sc3-PlugIns: JoshUGens) and GUI.qt // heavily inspired by redFrik's "bufferdisplay" (http://sccode.org/1-1HR) ( b = Buffer.alloc(s, 1024, 1); // FFT c = Buffer.alloc(s, 1024/2, 1); // Mags SynthDef(\magbuf, { |fftbuf, magbuf, freqbuf| var in, chain; in = SoundIn.ar(0); // <---------- change your input here // in = PMOsc.ar(800, MouseX.kr(10, 800), MouseY.kr(0,40)); chain = FFT(fftbuf, in); PV_MagBuffer(chain, magbuf); // Out.ar(0, in) }).add; ) //////////////////////////////////////////////////////////////// // 3D Spectrum vs. Time plotting ( t = true; ~case = 0; ~amp = 100; x = Synth(\magbuf, [\fftbuf, b, \magbuf, c]); w = Window("3D SCOPE", Rect(600, 400, 800, 600)).front; w.view.keyDownAction_{ |view, char, xxx, code| if(code==32){ w.refresh; t = t.not; u.animate = t; } }; u = UserView(w, w.view.bounds); u.background = Color.black; u.animate = t; u.frameRate = 30; u.clearOnRefresh = false; u.drawFunc = { |view| var i = view.frame; var ypos = i % 500; var xpos = 200 - (ypos/3); var numFreqs = 512; var lineColor = Color.hsv(ypos/500, 0.5, 0.5, 0.3); // var lineColor = Color.green.alpha_(0.5); // for retro style if( ypos == 0 ) { Pen.fillColor = Color.black; Pen.fillRect(view.bounds) }; // clear on new begin c.getn(0, numFreqs-1, { |v| d = v }); // get mag buffer data Pen.strokeColor = lineColor; Pen.moveTo(0, 0); // init Pen.translate(xpos, ypos + 100); // scan down switch(~case, // lines 0, { d.do{ |y, x| if(y.isNil.not){ Pen.lineTo(Point(x*(600/numFreqs), (y/64).tanh.neg * ~amp)) }; }; Pen.stroke; }, // dots 1, { d.do{ |y, x| Pen.fillColor = lineColor; if(y.isNil.not){ Pen.addOval(Rect.aboutPoint(Point(x*(600/numFreqs), (y/64).tanh.neg * ~amp), 1, 1)) }; Pen.fill; }; }, { nil } ); }; w.onClose_{ x.free }; ); ~case = 0; // draw continuous lines ~case = 1; // draw points ~amp = 200; // change the amp scaling