{
   "name" : "Draw your waveform feat. silly pattern player",
   "author" : "rukano",
   "description" : "A short demonstration how to change values in a buffer from a GUI. Also some presets added, because the mouse precision is not very good if you intend to draw fast.",
   "ancestor_list" : [],
   "labels" : [
      "drawing",
      "waveform"
   ],
   "code" : "/////////////////////////////////////////////////////////////////////////////////\r\n// Draw your waveform!\r\n(\r\nb = Buffer.alloc(s, 1024); // buffer, server side\r\na = Array.fill(1024, { 256 }); // array, language side\r\nw = Window(\"Draw your waveform!\", Rect(100, 100, 1024, 512)).front;\r\nu = UserView(w, w.view.bounds);\r\n\r\n// function that changes the array and the buffer, and makes some clipping\r\nf = { |x, y|\r\n\tx = x.clip(0, 1023);\r\n\ty = y.clip(0, 511);\r\n\ta[x] = y;\r\n\tb.set(x, (y / 512) * 2 - 1);\r\n};\r\n\r\n// animate, to cope with the mouse changes\r\nu.background_(Color.black);\r\nu.animate_(true);\r\nu.drawFunc = { |u|\r\n\tPen.strokeColor = Color.white;\r\n\tPen.moveTo( Point(0, a[0]) );\r\n\ta[1..].do{ |value, index| Pen.lineTo( Point(index+1, value) ) };\r\n\tPen.stroke;\r\n};\r\n\r\n// call our function when the mouse is pressed or moved\r\nu.mouseDownAction = { |u, x, y, mod| f.(x, y) };\r\nu.mouseMoveAction = { |u, x, y, mod| f.(x, y) };\r\n\r\n// call some presets (1..6), spacebar clears.\r\nu.keyDownAction = { |u, char, mod|\r\n\tchar.switch(\r\n\t\t$ , { a.size.do{ |i| f.(i, 256) } }, // reset waveform\r\n\t\t$1, { a.size.do{ |i| f.(i, 512.rand) } }, // random waveform\r\n\t\t$2, { Array.interpolation(1024, 0, 512).do{ |val, i| f.(i, val) } }, // linear ramp\r\n\t\t$3, { Array.fill(1024, { |i| sin(i/1024*2pi) * 256 + 256 }).do{ |val, i| f.(i, val) } }, // sinewave\r\n\t\t$4, { Array.fill(1024, { |i| (i/512).floor * 512 }).do{ |val, i| f.(i, val) } }, // squarewave\r\n\t\t$5, { Pbrown(0,512,16).asStream.nextN(1024).do{ |val, i| f.(i, val) } }, // brown pattern\r\n\t\t$6, { (Array.fill(1024, { |i| sin(i/1024*2pi) * 200 + 256 }) + Pbrown(0,32,8).asStream.nextN(1024)).do{ |val, i| f.(i, val) } }, // sinewave with brown\r\n\t);\r\n};\r\n// make a pattern player with a simple synth with COsc\r\nx = Pbind(\r\n\t\\type, \\set,\r\n\t\\id, { |freq| LeakDC.ar(COsc.ar(b, freq, 1))!2 * 0.5 }.play,\r\n\t\\octave, 3,\r\n\t\\scale, Scale.minorPentatonic,\r\n\t\\degree, Pn(Plazy{Pseq(Pxrand((0..4),inf).asStream.nextN(4),4)}),\r\n\t\\dur, 1/4\r\n).play;\r\n\r\n// clean up\r\nw.onClose_({\r\n\tb.free;\r\n\tx.stop;\r\n});\r\n)",
   "is_private" : null,
   "id" : "1-4VD"
}
