// title: Visual demonstration of aliasing/foldover (modified from James Harkins) // author: jnarveson // description: // James Harkins already posted already excellent little visualizer for illustrating the importance of the Nyquist frequency - I just wanted to add a slider for variable sample rate, and some grid lines that makes it easier for me to see the sampling rate. // code: ( // a slightly modified version of the excellent example patch by James Harkins. // I added some grid lines for the samples, an adjustable sampling rate, and changed some colors. // Jascha Narveson var screen = Window.screenBounds, height = (screen.height - 120).asInteger, width = (screen.width - 120).asInteger, win = Window(\aliasing, Rect.aboutPoint(screen.center, width / 2, height / 2 + 60)).background_(Color.white), sinPts = 400, sampPts = 20, sr, freq = 1, fsl, sinColor = Color.red, sampColor = Color.blue, lineColor = Color.grey; win.drawHook = { var pt; pt = Point(0, height/2); Pen.color_(sampColor) .moveTo(pt); (1..sampPts).do { |x| Pen.moveTo(pt); pt = Point(x * (width / sampPts), sin(x * freq / sampPts * 2pi).linlin(-1, 1, height, 0)); Pen.lineTo(pt).stroke .fillRect(Rect.aboutPoint(pt, 3, 3)); }; Pen.color_(sinColor) .moveTo(Point(0, height/2)); (1..sinPts).do { |x| Pen.lineTo(Point( x * (width / sinPts), sin(x * freq / sinPts * 2pi).linlin(-1, 1, height, 0) )); }; Pen.stroke; Pen.color_(lineColor); (1..sinPts).do({|x| var xpos = x * (width / sampPts); Pen.moveTo(Point(xpos, 0)); Pen.lineTo(Point(xpos, height)); Pen.stroke; }); }; fsl = EZSlider( win, Rect(5, height + 10, width-10, 20), "freq of input wave (red):", ControlSpec(1, 40, 'lin', 0, 20), {|slider| freq = slider.value; win.refresh }, 1, labelWidth: 200, initAction: true ); sr = EZSlider( win, Rect(5, height + 30, width-10, 20), "samp rate (output wave in blue):", ControlSpec(1, 44, 'lin', 1, 20), {|slider| sampPts = slider.value; win.refresh }, 1, labelWidth: 200, initAction: true ); win.front; )